Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2_6_support.js 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. 'use strict';
  2. const retrieveBSON = require('../connection/utils').retrieveBSON;
  3. const KillCursor = require('../connection/commands').KillCursor;
  4. const GetMore = require('../connection/commands').GetMore;
  5. const Query = require('../connection/commands').Query;
  6. const MongoError = require('../error').MongoError;
  7. const getReadPreference = require('./shared').getReadPreference;
  8. const applyCommonQueryOptions = require('./shared').applyCommonQueryOptions;
  9. const isMongos = require('./shared').isMongos;
  10. const databaseNamespace = require('./shared').databaseNamespace;
  11. const collectionNamespace = require('./shared').collectionNamespace;
  12. const BSON = retrieveBSON();
  13. const Long = BSON.Long;
  14. class WireProtocol {
  15. insert(server, ns, ops, options, callback) {
  16. executeWrite(this, server, 'insert', 'documents', ns, ops, options, callback);
  17. }
  18. update(server, ns, ops, options, callback) {
  19. executeWrite(this, server, 'update', 'updates', ns, ops, options, callback);
  20. }
  21. remove(server, ns, ops, options, callback) {
  22. executeWrite(this, server, 'delete', 'deletes', ns, ops, options, callback);
  23. }
  24. killCursor(server, ns, cursorState, callback) {
  25. const bson = server.s.bson;
  26. const pool = server.s.pool;
  27. const cursorId = cursorState.cursorId;
  28. const killCursor = new KillCursor(bson, ns, [cursorId]);
  29. const options = {
  30. immediateRelease: true,
  31. noResponse: true
  32. };
  33. if (typeof cursorState.session === 'object') {
  34. options.session = cursorState.session;
  35. }
  36. if (pool && pool.isConnected()) {
  37. try {
  38. pool.write(killCursor, options, callback);
  39. } catch (err) {
  40. if (typeof callback === 'function') {
  41. callback(err, null);
  42. } else {
  43. console.warn(err);
  44. }
  45. }
  46. }
  47. }
  48. getMore(server, ns, cursorState, batchSize, options, callback) {
  49. const bson = server.s.bson;
  50. const getMore = new GetMore(bson, ns, cursorState.cursorId, { numberToReturn: batchSize });
  51. function queryCallback(err, result) {
  52. if (err) return callback(err);
  53. const response = result.message;
  54. // If we have a timed out query or a cursor that was killed
  55. if (response.cursorNotFound) {
  56. return callback(new MongoError('Cursor does not exist, was killed, or timed out'), null);
  57. }
  58. const cursorId =
  59. typeof response.cursorId === 'number'
  60. ? Long.fromNumber(response.cursorId)
  61. : response.cursorId;
  62. cursorState.documents = response.documents;
  63. cursorState.cursorId = cursorId;
  64. callback(null, null, response.connection);
  65. }
  66. const queryOptions = applyCommonQueryOptions({}, cursorState);
  67. server.s.pool.write(getMore, queryOptions, queryCallback);
  68. }
  69. query(server, ns, cmd, cursorState, options, callback) {
  70. if (cursorState.cursorId != null) {
  71. return;
  72. }
  73. const query = setupClassicFind(server, ns, cmd, cursorState, options);
  74. const queryOptions = applyCommonQueryOptions({}, cursorState);
  75. if (typeof query.documentsReturnedIn === 'string') {
  76. queryOptions.documentsReturnedIn = query.documentsReturnedIn;
  77. }
  78. server.s.pool.write(query, queryOptions, callback);
  79. }
  80. command(server, ns, cmd, options, callback) {
  81. if (cmd == null) {
  82. return callback(new MongoError(`command ${JSON.stringify(cmd)} does not return a cursor`));
  83. }
  84. options = options || {};
  85. const bson = server.s.bson;
  86. const pool = server.s.pool;
  87. const readPreference = getReadPreference(cmd, options);
  88. let finalCmd = Object.assign({}, cmd);
  89. if (finalCmd.readConcern) {
  90. if (finalCmd.readConcern.level !== 'local') {
  91. return callback(
  92. new MongoError(
  93. `server ${JSON.stringify(finalCmd)} command does not support a readConcern level of ${
  94. finalCmd.readConcern.level
  95. }`
  96. )
  97. );
  98. }
  99. delete finalCmd['readConcern'];
  100. }
  101. if (isMongos(server) && readPreference && readPreference.preference !== 'primary') {
  102. finalCmd = {
  103. $query: finalCmd,
  104. $readPreference: readPreference.toJSON()
  105. };
  106. }
  107. const commandOptions = Object.assign(
  108. {
  109. command: true,
  110. numberToSkip: 0,
  111. numberToReturn: -1,
  112. checkKeys: false
  113. },
  114. options
  115. );
  116. // This value is not overridable
  117. commandOptions.slaveOk = readPreference.slaveOk();
  118. try {
  119. const query = new Query(bson, `${databaseNamespace(ns)}.$cmd`, finalCmd, commandOptions);
  120. pool.write(query, commandOptions, callback);
  121. } catch (err) {
  122. callback(err);
  123. }
  124. }
  125. }
  126. function executeWrite(handler, server, type, opsField, ns, ops, options, callback) {
  127. if (ops.length === 0) throw new MongoError('insert must contain at least one document');
  128. if (typeof options === 'function') {
  129. callback = options;
  130. options = {};
  131. options = options || {};
  132. }
  133. const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
  134. const writeConcern = options.writeConcern;
  135. const writeCommand = {};
  136. writeCommand[type] = collectionNamespace(ns);
  137. writeCommand[opsField] = ops;
  138. writeCommand.ordered = ordered;
  139. if (writeConcern && Object.keys(writeConcern).length > 0) {
  140. writeCommand.writeConcern = writeConcern;
  141. }
  142. if (options.bypassDocumentValidation === true) {
  143. writeCommand.bypassDocumentValidation = options.bypassDocumentValidation;
  144. }
  145. const commandOptions = Object.assign(
  146. {
  147. checkKeys: type === 'insert',
  148. numberToReturn: 1
  149. },
  150. options
  151. );
  152. handler.command(server, ns, writeCommand, commandOptions, callback);
  153. }
  154. function setupClassicFind(server, ns, cmd, cursorState, options) {
  155. options = options || {};
  156. const bson = server.s.bson;
  157. const readPreference = getReadPreference(cmd, options);
  158. cursorState.batchSize = cmd.batchSize || cursorState.batchSize;
  159. let numberToReturn = 0;
  160. if (cursorState.limit === 0) {
  161. numberToReturn = cursorState.batchSize;
  162. } else if (
  163. cursorState.limit < 0 ||
  164. cursorState.limit < cursorState.batchSize ||
  165. (cursorState.limit > 0 && cursorState.batchSize === 0)
  166. ) {
  167. numberToReturn = cursorState.limit;
  168. } else {
  169. numberToReturn = cursorState.batchSize;
  170. }
  171. const numberToSkip = cursorState.skip || 0;
  172. const findCmd = {};
  173. if (isMongos(server) && readPreference) {
  174. findCmd['$readPreference'] = readPreference.toJSON();
  175. }
  176. if (cmd.sort) findCmd['$orderby'] = cmd.sort;
  177. if (cmd.hint) findCmd['$hint'] = cmd.hint;
  178. if (cmd.snapshot) findCmd['$snapshot'] = cmd.snapshot;
  179. if (typeof cmd.returnKey !== 'undefined') findCmd['$returnKey'] = cmd.returnKey;
  180. if (cmd.maxScan) findCmd['$maxScan'] = cmd.maxScan;
  181. if (cmd.min) findCmd['$min'] = cmd.min;
  182. if (cmd.max) findCmd['$max'] = cmd.max;
  183. if (typeof cmd.showDiskLoc !== 'undefined') findCmd['$showDiskLoc'] = cmd.showDiskLoc;
  184. if (cmd.comment) findCmd['$comment'] = cmd.comment;
  185. if (cmd.maxTimeMS) findCmd['$maxTimeMS'] = cmd.maxTimeMS;
  186. if (cmd.explain) {
  187. // nToReturn must be 0 (match all) or negative (match N and close cursor)
  188. // nToReturn > 0 will give explain results equivalent to limit(0)
  189. numberToReturn = -Math.abs(cmd.limit || 0);
  190. findCmd['$explain'] = true;
  191. }
  192. findCmd['$query'] = cmd.query;
  193. if (cmd.readConcern && cmd.readConcern.level !== 'local') {
  194. throw new MongoError(
  195. `server find command does not support a readConcern level of ${cmd.readConcern.level}`
  196. );
  197. }
  198. if (cmd.readConcern) {
  199. cmd = Object.assign({}, cmd);
  200. delete cmd['readConcern'];
  201. }
  202. const serializeFunctions =
  203. typeof options.serializeFunctions === 'boolean' ? options.serializeFunctions : false;
  204. const ignoreUndefined =
  205. typeof options.ignoreUndefined === 'boolean' ? options.ignoreUndefined : false;
  206. const query = new Query(bson, ns, findCmd, {
  207. numberToSkip: numberToSkip,
  208. numberToReturn: numberToReturn,
  209. pre32Limit: typeof cmd.limit !== 'undefined' ? cmd.limit : undefined,
  210. checkKeys: false,
  211. returnFieldSelector: cmd.fields,
  212. serializeFunctions: serializeFunctions,
  213. ignoreUndefined: ignoreUndefined
  214. });
  215. if (typeof cmd.tailable === 'boolean') query.tailable = cmd.tailable;
  216. if (typeof cmd.oplogReplay === 'boolean') query.oplogReplay = cmd.oplogReplay;
  217. if (typeof cmd.noCursorTimeout === 'boolean') query.noCursorTimeout = cmd.noCursorTimeout;
  218. if (typeof cmd.awaitData === 'boolean') query.awaitData = cmd.awaitData;
  219. if (typeof cmd.partial === 'boolean') query.partial = cmd.partial;
  220. query.slaveOk = readPreference.slaveOk();
  221. return query;
  222. }
  223. module.exports = WireProtocol;