PageRenderTime 57ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/server/node_modules/mongoose/node_modules/mongodb/lib/aggregation_cursor.js

https://gitlab.com/angtrim/gaia-back-due
JavaScript | 432 lines | 128 code | 58 blank | 246 comment | 11 complexity | 6ff8451bc812ed4549ad4912126218c6 MD5 | raw file
  1. "use strict";
  2. var inherits = require('util').inherits
  3. , f = require('util').format
  4. , toError = require('./utils').toError
  5. , getSingleProperty = require('./utils').getSingleProperty
  6. , formattedOrderClause = require('./utils').formattedOrderClause
  7. , handleCallback = require('./utils').handleCallback
  8. , Logger = require('mongodb-core').Logger
  9. , EventEmitter = require('events').EventEmitter
  10. , ReadPreference = require('./read_preference')
  11. , MongoError = require('mongodb-core').MongoError
  12. , Readable = require('stream').Readable || require('readable-stream').Readable
  13. , Define = require('./metadata')
  14. , CoreCursor = require('./cursor')
  15. , Query = require('mongodb-core').Query
  16. , CoreReadPreference = require('mongodb-core').ReadPreference;
  17. /**
  18. * @fileOverview The **AggregationCursor** class is an internal class that embodies an aggregation cursor on MongoDB
  19. * allowing for iteration over the results returned from the underlying query. It supports
  20. * one by one document iteration, conversion to an array or can be iterated as a Node 0.10.X
  21. * or higher stream
  22. *
  23. * **AGGREGATIONCURSOR Cannot directly be instantiated**
  24. * @example
  25. * var MongoClient = require('mongodb').MongoClient,
  26. * test = require('assert');
  27. * // Connection url
  28. * var url = 'mongodb://localhost:27017/test';
  29. * // Connect using MongoClient
  30. * MongoClient.connect(url, function(err, db) {
  31. * // Create a collection we want to drop later
  32. * var col = db.collection('createIndexExample1');
  33. * // Insert a bunch of documents
  34. * col.insert([{a:1, b:1}
  35. * , {a:2, b:2}, {a:3, b:3}
  36. * , {a:4, b:4}], {w:1}, function(err, result) {
  37. * test.equal(null, err);
  38. * // Show that duplicate records got dropped
  39. * col.aggregation({}, {cursor: {}}).toArray(function(err, items) {
  40. * test.equal(null, err);
  41. * test.equal(4, items.length);
  42. * db.close();
  43. * });
  44. * });
  45. * });
  46. */
  47. /**
  48. * Namespace provided by the browser.
  49. * @external Readable
  50. */
  51. /**
  52. * Creates a new Aggregation Cursor instance (INTERNAL TYPE, do not instantiate directly)
  53. * @class AggregationCursor
  54. * @extends external:Readable
  55. * @fires AggregationCursor#data
  56. * @fires AggregationCursor#end
  57. * @fires AggregationCursor#close
  58. * @fires AggregationCursor#readable
  59. * @return {AggregationCursor} an AggregationCursor instance.
  60. */
  61. var AggregationCursor = function(bson, ns, cmd, options, topology, topologyOptions) {
  62. CoreCursor.apply(this, Array.prototype.slice.call(arguments, 0));
  63. var self = this;
  64. var state = AggregationCursor.INIT;
  65. var streamOptions = {};
  66. // MaxTimeMS
  67. var maxTimeMS = null;
  68. // Get the promiseLibrary
  69. var promiseLibrary = options.promiseLibrary;
  70. // No promise library selected fall back
  71. if(!promiseLibrary) {
  72. promiseLibrary = typeof global.Promise == 'function' ?
  73. global.Promise : require('es6-promise').Promise;
  74. }
  75. // Set up
  76. Readable.call(this, {objectMode: true});
  77. // Internal state
  78. this.s = {
  79. // MaxTimeMS
  80. maxTimeMS: maxTimeMS
  81. // State
  82. , state: state
  83. // Stream options
  84. , streamOptions: streamOptions
  85. // BSON
  86. , bson: bson
  87. // Namespae
  88. , ns: ns
  89. // Command
  90. , cmd: cmd
  91. // Options
  92. , options: options
  93. // Topology
  94. , topology: topology
  95. // Topology Options
  96. , topologyOptions: topologyOptions
  97. // Promise library
  98. , promiseLibrary: promiseLibrary
  99. }
  100. }
  101. /**
  102. * AggregationCursor stream data event, fired for each document in the cursor.
  103. *
  104. * @event AggregationCursor#data
  105. * @type {object}
  106. */
  107. /**
  108. * AggregationCursor stream end event
  109. *
  110. * @event AggregationCursor#end
  111. * @type {null}
  112. */
  113. /**
  114. * AggregationCursor stream close event
  115. *
  116. * @event AggregationCursor#close
  117. * @type {null}
  118. */
  119. /**
  120. * AggregationCursor stream readable event
  121. *
  122. * @event AggregationCursor#readable
  123. * @type {null}
  124. */
  125. // Inherit from Readable
  126. inherits(AggregationCursor, Readable);
  127. // Set the methods to inherit from prototype
  128. var methodsToInherit = ['_next', 'next', 'each', 'forEach', 'toArray'
  129. , 'rewind', 'bufferedCount', 'readBufferedDocuments', 'close', 'isClosed', 'kill'
  130. , '_find', '_getmore', '_killcursor', 'isDead', 'explain', 'isNotified'];
  131. // Extend the Cursor
  132. for(var name in CoreCursor.prototype) {
  133. AggregationCursor.prototype[name] = CoreCursor.prototype[name];
  134. }
  135. var define = AggregationCursor.define = new Define('AggregationCursor', AggregationCursor, true);
  136. /**
  137. * Set the batch size for the cursor.
  138. * @method
  139. * @param {number} value The batchSize for the cursor.
  140. * @throws {MongoError}
  141. * @return {AggregationCursor}
  142. */
  143. AggregationCursor.prototype.batchSize = function(value) {
  144. if(this.s.state == AggregationCursor.CLOSED || this.isDead()) throw MongoError.create({message: "Cursor is closed", driver:true });
  145. if(typeof value != 'number') throw MongoError.create({message: "batchSize requires an integer", drvier:true });
  146. if(this.s.cmd.cursor) this.s.cmd.cursor.batchSize = value;
  147. this.setCursorBatchSize(value);
  148. return this;
  149. }
  150. define.classMethod('batchSize', {callback: false, promise:false, returns: [AggregationCursor]});
  151. /**
  152. * Add a geoNear stage to the aggregation pipeline
  153. * @method
  154. * @param {object} document The geoNear stage document.
  155. * @return {AggregationCursor}
  156. */
  157. AggregationCursor.prototype.geoNear = function(document) {
  158. this.s.cmd.pipeline.push({$geoNear: document});
  159. return this;
  160. }
  161. define.classMethod('geoNear', {callback: false, promise:false, returns: [AggregationCursor]});
  162. /**
  163. * Add a group stage to the aggregation pipeline
  164. * @method
  165. * @param {object} document The group stage document.
  166. * @return {AggregationCursor}
  167. */
  168. AggregationCursor.prototype.group = function(document) {
  169. this.s.cmd.pipeline.push({$group: document});
  170. return this;
  171. }
  172. define.classMethod('group', {callback: false, promise:false, returns: [AggregationCursor]});
  173. /**
  174. * Add a limit stage to the aggregation pipeline
  175. * @method
  176. * @param {number} value The state limit value.
  177. * @return {AggregationCursor}
  178. */
  179. AggregationCursor.prototype.limit = function(value) {
  180. this.s.cmd.pipeline.push({$limit: value});
  181. return this;
  182. }
  183. define.classMethod('limit', {callback: false, promise:false, returns: [AggregationCursor]});
  184. /**
  185. * Add a match stage to the aggregation pipeline
  186. * @method
  187. * @param {object} document The match stage document.
  188. * @return {AggregationCursor}
  189. */
  190. AggregationCursor.prototype.match = function(document) {
  191. this.s.cmd.pipeline.push({$match: document});
  192. return this;
  193. }
  194. define.classMethod('match', {callback: false, promise:false, returns: [AggregationCursor]});
  195. /**
  196. * Add a maxTimeMS stage to the aggregation pipeline
  197. * @method
  198. * @param {number} value The state maxTimeMS value.
  199. * @return {AggregationCursor}
  200. */
  201. AggregationCursor.prototype.maxTimeMS = function(value) {
  202. if(this.s.topology.lastIsMaster().minWireVersion > 2) {
  203. this.s.cmd.maxTimeMS = value;
  204. }
  205. return this;
  206. }
  207. define.classMethod('maxTimeMS', {callback: false, promise:false, returns: [AggregationCursor]});
  208. /**
  209. * Add a out stage to the aggregation pipeline
  210. * @method
  211. * @param {number} destination The destination name.
  212. * @return {AggregationCursor}
  213. */
  214. AggregationCursor.prototype.out = function(destination) {
  215. this.s.cmd.pipeline.push({$out: destination});
  216. return this;
  217. }
  218. define.classMethod('out', {callback: false, promise:false, returns: [AggregationCursor]});
  219. /**
  220. * Add a project stage to the aggregation pipeline
  221. * @method
  222. * @param {object} document The project stage document.
  223. * @return {AggregationCursor}
  224. */
  225. AggregationCursor.prototype.project = function(document) {
  226. this.s.cmd.pipeline.push({$project: document});
  227. return this;
  228. }
  229. define.classMethod('project', {callback: false, promise:false, returns: [AggregationCursor]});
  230. /**
  231. * Add a redact stage to the aggregation pipeline
  232. * @method
  233. * @param {object} document The redact stage document.
  234. * @return {AggregationCursor}
  235. */
  236. AggregationCursor.prototype.redact = function(document) {
  237. this.s.cmd.pipeline.push({$redact: document});
  238. return this;
  239. }
  240. define.classMethod('redact', {callback: false, promise:false, returns: [AggregationCursor]});
  241. /**
  242. * Add a skip stage to the aggregation pipeline
  243. * @method
  244. * @param {number} value The state skip value.
  245. * @return {AggregationCursor}
  246. */
  247. AggregationCursor.prototype.skip = function(value) {
  248. this.s.cmd.pipeline.push({$skip: value});
  249. return this;
  250. }
  251. define.classMethod('skip', {callback: false, promise:false, returns: [AggregationCursor]});
  252. /**
  253. * Add a sort stage to the aggregation pipeline
  254. * @method
  255. * @param {object} document The sort stage document.
  256. * @return {AggregationCursor}
  257. */
  258. AggregationCursor.prototype.sort = function(document) {
  259. this.s.cmd.pipeline.push({$sort: document});
  260. return this;
  261. }
  262. define.classMethod('sort', {callback: false, promise:false, returns: [AggregationCursor]});
  263. /**
  264. * Add a unwind stage to the aggregation pipeline
  265. * @method
  266. * @param {number} field The unwind field name.
  267. * @return {AggregationCursor}
  268. */
  269. AggregationCursor.prototype.unwind = function(field) {
  270. this.s.cmd.pipeline.push({$unwind: field});
  271. return this;
  272. }
  273. define.classMethod('unwind', {callback: false, promise:false, returns: [AggregationCursor]});
  274. AggregationCursor.prototype.get = AggregationCursor.prototype.toArray;
  275. // Inherited methods
  276. define.classMethod('toArray', {callback: true, promise:true});
  277. define.classMethod('each', {callback: true, promise:false});
  278. define.classMethod('forEach', {callback: true, promise:false});
  279. define.classMethod('next', {callback: true, promise:true});
  280. define.classMethod('close', {callback: true, promise:true});
  281. define.classMethod('isClosed', {callback: false, promise:false, returns: [Boolean]});
  282. define.classMethod('rewind', {callback: false, promise:false});
  283. define.classMethod('bufferedCount', {callback: false, promise:false, returns: [Number]});
  284. define.classMethod('readBufferedDocuments', {callback: false, promise:false, returns: [Array]});
  285. /**
  286. * Get the next available document from the cursor, returns null if no more documents are available.
  287. * @function AggregationCursor.prototype.next
  288. * @param {AggregationCursor~resultCallback} [callback] The result callback.
  289. * @throws {MongoError}
  290. * @return {Promise} returns Promise if no callback passed
  291. */
  292. /**
  293. * The callback format for results
  294. * @callback AggregationCursor~toArrayResultCallback
  295. * @param {MongoError} error An error instance representing the error during the execution.
  296. * @param {object[]} documents All the documents the satisfy the cursor.
  297. */
  298. /**
  299. * Returns an array of documents. The caller is responsible for making sure that there
  300. * is enough memory to store the results. Note that the array only contain partial
  301. * results when this cursor had been previouly accessed. In that case,
  302. * cursor.rewind() can be used to reset the cursor.
  303. * @method AggregationCursor.prototype.toArray
  304. * @param {AggregationCursor~toArrayResultCallback} [callback] The result callback.
  305. * @throws {MongoError}
  306. * @return {Promise} returns Promise if no callback passed
  307. */
  308. /**
  309. * The callback format for results
  310. * @callback AggregationCursor~resultCallback
  311. * @param {MongoError} error An error instance representing the error during the execution.
  312. * @param {(object|null)} result The result object if the command was executed successfully.
  313. */
  314. /**
  315. * Iterates over all the documents for this cursor. As with **{cursor.toArray}**,
  316. * not all of the elements will be iterated if this cursor had been previouly accessed.
  317. * In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike
  318. * **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements
  319. * at any given time if batch size is specified. Otherwise, the caller is responsible
  320. * for making sure that the entire result can fit the memory.
  321. * @method AggregationCursor.prototype.each
  322. * @param {AggregationCursor~resultCallback} callback The result callback.
  323. * @throws {MongoError}
  324. * @return {null}
  325. */
  326. /**
  327. * Close the cursor, sending a AggregationCursor command and emitting close.
  328. * @method AggregationCursor.prototype.close
  329. * @param {AggregationCursor~resultCallback} [callback] The result callback.
  330. * @return {Promise} returns Promise if no callback passed
  331. */
  332. /**
  333. * Is the cursor closed
  334. * @method AggregationCursor.prototype.isClosed
  335. * @return {boolean}
  336. */
  337. /**
  338. * Execute the explain for the cursor
  339. * @method AggregationCursor.prototype.explain
  340. * @param {AggregationCursor~resultCallback} [callback] The result callback.
  341. * @return {Promise} returns Promise if no callback passed
  342. */
  343. /**
  344. * Clone the cursor
  345. * @function AggregationCursor.prototype.clone
  346. * @return {AggregationCursor}
  347. */
  348. /**
  349. * Resets the cursor
  350. * @function AggregationCursor.prototype.rewind
  351. * @return {AggregationCursor}
  352. */
  353. /**
  354. * The callback format for the forEach iterator method
  355. * @callback AggregationCursor~iteratorCallback
  356. * @param {Object} doc An emitted document for the iterator
  357. */
  358. /**
  359. * The callback error format for the forEach iterator method
  360. * @callback AggregationCursor~endCallback
  361. * @param {MongoError} error An error instance representing the error during the execution.
  362. */
  363. /*
  364. * Iterates over all the documents for this cursor using the iterator, callback pattern.
  365. * @method AggregationCursor.prototype.forEach
  366. * @param {AggregationCursor~iteratorCallback} iterator The iteration callback.
  367. * @param {AggregationCursor~endCallback} callback The end callback.
  368. * @throws {MongoError}
  369. * @return {null}
  370. */
  371. AggregationCursor.INIT = 0;
  372. AggregationCursor.OPEN = 1;
  373. AggregationCursor.CLOSED = 2;
  374. module.exports = AggregationCursor;