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.

186 lines
3.7 KiB

  1. /*!
  2. * Module dependencies.
  3. */
  4. var SchemaType = require('../schematype')
  5. , CastError = SchemaType.CastError
  6. , driver = global.MONGOOSE_DRIVER_PATH || './../drivers/node-mongodb-native'
  7. , oid = require('../types/objectid')
  8. , utils = require('../utils')
  9. , Document
  10. /**
  11. * ObjectId SchemaType constructor.
  12. *
  13. * @param {String} key
  14. * @param {Object} options
  15. * @inherits SchemaType
  16. * @api private
  17. */
  18. function ObjectId (key, options) {
  19. SchemaType.call(this, key, options, 'ObjectID');
  20. };
  21. /*!
  22. * Inherits from SchemaType.
  23. */
  24. ObjectId.prototype.__proto__ = SchemaType.prototype;
  25. /**
  26. * Adds an auto-generated ObjectId default if turnOn is true.
  27. * @param {Boolean} turnOn auto generated ObjectId defaults
  28. * @api public
  29. * @return {SchemaType} this
  30. */
  31. ObjectId.prototype.auto = function (turnOn) {
  32. if (turnOn) {
  33. this.default(defaultId);
  34. this.set(resetId)
  35. }
  36. return this;
  37. };
  38. /**
  39. * Check required
  40. *
  41. * @api private
  42. */
  43. ObjectId.prototype.checkRequired = function checkRequired (value, doc) {
  44. if (SchemaType._isRef(this, value, doc, true)) {
  45. return null != value;
  46. } else {
  47. return value instanceof oid;
  48. }
  49. };
  50. /**
  51. * Casts to ObjectId
  52. *
  53. * @param {Object} value
  54. * @param {Object} doc
  55. * @param {Boolean} init whether this is an initialization cast
  56. * @api private
  57. */
  58. ObjectId.prototype.cast = function (value, doc, init) {
  59. if (SchemaType._isRef(this, value, doc, init)) {
  60. // wait! we may need to cast this to a document
  61. if (null == value) {
  62. return value;
  63. }
  64. // lazy load
  65. Document || (Document = require('./../document'));
  66. if (value instanceof Document) {
  67. value.$__.wasPopulated = true;
  68. return value;
  69. }
  70. // setting a populated path
  71. if (value instanceof oid) {
  72. return value;
  73. } else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
  74. throw new CastError('ObjectId', value, this.path);
  75. }
  76. // Handle the case where user directly sets a populated
  77. // path to a plain object; cast to the Model used in
  78. // the population query.
  79. var path = doc.$__fullPath(this.path);
  80. var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
  81. var pop = owner.populated(path, true);
  82. var ret = new pop.options.model(value);
  83. ret.$__.wasPopulated = true;
  84. return ret;
  85. }
  86. if (value === null) return value;
  87. if (value instanceof oid)
  88. return value;
  89. if (value._id && value._id instanceof oid)
  90. return value._id;
  91. if (value.toString) {
  92. try {
  93. return oid.fromString(value.toString());
  94. } catch (err) {
  95. throw new CastError('ObjectId', value, this.path);
  96. }
  97. }
  98. throw new CastError('ObjectId', value, this.path);
  99. };
  100. /*!
  101. * ignore
  102. */
  103. function handleSingle (val) {
  104. return this.cast(val);
  105. }
  106. function handleArray (val) {
  107. var self = this;
  108. return val.map(function (m) {
  109. return self.cast(m);
  110. });
  111. }
  112. ObjectId.prototype.$conditionalHandlers = {
  113. '$ne': handleSingle
  114. , '$in': handleArray
  115. , '$nin': handleArray
  116. , '$gt': handleSingle
  117. , '$lt': handleSingle
  118. , '$gte': handleSingle
  119. , '$lte': handleSingle
  120. , '$all': handleArray
  121. };
  122. /**
  123. * Casts contents for queries.
  124. *
  125. * @param {String} $conditional
  126. * @param {any} [val]
  127. * @api private
  128. */
  129. ObjectId.prototype.castForQuery = function ($conditional, val) {
  130. var handler;
  131. if (arguments.length === 2) {
  132. handler = this.$conditionalHandlers[$conditional];
  133. if (!handler)
  134. throw new Error("Can't use " + $conditional + " with ObjectId.");
  135. return handler.call(this, val);
  136. } else {
  137. return this.cast($conditional);
  138. }
  139. };
  140. /*!
  141. * ignore
  142. */
  143. function defaultId () {
  144. return new oid();
  145. };
  146. function resetId (v) {
  147. this.$__._id = null;
  148. return v;
  149. }
  150. /*!
  151. * Module exports.
  152. */
  153. module.exports = ObjectId;