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.

168 lines
3.6 KiB

  1. /*!
  2. * Module dependencies.
  3. */
  4. var SchemaType = require('../schematype')
  5. , CastError = SchemaType.CastError
  6. , MongooseBuffer = require('../types').Buffer
  7. , Binary = MongooseBuffer.Binary
  8. , Query = require('../query')
  9. , utils = require('../utils')
  10. , Document
  11. /**
  12. * Buffer SchemaType constructor
  13. *
  14. * @param {String} key
  15. * @param {SchemaType} cast
  16. * @inherits SchemaType
  17. * @api private
  18. */
  19. function SchemaBuffer (key, options) {
  20. SchemaType.call(this, key, options, 'Buffer');
  21. };
  22. /*!
  23. * Inherits from SchemaType.
  24. */
  25. SchemaBuffer.prototype.__proto__ = SchemaType.prototype;
  26. /**
  27. * Check required
  28. *
  29. * @api private
  30. */
  31. SchemaBuffer.prototype.checkRequired = function (value, doc) {
  32. if (SchemaType._isRef(this, value, doc, true)) {
  33. return null != value;
  34. } else {
  35. return !!(value && value.length);
  36. }
  37. };
  38. /**
  39. * Casts contents
  40. *
  41. * @param {Object} value
  42. * @param {Document} doc document that triggers the casting
  43. * @param {Boolean} init
  44. * @api private
  45. */
  46. SchemaBuffer.prototype.cast = function (value, doc, init) {
  47. if (SchemaType._isRef(this, value, doc, init)) {
  48. // wait! we may need to cast this to a document
  49. if (null == value) {
  50. return value;
  51. }
  52. // lazy load
  53. Document || (Document = require('./../document'));
  54. if (value instanceof Document) {
  55. value.$__.wasPopulated = true;
  56. return value;
  57. }
  58. // setting a populated path
  59. if (Buffer.isBuffer(value)) {
  60. return value;
  61. } else if (!utils.isObject(value)) {
  62. throw new CastError('buffer', value, this.path);
  63. }
  64. // Handle the case where user directly sets a populated
  65. // path to a plain object; cast to the Model used in
  66. // the population query.
  67. var path = doc.$__fullPath(this.path);
  68. var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
  69. var pop = owner.populated(path, true);
  70. var ret = new pop.options.model(value);
  71. ret.$__.wasPopulated = true;
  72. return ret;
  73. }
  74. // documents
  75. if (value && value._id) {
  76. value = value._id;
  77. }
  78. if (Buffer.isBuffer(value)) {
  79. if (!(value instanceof MongooseBuffer)) {
  80. value = new MongooseBuffer(value, [this.path, doc]);
  81. }
  82. return value;
  83. } else if (value instanceof Binary) {
  84. var ret = new MongooseBuffer(value.value(true), [this.path, doc]);
  85. ret._subtype = value.sub_type;
  86. // do not override Binary subtypes. users set this
  87. // to whatever they want.
  88. return ret;
  89. }
  90. if (null === value) return value;
  91. var type = typeof value;
  92. if ('string' == type || 'number' == type || Array.isArray(value)) {
  93. var ret = new MongooseBuffer(value, [this.path, doc]);
  94. return ret;
  95. }
  96. throw new CastError('buffer', value, this.path);
  97. };
  98. /*!
  99. * ignore
  100. */
  101. function handleSingle (val) {
  102. return this.castForQuery(val);
  103. }
  104. function handleArray (val) {
  105. var self = this;
  106. return val.map( function (m) {
  107. return self.castForQuery(m);
  108. });
  109. }
  110. SchemaBuffer.prototype.$conditionalHandlers = {
  111. '$ne' : handleSingle
  112. , '$in' : handleArray
  113. , '$nin': handleArray
  114. , '$gt' : handleSingle
  115. , '$lt' : handleSingle
  116. , '$gte': handleSingle
  117. , '$lte': handleSingle
  118. };
  119. /**
  120. * Casts contents for queries.
  121. *
  122. * @param {String} $conditional
  123. * @param {any} [value]
  124. * @api private
  125. */
  126. SchemaBuffer.prototype.castForQuery = function ($conditional, val) {
  127. var handler;
  128. if (arguments.length === 2) {
  129. handler = this.$conditionalHandlers[$conditional];
  130. if (!handler)
  131. throw new Error("Can't use " + $conditional + " with Buffer.");
  132. return handler.call(this, val);
  133. } else {
  134. val = $conditional;
  135. return this.cast(val).toObject();
  136. }
  137. };
  138. /*!
  139. * Module exports.
  140. */
  141. module.exports = SchemaBuffer;