objectid.js 4.1 KB

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