mongodb-raw.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. const h = require('../helper');
  2. const MongoClient = require('mongodb').MongoClient;
  3. let collectionsMaybe = null, connecting = false, connectionCallbacks = [];
  4. const mongoUrl = 'mongodb://tfb-database:27017';
  5. const dbName = 'hello_world';
  6. /**
  7. * Note! The benchmarks say we should use "id" as a property name.
  8. * However, Mongo provides a default index on "_id", so to be equivalent to the other tests, we use
  9. * the same, default index provided by the database.
  10. *
  11. */
  12. const getCollections = async () => {
  13. // mongoose creates a queue of requests during connection, so we don't have to wait.
  14. // however, with the raw driver we need to connect first, or sometimes the test will fail randomly
  15. if (collectionsMaybe) {
  16. return collectionsMaybe;
  17. }
  18. if (connecting) {
  19. const promise = new Promise((resolve) => {
  20. connectionCallbacks.push(resolve);
  21. });
  22. return await promise;
  23. }
  24. connecting = true;
  25. const client = await MongoClient.connect(mongoUrl);
  26. collectionsMaybe = {
  27. World: null,
  28. Fortune: null
  29. };
  30. collectionsMaybe.World = client.db(dbName).collection('world');
  31. collectionsMaybe.Fortune = client.db(dbName).collection('fortune');
  32. // resolve pending requests in buffer
  33. for (const callback of connectionCallbacks) {
  34. callback(collectionsMaybe);
  35. }
  36. return collectionsMaybe;
  37. }
  38. const toClientWorld = (world) => {
  39. if (world) {
  40. world.id = world._id;
  41. delete world._id;
  42. }
  43. return world;
  44. };
  45. const mongodbRandomWorld = async () => {
  46. const collections = await getCollections();
  47. return toClientWorld(await collections.World.findOne({
  48. _id: h.randomTfbNumber()
  49. }));
  50. };
  51. const mongodbGetAllFortunes = async () => {
  52. const collections = await getCollections();
  53. return (await collections.Fortune.find({}).toArray()).map(toClientWorld);
  54. };
  55. async function getUpdateRandomWorld() {
  56. const collections = await getCollections();
  57. const world = await collections.World.findOne({
  58. _id: h.randomTfbNumber()
  59. });
  60. world.randomNumber = h.randomTfbNumber();
  61. await collections.World.updateOne({
  62. _id: world._id
  63. }, {
  64. $set: {
  65. randomNumber: world.randomNumber
  66. }
  67. })
  68. return toClientWorld(world);
  69. }
  70. module.exports = {
  71. SingleQuery: async (req, res) => {
  72. const result = await mongodbRandomWorld();
  73. h.addTfbHeaders(res, 'json');
  74. res.end(JSON.stringify(result));
  75. },
  76. MultipleQueries: async (queryCount, req, res) => {
  77. const queryFunctions = [];
  78. for (let i = 0; i < queryCount; i++) {
  79. queryFunctions.push(mongodbRandomWorld());
  80. }
  81. const results = await Promise.all(queryFunctions);
  82. h.addTfbHeaders(res, 'json');
  83. res.end(JSON.stringify(results));
  84. },
  85. Fortunes: async (req, res) => {
  86. const fortunes = await mongodbGetAllFortunes();
  87. fortunes.push(h.additionalFortune());
  88. fortunes.sort(function (a, b) {
  89. return a.message.localeCompare(b.message);
  90. });
  91. h.addTfbHeaders(res, 'html');
  92. res.end(h.fortunesTemplate({fortunes}));
  93. },
  94. Updates: async (queryCount, req, res) => {
  95. const promises = [];
  96. for (let i = 1; i <= queryCount; i++) {
  97. promises.push(getUpdateRandomWorld());
  98. }
  99. h.addTfbHeaders(res, 'json');
  100. res.end(JSON.stringify(await Promise.all(promises)));
  101. }
  102. };