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.

index.js 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. 'use strict';
  2. /*!
  3. * Module dependencies.
  4. */
  5. if (global.MONGOOSE_DRIVER_PATH) {
  6. const deprecationWarning = 'The `MONGOOSE_DRIVER_PATH` global property is ' +
  7. 'deprecated. Use `mongoose.driver.set()` instead.';
  8. const setDriver = require('util').deprecate(function() {
  9. require('./driver').set(require(global.MONGOOSE_DRIVER_PATH));
  10. }, deprecationWarning);
  11. setDriver();
  12. } else {
  13. require('./driver').set(require('./drivers/node-mongodb-native'));
  14. }
  15. const Schema = require('./schema');
  16. const SchemaType = require('./schematype');
  17. const SchemaTypes = require('./schema/index');
  18. const VirtualType = require('./virtualtype');
  19. const STATES = require('./connectionstate');
  20. const Types = require('./types');
  21. const Query = require('./query');
  22. const Model = require('./model');
  23. const Document = require('./document');
  24. const applyPlugins = require('./helpers/schema/applyPlugins');
  25. const get = require('./helpers/get');
  26. const legacyPluralize = require('mongoose-legacy-pluralize');
  27. const utils = require('./utils');
  28. const pkg = require('../package.json');
  29. const removeSubdocs = require('./plugins/removeSubdocs');
  30. const saveSubdocs = require('./plugins/saveSubdocs');
  31. const validateBeforeSave = require('./plugins/validateBeforeSave');
  32. const Aggregate = require('./aggregate');
  33. const PromiseProvider = require('./promise_provider');
  34. const shardingPlugin = require('./plugins/sharding');
  35. const defaultMongooseSymbol = Symbol.for('mongoose:default');
  36. require('./helpers/printJestWarning');
  37. /**
  38. * Mongoose constructor.
  39. *
  40. * The exports object of the `mongoose` module is an instance of this class.
  41. * Most apps will only use this one instance.
  42. *
  43. * @api public
  44. */
  45. function Mongoose(options) {
  46. this.connections = [];
  47. this.models = {};
  48. this.modelSchemas = {};
  49. // default global options
  50. this.options = {
  51. pluralization: true
  52. };
  53. const conn = this.createConnection(); // default connection
  54. conn.models = this.models;
  55. this._pluralize = legacyPluralize;
  56. // If a user creates their own Mongoose instance, give them a separate copy
  57. // of the `Schema` constructor so they get separate custom types. (gh-6933)
  58. if (!options || !options[defaultMongooseSymbol]) {
  59. const _this = this;
  60. this.Schema = function() {
  61. this.base = _this;
  62. return Schema.apply(this, arguments);
  63. };
  64. this.Schema.prototype = Object.create(Schema.prototype);
  65. Object.assign(this.Schema, Schema);
  66. this.Schema.base = this;
  67. this.Schema.Types = Object.assign({}, Schema.Types);
  68. } else {
  69. // Hack to work around babel's strange behavior with
  70. // `import mongoose, { Schema } from 'mongoose'`. Because `Schema` is not
  71. // an own property of a Mongoose global, Schema will be undefined. See gh-5648
  72. for (const key of ['Schema', 'model']) {
  73. this[key] = Mongoose.prototype[key];
  74. }
  75. }
  76. this.Schema.prototype.base = this;
  77. Object.defineProperty(this, 'plugins', {
  78. configurable: false,
  79. enumerable: true,
  80. writable: false,
  81. value: [
  82. [saveSubdocs, { deduplicate: true }],
  83. [validateBeforeSave, { deduplicate: true }],
  84. [shardingPlugin, { deduplicate: true }],
  85. [removeSubdocs, { deduplicate: true }]
  86. ]
  87. });
  88. }
  89. /**
  90. * Expose connection states for user-land
  91. *
  92. * @memberOf Mongoose
  93. * @property STATES
  94. * @api public
  95. */
  96. Mongoose.prototype.STATES = STATES;
  97. /**
  98. * The underlying driver this Mongoose instance uses to communicate with
  99. * the database. A driver is a Mongoose-specific interface that defines functions
  100. * like `find()`.
  101. *
  102. * @memberOf Mongoose
  103. * @property driver
  104. * @api public
  105. */
  106. Mongoose.prototype.driver = require('./driver');
  107. /**
  108. * Sets mongoose options
  109. *
  110. * ####Example:
  111. *
  112. * mongoose.set('test', value) // sets the 'test' option to `value`
  113. *
  114. * mongoose.set('debug', true) // enable logging collection methods + arguments to the console
  115. *
  116. * mongoose.set('debug', function(collectionName, methodName, arg1, arg2...) {}); // use custom function to log collection methods + arguments
  117. *
  118. * Currently supported options are:
  119. * - 'debug': prints the operations mongoose sends to MongoDB to the console
  120. * - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models
  121. * - 'useCreateIndex': false by default. Set to `true` to make Mongoose's default index build use `createIndex()` instead of `ensureIndex()` to avoid deprecation warnings from the MongoDB driver.
  122. * - 'useFindAndModify': true by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`.
  123. * - 'useNewUrlParser': false by default. Set to `true` to make all connections set the `useNewUrlParser` option by default
  124. * - 'cloneSchemas': false by default. Set to `true` to `clone()` all schemas before compiling into a model.
  125. * - 'applyPluginsToDiscriminators': false by default. Set to true to apply global plugins to discriminator schemas. This typically isn't necessary because plugins are applied to the base schema and discriminators copy all middleware, methods, statics, and properties from the base schema.
  126. * - 'applyPluginsToChildSchemas': true by default. Set to false to skip applying global plugins to child schemas
  127. * - 'objectIdGetter': true by default. Mongoose adds a getter to MongoDB ObjectId's called `_id` that returns `this` for convenience with populate. Set this to false to remove the getter.
  128. * - 'runValidators': false by default. Set to true to enable [update validators](/docs/validation.html#update-validators) for all validators by default.
  129. * - 'toObject': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toObject()`](/docs/api.html#document_Document-toObject)
  130. * - 'toJSON': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toJSON()`](/docs/api.html#document_Document-toJSON), for determining how Mongoose documents get serialized by `JSON.stringify()`
  131. * - 'strict': true by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas.
  132. * - 'selectPopulatedPaths': true by default. Set to false to opt out of Mongoose adding all fields that you `populate()` to your `select()`. The schema-level option `selectPopulatedPaths` overwrites this one.
  133. * - 'maxTimeMS': If set, attaches [maxTimeMS](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/) to every query
  134. *
  135. * @param {String} key
  136. * @param {String|Function|Boolean} value
  137. * @api public
  138. */
  139. Mongoose.prototype.set = function(key, value) {
  140. if (arguments.length === 1) {
  141. return this.options[key];
  142. }
  143. this.options[key] = value;
  144. if (key === 'objectIdGetter') {
  145. if (value) {
  146. Object.defineProperty(mongoose.Types.ObjectId.prototype, '_id', {
  147. enumerable: false,
  148. configurable: true,
  149. get: function() {
  150. return this;
  151. }
  152. });
  153. } else {
  154. delete mongoose.Types.ObjectId.prototype._id;
  155. }
  156. }
  157. return this;
  158. };
  159. /**
  160. * Gets mongoose options
  161. *
  162. * ####Example:
  163. *
  164. * mongoose.get('test') // returns the 'test' value
  165. *
  166. * @param {String} key
  167. * @method get
  168. * @api public
  169. */
  170. Mongoose.prototype.get = Mongoose.prototype.set;
  171. /**
  172. * Creates a Connection instance.
  173. *
  174. * Each `connection` instance maps to a single database. This method is helpful when mangaging multiple db connections.
  175. *
  176. *
  177. * _Options passed take precedence over options included in connection strings._
  178. *
  179. * ####Example:
  180. *
  181. * // with mongodb:// URI
  182. * db = mongoose.createConnection('mongodb://user:pass@localhost:port/database');
  183. *
  184. * // and options
  185. * var opts = { db: { native_parser: true }}
  186. * db = mongoose.createConnection('mongodb://user:pass@localhost:port/database', opts);
  187. *
  188. * // replica sets
  189. * db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database');
  190. *
  191. * // and options
  192. * var opts = { replset: { strategy: 'ping', rs_name: 'testSet' }}
  193. * db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database', opts);
  194. *
  195. * // and options
  196. * var opts = { server: { auto_reconnect: false }, user: 'username', pass: 'mypassword' }
  197. * db = mongoose.createConnection('localhost', 'database', port, opts)
  198. *
  199. * // initialize now, connect later
  200. * db = mongoose.createConnection();
  201. * db.openUri('localhost', 'database', port, [opts]);
  202. *
  203. * @param {String} [uri] a mongodb:// URI
  204. * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
  205. * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
  206. * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
  207. * @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
  208. * @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](http://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
  209. * @return {Connection} the created Connection object. Connections are thenable, so you can do `await mongoose.createConnection()`
  210. * @api public
  211. */
  212. Mongoose.prototype.createConnection = function(uri, options, callback) {
  213. const conn = new Connection(this);
  214. if (typeof options === 'function') {
  215. callback = options;
  216. options = null;
  217. }
  218. this.connections.push(conn);
  219. if (arguments.length > 0) {
  220. return conn.openUri(uri, options, callback);
  221. }
  222. return conn;
  223. };
  224. /**
  225. * Opens the default mongoose connection.
  226. *
  227. * ####Example:
  228. *
  229. * mongoose.connect('mongodb://user:pass@localhost:port/database');
  230. *
  231. * // replica sets
  232. * var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase';
  233. * mongoose.connect(uri);
  234. *
  235. * // with options
  236. * mongoose.connect(uri, options);
  237. *
  238. * // optional callback that gets fired when initial connection completed
  239. * var uri = 'mongodb://nonexistent.domain:27000';
  240. * mongoose.connect(uri, function(error) {
  241. * // if error is truthy, the initial connection failed.
  242. * })
  243. *
  244. * @param {String} uri(s)
  245. * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
  246. * @param {String} [options.dbName] The name of the database we want to use. If not provided, use database name from connection string.
  247. * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
  248. * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
  249. * @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
  250. * @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](http://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
  251. * @param {Boolean} [options.useCreateIndex=true] Mongoose-specific option. If `true`, this connection will use [`createIndex()` instead of `ensureIndex()`](/docs/deprecations.html#-ensureindex-) for automatic index builds via [`Model.init()`](/docs/api.html#model_Model.init).
  252. * @param {Boolean} [options.useFindAndModify=true] True by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`.
  253. * @param {Boolean} [options.useNewUrlParser=false] False by default. Set to `true` to make all connections set the `useNewUrlParser` option by default.
  254. * @param {Function} [callback]
  255. * @see Mongoose#createConnection #index_Mongoose-createConnection
  256. * @api public
  257. * @return {Promise} resolves to `this` if connection succeeded
  258. */
  259. Mongoose.prototype.connect = function() {
  260. const _mongoose = this instanceof Mongoose ? this : mongoose;
  261. const conn = _mongoose.connection;
  262. if (conn.readyState !== STATES.disconnected) {
  263. throw new _mongoose.Error('You can not `mongoose.connect()` multiple times while connected.');
  264. }
  265. return conn.openUri(arguments[0], arguments[1], arguments[2]).then(() => _mongoose);
  266. };
  267. /**
  268. * Runs `.close()` on all connections in parallel.
  269. *
  270. * @param {Function} [callback] called after all connection close, or when first error occurred.
  271. * @return {Promise} resolves when all connections are closed, or rejects with the first error that occurred.
  272. * @api public
  273. */
  274. Mongoose.prototype.disconnect = function(callback) {
  275. return utils.promiseOrCallback(callback, cb => {
  276. let remaining = this.connections.length;
  277. if (remaining <= 0) {
  278. return cb(null);
  279. }
  280. this.connections.forEach(conn => {
  281. conn.close(function(error) {
  282. if (error) {
  283. return cb(error);
  284. }
  285. if (!--remaining) {
  286. cb(null);
  287. }
  288. });
  289. });
  290. });
  291. };
  292. /**
  293. * _Requires MongoDB >= 3.6.0._ Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
  294. * for benefits like causal consistency, [retryable writes](https://docs.mongodb.com/manual/core/retryable-writes/),
  295. * and [transactions](http://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
  296. *
  297. * Calling `mongoose.startSession()` is equivalent to calling `mongoose.connection.startSession()`.
  298. * Sessions are scoped to a connection, so calling `mongoose.startSession()`
  299. * starts a session on the [default mongoose connection](/docs/api.html#mongoose_Mongoose-connection).
  300. *
  301. * @param {Object} [options] see the [mongodb driver options](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
  302. * @param {Boolean} [options.causalConsistency=true] set to false to disable causal consistency
  303. * @param {Function} [callback]
  304. * @return {Promise<ClientSession>} promise that resolves to a MongoDB driver `ClientSession`
  305. * @api public
  306. */
  307. Mongoose.prototype.startSession = function() {
  308. return this.connection.startSession.apply(this.connection, arguments);
  309. };
  310. /**
  311. * Getter/setter around function for pluralizing collection names.
  312. *
  313. * @param {Function|null} [fn] overwrites the function used to pluralize collection names
  314. * @return {Function|null} the current function used to pluralize collection names, defaults to the legacy function from `mongoose-legacy-pluralize`.
  315. * @api public
  316. */
  317. Mongoose.prototype.pluralize = function(fn) {
  318. if (arguments.length > 0) {
  319. this._pluralize = fn;
  320. }
  321. return this._pluralize;
  322. };
  323. /**
  324. * Defines a model or retrieves it.
  325. *
  326. * Models defined on the `mongoose` instance are available to all connection
  327. * created by the same `mongoose` instance.
  328. *
  329. * If you call `mongoose.model()` with twice the same name but a different schema,
  330. * you will get an `OverwriteModelError`. If you call `mongoose.model()` with
  331. * the same name and same schema, you'll get the same schema back.
  332. *
  333. * ####Example:
  334. *
  335. * var mongoose = require('mongoose');
  336. *
  337. * // define an Actor model with this mongoose instance
  338. * const Schema = new Schema({ name: String });
  339. * mongoose.model('Actor', schema);
  340. *
  341. * // create a new connection
  342. * var conn = mongoose.createConnection(..);
  343. *
  344. * // create Actor model
  345. * var Actor = conn.model('Actor', schema);
  346. * conn.model('Actor') === Actor; // true
  347. * conn.model('Actor', schema) === Actor; // true, same schema
  348. * conn.model('Actor', schema, 'actors') === Actor; // true, same schema and collection name
  349. *
  350. * // This throws an `OverwriteModelError` because the schema is different.
  351. * conn.model('Actor', new Schema({ name: String }));
  352. *
  353. * _When no `collection` argument is passed, Mongoose uses the model name. If you don't like this behavior, either pass a collection name, use `mongoose.pluralize()`, or set your schemas collection name option._
  354. *
  355. * ####Example:
  356. *
  357. * var schema = new Schema({ name: String }, { collection: 'actor' });
  358. *
  359. * // or
  360. *
  361. * schema.set('collection', 'actor');
  362. *
  363. * // or
  364. *
  365. * var collectionName = 'actor'
  366. * var M = mongoose.model('Actor', schema, collectionName)
  367. *
  368. * @param {String|Function} name model name or class extending Model
  369. * @param {Schema} [schema] the schema to use.
  370. * @param {String} [collection] name (optional, inferred from model name)
  371. * @param {Boolean} [skipInit] whether to skip initialization (defaults to false)
  372. * @return {Model} The model associated with `name`. Mongoose will create the model if it doesn't already exist.
  373. * @api public
  374. */
  375. Mongoose.prototype.model = function(name, schema, collection, skipInit) {
  376. const _mongoose = this instanceof Mongoose ? this : mongoose;
  377. let model;
  378. if (typeof name === 'function') {
  379. model = name;
  380. name = model.name;
  381. if (!(model.prototype instanceof Model)) {
  382. throw new _mongoose.Error('The provided class ' + name + ' must extend Model');
  383. }
  384. }
  385. if (typeof schema === 'string') {
  386. collection = schema;
  387. schema = false;
  388. }
  389. if (utils.isObject(schema) && !(schema.instanceOfSchema)) {
  390. schema = new Schema(schema);
  391. }
  392. if (schema && !schema.instanceOfSchema) {
  393. throw new Error('The 2nd parameter to `mongoose.model()` should be a ' +
  394. 'schema or a POJO');
  395. }
  396. if (typeof collection === 'boolean') {
  397. skipInit = collection;
  398. collection = null;
  399. }
  400. // handle internal options from connection.model()
  401. let options;
  402. if (skipInit && utils.isObject(skipInit)) {
  403. options = skipInit;
  404. skipInit = true;
  405. } else {
  406. options = {};
  407. }
  408. // look up schema for the collection.
  409. if (!_mongoose.modelSchemas[name]) {
  410. if (schema) {
  411. // cache it so we only apply plugins once
  412. _mongoose.modelSchemas[name] = schema;
  413. } else {
  414. throw new mongoose.Error.MissingSchemaError(name);
  415. }
  416. }
  417. const originalSchema = schema;
  418. if (schema) {
  419. if (_mongoose.get('cloneSchemas')) {
  420. schema = schema.clone();
  421. }
  422. _mongoose._applyPlugins(schema);
  423. }
  424. let sub;
  425. // connection.model() may be passing a different schema for
  426. // an existing model name. in this case don't read from cache.
  427. if (_mongoose.models[name] && options.cache !== false) {
  428. if (originalSchema &&
  429. originalSchema.instanceOfSchema &&
  430. originalSchema !== _mongoose.models[name].schema) {
  431. throw new _mongoose.Error.OverwriteModelError(name);
  432. }
  433. if (collection && collection !== _mongoose.models[name].collection.name) {
  434. // subclass current model with alternate collection
  435. model = _mongoose.models[name];
  436. schema = model.prototype.schema;
  437. sub = model.__subclass(_mongoose.connection, schema, collection);
  438. // do not cache the sub model
  439. return sub;
  440. }
  441. return _mongoose.models[name];
  442. }
  443. // ensure a schema exists
  444. if (!schema) {
  445. schema = this.modelSchemas[name];
  446. if (!schema) {
  447. throw new mongoose.Error.MissingSchemaError(name);
  448. }
  449. }
  450. // Apply relevant "global" options to the schema
  451. if (!('pluralization' in schema.options)) {
  452. schema.options.pluralization = _mongoose.options.pluralization;
  453. }
  454. if (!collection) {
  455. collection = schema.get('collection') ||
  456. utils.toCollectionName(name, _mongoose.pluralize());
  457. }
  458. const connection = options.connection || _mongoose.connection;
  459. model = _mongoose.Model.compile(model || name, schema, collection, connection, _mongoose);
  460. if (!skipInit) {
  461. // Errors handled internally, so safe to ignore error
  462. model.init(function $modelInitNoop() {});
  463. }
  464. if (options.cache === false) {
  465. return model;
  466. }
  467. _mongoose.models[name] = model;
  468. return _mongoose.models[name];
  469. };
  470. /**
  471. * Removes the model named `name` from the default connection, if it exists.
  472. * You can use this function to clean up any models you created in your tests to
  473. * prevent OverwriteModelErrors.
  474. *
  475. * Equivalent to `mongoose.connection.deleteModel(name)`.
  476. *
  477. * ####Example:
  478. *
  479. * mongoose.model('User', new Schema({ name: String }));
  480. * console.log(mongoose.model('User')); // Model object
  481. * mongoose.deleteModel('User');
  482. * console.log(mongoose.model('User')); // undefined
  483. *
  484. * // Usually useful in a Mocha `afterEach()` hook
  485. * afterEach(function() {
  486. * mongoose.deleteModel(/.+/); // Delete every model
  487. * });
  488. *
  489. * @api public
  490. * @param {String|RegExp} name if string, the name of the model to remove. If regexp, removes all models whose name matches the regexp.
  491. * @return {Mongoose} this
  492. */
  493. Mongoose.prototype.deleteModel = function(name) {
  494. this.connection.deleteModel(name);
  495. return this;
  496. };
  497. /**
  498. * Returns an array of model names created on this instance of Mongoose.
  499. *
  500. * ####Note:
  501. *
  502. * _Does not include names of models created using `connection.model()`._
  503. *
  504. * @api public
  505. * @return {Array}
  506. */
  507. Mongoose.prototype.modelNames = function() {
  508. const names = Object.keys(this.models);
  509. return names;
  510. };
  511. /**
  512. * Applies global plugins to `schema`.
  513. *
  514. * @param {Schema} schema
  515. * @api private
  516. */
  517. Mongoose.prototype._applyPlugins = function(schema, options) {
  518. options = options || {};
  519. options.applyPluginsToDiscriminators = get(this,
  520. 'options.applyPluginsToDiscriminators', false);
  521. options.applyPluginsToChildSchemas = get(this,
  522. 'options.applyPluginsToChildSchemas', true);
  523. applyPlugins(schema, this.plugins, options, '$globalPluginsApplied');
  524. };
  525. /**
  526. * Declares a global plugin executed on all Schemas.
  527. *
  528. * Equivalent to calling `.plugin(fn)` on each Schema you create.
  529. *
  530. * @param {Function} fn plugin callback
  531. * @param {Object} [opts] optional options
  532. * @return {Mongoose} this
  533. * @see plugins ./plugins.html
  534. * @api public
  535. */
  536. Mongoose.prototype.plugin = function(fn, opts) {
  537. this.plugins.push([fn, opts]);
  538. return this;
  539. };
  540. /**
  541. * The Mongoose module's default connection. Equivalent to `mongoose.connections][0]`, see [`connections`](#mongoose_Mongoose-connections).
  542. *
  543. * ####Example:
  544. *
  545. * var mongoose = require('mongoose');
  546. * mongoose.connect(...);
  547. * mongoose.connection.on('error', cb);
  548. *
  549. * This is the connection used by default for every model created using [mongoose.model](#index_Mongoose-model).
  550. *
  551. * To create a new connection, use [`createConnection()`](#mongoose_Mongoose-createConnection).
  552. *
  553. * @memberOf Mongoose
  554. * @instance
  555. * @property {Connection} connection
  556. * @api public
  557. */
  558. Mongoose.prototype.__defineGetter__('connection', function() {
  559. return this.connections[0];
  560. });
  561. Mongoose.prototype.__defineSetter__('connection', function(v) {
  562. if (v instanceof Connection) {
  563. this.connections[0] = v;
  564. this.models = v.models;
  565. }
  566. });
  567. /**
  568. * An array containing all [connections](connections.html) associated with this
  569. * Mongoose instance. By default, there is 1 connection. Calling
  570. * [`createConnection()`](#mongoose_Mongoose-createConnection) adds a connection
  571. * to this array.
  572. *
  573. * ####Example:
  574. *
  575. * const mongoose = require('mongoose');
  576. * mongoose.connections.length; // 1, just the default connection
  577. * mongoose.connections[0] === mongoose.connection; // true
  578. *
  579. * mongoose.createConnection('mongodb://localhost:27017/test');
  580. * mongoose.connections.length; // 2
  581. *
  582. * @memberOf Mongoose
  583. * @instance
  584. * @property {Array} connections
  585. * @api public
  586. */
  587. Mongoose.prototype.connections;
  588. /*!
  589. * Driver dependent APIs
  590. */
  591. const driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
  592. /*!
  593. * Connection
  594. */
  595. const Connection = require(driver + '/connection');
  596. /*!
  597. * Collection
  598. */
  599. const Collection = require(driver + '/collection');
  600. /**
  601. * The Mongoose Aggregate constructor
  602. *
  603. * @method Aggregate
  604. * @api public
  605. */
  606. Mongoose.prototype.Aggregate = Aggregate;
  607. /**
  608. * The Mongoose Collection constructor
  609. *
  610. * @method Collection
  611. * @api public
  612. */
  613. Mongoose.prototype.Collection = Collection;
  614. /**
  615. * The Mongoose [Connection](#connection_Connection) constructor
  616. *
  617. * @memberOf Mongoose
  618. * @instance
  619. * @method Connection
  620. * @api public
  621. */
  622. Mongoose.prototype.Connection = Connection;
  623. /**
  624. * The Mongoose version
  625. *
  626. * #### Example
  627. *
  628. * console.log(mongoose.version); // '5.x.x'
  629. *
  630. * @property version
  631. * @api public
  632. */
  633. Mongoose.prototype.version = pkg.version;
  634. /**
  635. * The Mongoose constructor
  636. *
  637. * The exports of the mongoose module is an instance of this class.
  638. *
  639. * ####Example:
  640. *
  641. * var mongoose = require('mongoose');
  642. * var mongoose2 = new mongoose.Mongoose();
  643. *
  644. * @method Mongoose
  645. * @api public
  646. */
  647. Mongoose.prototype.Mongoose = Mongoose;
  648. /**
  649. * The Mongoose [Schema](#schema_Schema) constructor
  650. *
  651. * ####Example:
  652. *
  653. * var mongoose = require('mongoose');
  654. * var Schema = mongoose.Schema;
  655. * var CatSchema = new Schema(..);
  656. *
  657. * @method Schema
  658. * @api public
  659. */
  660. Mongoose.prototype.Schema = Schema;
  661. /**
  662. * The Mongoose [SchemaType](#schematype_SchemaType) constructor
  663. *
  664. * @method SchemaType
  665. * @api public
  666. */
  667. Mongoose.prototype.SchemaType = SchemaType;
  668. /**
  669. * The various Mongoose SchemaTypes.
  670. *
  671. * ####Note:
  672. *
  673. * _Alias of mongoose.Schema.Types for backwards compatibility._
  674. *
  675. * @property SchemaTypes
  676. * @see Schema.SchemaTypes #schema_Schema.Types
  677. * @api public
  678. */
  679. Mongoose.prototype.SchemaTypes = Schema.Types;
  680. /**
  681. * The Mongoose [VirtualType](#virtualtype_VirtualType) constructor
  682. *
  683. * @method VirtualType
  684. * @api public
  685. */
  686. Mongoose.prototype.VirtualType = VirtualType;
  687. /**
  688. * The various Mongoose Types.
  689. *
  690. * ####Example:
  691. *
  692. * var mongoose = require('mongoose');
  693. * var array = mongoose.Types.Array;
  694. *
  695. * ####Types:
  696. *
  697. * - [ObjectId](#types-objectid-js)
  698. * - [Buffer](#types-buffer-js)
  699. * - [SubDocument](#types-embedded-js)
  700. * - [Array](#types-array-js)
  701. * - [DocumentArray](#types-documentarray-js)
  702. *
  703. * Using this exposed access to the `ObjectId` type, we can construct ids on demand.
  704. *
  705. * var ObjectId = mongoose.Types.ObjectId;
  706. * var id1 = new ObjectId;
  707. *
  708. * @property Types
  709. * @api public
  710. */
  711. Mongoose.prototype.Types = Types;
  712. /**
  713. * The Mongoose [Query](#query_Query) constructor.
  714. *
  715. * @method Query
  716. * @api public
  717. */
  718. Mongoose.prototype.Query = Query;
  719. /**
  720. * The Mongoose [Promise](#promise_Promise) constructor.
  721. *
  722. * @memberOf Mongoose
  723. * @instance
  724. * @property Promise
  725. * @api public
  726. */
  727. Object.defineProperty(Mongoose.prototype, 'Promise', {
  728. get: function() {
  729. return PromiseProvider.get();
  730. },
  731. set: function(lib) {
  732. PromiseProvider.set(lib);
  733. }
  734. });
  735. /**
  736. * Storage layer for mongoose promises
  737. *
  738. * @method PromiseProvider
  739. * @api public
  740. */
  741. Mongoose.prototype.PromiseProvider = PromiseProvider;
  742. /**
  743. * The Mongoose [Model](#model_Model) constructor.
  744. *
  745. * @method Model
  746. * @api public
  747. */
  748. Mongoose.prototype.Model = Model;
  749. /**
  750. * The Mongoose [Document](#document-js) constructor.
  751. *
  752. * @method Document
  753. * @api public
  754. */
  755. Mongoose.prototype.Document = Document;
  756. /**
  757. * The Mongoose DocumentProvider constructor. Mongoose users should not have to
  758. * use this directly
  759. *
  760. * @method DocumentProvider
  761. * @api public
  762. */
  763. Mongoose.prototype.DocumentProvider = require('./document_provider');
  764. /**
  765. * The Mongoose ObjectId [SchemaType](/docs/schematypes.html). Used for
  766. * declaring paths in your schema that should be
  767. * [MongoDB ObjectIds](https://docs.mongodb.com/manual/reference/method/ObjectId/).
  768. * Do not use this to create a new ObjectId instance, use `mongoose.Types.ObjectId`
  769. * instead.
  770. *
  771. * ####Example:
  772. *
  773. * const childSchema = new Schema({ parentId: mongoose.ObjectId });
  774. *
  775. * @property ObjectId
  776. * @api public
  777. */
  778. Mongoose.prototype.ObjectId = SchemaTypes.ObjectId;
  779. /**
  780. * The Mongoose Decimal128 [SchemaType](/docs/schematypes.html). Used for
  781. * declaring paths in your schema that should be
  782. * [128-bit decimal floating points](http://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-decimal.html).
  783. * Do not use this to create a new Decimal128 instance, use `mongoose.Types.Decimal128`
  784. * instead.
  785. *
  786. * ####Example:
  787. *
  788. * const vehicleSchema = new Schema({ fuelLevel: mongoose.Decimal128 });
  789. *
  790. * @property Decimal128
  791. * @api public
  792. */
  793. Mongoose.prototype.Decimal128 = SchemaTypes.Decimal128;
  794. /**
  795. * The Mongoose Mixed [SchemaType](/docs/schematypes.html). Used for
  796. * declaring paths in your schema that Mongoose's change tracking, casting,
  797. * and validation should ignore.
  798. *
  799. * ####Example:
  800. *
  801. * const schema = new Schema({ arbitrary: mongoose.Mixed });
  802. *
  803. * @property Mixed
  804. * @api public
  805. */
  806. Mongoose.prototype.Mixed = SchemaTypes.Mixed;
  807. /**
  808. * The Mongoose Number [SchemaType](/docs/schematypes.html). Used for
  809. * declaring paths in your schema that Mongoose should cast to numbers.
  810. *
  811. * ####Example:
  812. *
  813. * const schema = new Schema({ num: mongoose.Number });
  814. * // Equivalent to:
  815. * const schema = new Schema({ num: 'number' });
  816. *
  817. * @property Number
  818. * @api public
  819. */
  820. Mongoose.prototype.Number = SchemaTypes.Number;
  821. /**
  822. * The [MongooseError](#error_MongooseError) constructor.
  823. *
  824. * @method Error
  825. * @api public
  826. */
  827. Mongoose.prototype.Error = require('./error');
  828. /**
  829. * Mongoose uses this function to get the current time when setting
  830. * [timestamps](/docs/guide.html#timestamps). You may stub out this function
  831. * using a tool like [Sinon](https://www.npmjs.com/package/sinon) for testing.
  832. *
  833. * @method now
  834. * @returns Date the current time
  835. * @api public
  836. */
  837. Mongoose.prototype.now = function now() { return new Date(); };
  838. /**
  839. * The Mongoose CastError constructor
  840. *
  841. * @method CastError
  842. * @param {String} type The name of the type
  843. * @param {Any} value The value that failed to cast
  844. * @param {String} path The path `a.b.c` in the doc where this cast error occurred
  845. * @param {Error} [reason] The original error that was thrown
  846. * @api public
  847. */
  848. Mongoose.prototype.CastError = require('./error/cast');
  849. /**
  850. * The [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver Mongoose uses.
  851. *
  852. * @property mongo
  853. * @api public
  854. */
  855. Mongoose.prototype.mongo = require('mongodb');
  856. /**
  857. * The [mquery](https://github.com/aheckmann/mquery) query builder Mongoose uses.
  858. *
  859. * @property mquery
  860. * @api public
  861. */
  862. Mongoose.prototype.mquery = require('mquery');
  863. /*!
  864. * The exports object is an instance of Mongoose.
  865. *
  866. * @api public
  867. */
  868. const mongoose = module.exports = exports = new Mongoose({
  869. [defaultMongooseSymbol]: true
  870. });