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.

103 lines
2.7 KiB

  1. /*!
  2. * Module dependencies.
  3. */
  4. var NodeJSDocument = require('./document'),
  5. EventEmitter = require('events').EventEmitter,
  6. MongooseError = require('./error'),
  7. Schema = require('./schema'),
  8. ObjectId = require('./types/objectid'),
  9. utils = require('./utils'),
  10. ValidationError = MongooseError.ValidationError,
  11. InternalCache = require('./internal');
  12. /**
  13. * Document constructor.
  14. *
  15. * @param {Object} obj the values to set
  16. * @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
  17. * @param {Boolean} [skipId] bool, should we auto create an ObjectId _id
  18. * @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
  19. * @event `init`: Emitted on a document after it has was retrieved from the db and fully hydrated by Mongoose.
  20. * @event `save`: Emitted when the document is successfully saved
  21. * @api private
  22. */
  23. function Document(obj, schema, fields, skipId, skipInit) {
  24. if (!(this instanceof Document)) {
  25. return new Document(obj, schema, fields, skipId, skipInit);
  26. }
  27. if (utils.isObject(schema) && !schema.instanceOfSchema) {
  28. schema = new Schema(schema);
  29. }
  30. // When creating EmbeddedDocument, it already has the schema and he doesn't need the _id
  31. schema = this.schema || schema;
  32. // Generate ObjectId if it is missing, but it requires a scheme
  33. if (!this.schema && schema.options._id) {
  34. obj = obj || {};
  35. if (obj._id === undefined) {
  36. obj._id = new ObjectId();
  37. }
  38. }
  39. if (!schema) {
  40. throw new MongooseError.MissingSchemaError();
  41. }
  42. this.$__setSchema(schema);
  43. this.$__ = new InternalCache;
  44. this.$__.emitter = new EventEmitter();
  45. this.isNew = true;
  46. this.errors = undefined;
  47. // var schema = this.schema;
  48. if (typeof fields === 'boolean') {
  49. this.$__.strictMode = fields;
  50. fields = undefined;
  51. } else {
  52. this.$__.strictMode = this.schema.options && this.schema.options.strict;
  53. this.$__.selected = fields;
  54. }
  55. var required = this.schema.requiredPaths();
  56. for (var i = 0; i < required.length; ++i) {
  57. this.$__.activePaths.require(required[i]);
  58. }
  59. this.$__.emitter.setMaxListeners(0);
  60. this._doc = this.$__buildDoc(obj, fields, skipId);
  61. if (!skipInit && obj) {
  62. this.init(obj);
  63. }
  64. this.$__registerHooksFromSchema();
  65. // apply methods
  66. for (var m in schema.methods) {
  67. this[m] = schema.methods[m];
  68. }
  69. // apply statics
  70. for (var s in schema.statics) {
  71. this[s] = schema.statics[s];
  72. }
  73. }
  74. /*!
  75. * Inherit from the NodeJS document
  76. */
  77. Document.prototype = Object.create(NodeJSDocument.prototype);
  78. Document.prototype.constructor = Document;
  79. /*!
  80. * Module exports.
  81. */
  82. Document.ValidationError = ValidationError;
  83. module.exports = exports = Document;