collection.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. 'use strict';
  2. /*!
  3. * Module dependencies.
  4. */
  5. const EventEmitter = require('events').EventEmitter;
  6. const STATES = require('./connectionstate');
  7. const immediate = require('./helpers/immediate');
  8. /**
  9. * Abstract Collection constructor
  10. *
  11. * This is the base class that drivers inherit from and implement.
  12. *
  13. * @param {String} name name of the collection
  14. * @param {Connection} conn A MongooseConnection instance
  15. * @param {Object} opts optional collection options
  16. * @api public
  17. */
  18. function Collection(name, conn, opts) {
  19. if (opts === void 0) {
  20. opts = {};
  21. }
  22. if (opts.capped === void 0) {
  23. opts.capped = {};
  24. }
  25. if (typeof opts.capped === 'number') {
  26. opts.capped = { size: opts.capped };
  27. }
  28. this.opts = opts;
  29. this.name = name;
  30. this.collectionName = name;
  31. this.conn = conn;
  32. this.queue = [];
  33. this.buffer = true;
  34. this.emitter = new EventEmitter();
  35. if (STATES.connected === this.conn.readyState) {
  36. this.onOpen();
  37. }
  38. }
  39. /**
  40. * The collection name
  41. *
  42. * @api public
  43. * @property name
  44. */
  45. Collection.prototype.name;
  46. /**
  47. * The collection name
  48. *
  49. * @api public
  50. * @property collectionName
  51. */
  52. Collection.prototype.collectionName;
  53. /**
  54. * The Connection instance
  55. *
  56. * @api public
  57. * @property conn
  58. */
  59. Collection.prototype.conn;
  60. /**
  61. * Called when the database connects
  62. *
  63. * @api private
  64. */
  65. Collection.prototype.onOpen = function() {
  66. this.buffer = false;
  67. immediate(() => this.doQueue());
  68. };
  69. /**
  70. * Called when the database disconnects
  71. *
  72. * @api private
  73. */
  74. Collection.prototype.onClose = function(force) {
  75. if (this._shouldBufferCommands() && !force) {
  76. this.buffer = true;
  77. }
  78. };
  79. /**
  80. * Queues a method for later execution when its
  81. * database connection opens.
  82. *
  83. * @param {String} name name of the method to queue
  84. * @param {Array} args arguments to pass to the method when executed
  85. * @api private
  86. */
  87. Collection.prototype.addQueue = function(name, args) {
  88. this.queue.push([name, args]);
  89. return this;
  90. };
  91. /**
  92. * Removes a queued method
  93. *
  94. * @param {String} name name of the method to queue
  95. * @param {Array} args arguments to pass to the method when executed
  96. * @api private
  97. */
  98. Collection.prototype.removeQueue = function(name, args) {
  99. const index = this.queue.findIndex(v => v[0] === name && v[1] === args);
  100. if (index === -1) {
  101. return false;
  102. }
  103. this.queue.splice(index, 1);
  104. return true;
  105. };
  106. /**
  107. * Executes all queued methods and clears the queue.
  108. *
  109. * @api private
  110. */
  111. Collection.prototype.doQueue = function() {
  112. for (const method of this.queue) {
  113. if (typeof method[0] === 'function') {
  114. method[0].apply(this, method[1]);
  115. } else {
  116. this[method[0]].apply(this, method[1]);
  117. }
  118. }
  119. this.queue = [];
  120. const _this = this;
  121. immediate(function() {
  122. _this.emitter.emit('queue');
  123. });
  124. return this;
  125. };
  126. /**
  127. * Abstract method that drivers must implement.
  128. */
  129. Collection.prototype.ensureIndex = function() {
  130. throw new Error('Collection#ensureIndex unimplemented by driver');
  131. };
  132. /**
  133. * Abstract method that drivers must implement.
  134. */
  135. Collection.prototype.createIndex = function() {
  136. throw new Error('Collection#createIndex unimplemented by driver');
  137. };
  138. /**
  139. * Abstract method that drivers must implement.
  140. */
  141. Collection.prototype.findAndModify = function() {
  142. throw new Error('Collection#findAndModify unimplemented by driver');
  143. };
  144. /**
  145. * Abstract method that drivers must implement.
  146. */
  147. Collection.prototype.findOneAndUpdate = function() {
  148. throw new Error('Collection#findOneAndUpdate unimplemented by driver');
  149. };
  150. /**
  151. * Abstract method that drivers must implement.
  152. */
  153. Collection.prototype.findOneAndDelete = function() {
  154. throw new Error('Collection#findOneAndDelete unimplemented by driver');
  155. };
  156. /**
  157. * Abstract method that drivers must implement.
  158. */
  159. Collection.prototype.findOneAndReplace = function() {
  160. throw new Error('Collection#findOneAndReplace unimplemented by driver');
  161. };
  162. /**
  163. * Abstract method that drivers must implement.
  164. */
  165. Collection.prototype.findOne = function() {
  166. throw new Error('Collection#findOne unimplemented by driver');
  167. };
  168. /**
  169. * Abstract method that drivers must implement.
  170. */
  171. Collection.prototype.find = function() {
  172. throw new Error('Collection#find unimplemented by driver');
  173. };
  174. /**
  175. * Abstract method that drivers must implement.
  176. */
  177. Collection.prototype.insert = function() {
  178. throw new Error('Collection#insert unimplemented by driver');
  179. };
  180. /**
  181. * Abstract method that drivers must implement.
  182. */
  183. Collection.prototype.insertOne = function() {
  184. throw new Error('Collection#insertOne unimplemented by driver');
  185. };
  186. /**
  187. * Abstract method that drivers must implement.
  188. */
  189. Collection.prototype.insertMany = function() {
  190. throw new Error('Collection#insertMany unimplemented by driver');
  191. };
  192. /**
  193. * Abstract method that drivers must implement.
  194. */
  195. Collection.prototype.save = function() {
  196. throw new Error('Collection#save unimplemented by driver');
  197. };
  198. /**
  199. * Abstract method that drivers must implement.
  200. */
  201. Collection.prototype.update = function() {
  202. throw new Error('Collection#update unimplemented by driver');
  203. };
  204. /**
  205. * Abstract method that drivers must implement.
  206. */
  207. Collection.prototype.getIndexes = function() {
  208. throw new Error('Collection#getIndexes unimplemented by driver');
  209. };
  210. /**
  211. * Abstract method that drivers must implement.
  212. */
  213. Collection.prototype.mapReduce = function() {
  214. throw new Error('Collection#mapReduce unimplemented by driver');
  215. };
  216. /**
  217. * Abstract method that drivers must implement.
  218. */
  219. Collection.prototype.watch = function() {
  220. throw new Error('Collection#watch unimplemented by driver');
  221. };
  222. /*!
  223. * ignore
  224. */
  225. Collection.prototype._shouldBufferCommands = function _shouldBufferCommands() {
  226. const opts = this.opts;
  227. if (opts.bufferCommands != null) {
  228. return opts.bufferCommands;
  229. }
  230. if (opts && opts.schemaUserProvidedOptions != null && opts.schemaUserProvidedOptions.bufferCommands != null) {
  231. return opts.schemaUserProvidedOptions.bufferCommands;
  232. }
  233. return this.conn._shouldBufferCommands();
  234. };
  235. /*!
  236. * ignore
  237. */
  238. Collection.prototype._getBufferTimeoutMS = function _getBufferTimeoutMS() {
  239. const conn = this.conn;
  240. const opts = this.opts;
  241. if (opts.bufferTimeoutMS != null) {
  242. return opts.bufferTimeoutMS;
  243. }
  244. if (opts && opts.schemaUserProvidedOptions != null && opts.schemaUserProvidedOptions.bufferTimeoutMS != null) {
  245. return opts.schemaUserProvidedOptions.bufferTimeoutMS;
  246. }
  247. if (conn.config.bufferTimeoutMS != null) {
  248. return conn.config.bufferTimeoutMS;
  249. }
  250. if (conn.base != null && conn.base.get('bufferTimeoutMS') != null) {
  251. return conn.base.get('bufferTimeoutMS');
  252. }
  253. return 10000;
  254. };
  255. /*!
  256. * Module exports.
  257. */
  258. module.exports = Collection;