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.

167 lines
3.3 KiB

  1. /*!
  2. * Module requirements.
  3. */
  4. var SchemaType = require('../schematype');
  5. var CastError = SchemaType.CastError;
  6. var utils = require('../utils');
  7. /**
  8. * Date SchemaType constructor.
  9. *
  10. * @param {String} key
  11. * @param {Object} options
  12. * @inherits SchemaType
  13. * @api private
  14. */
  15. function SchemaDate (key, options) {
  16. SchemaType.call(this, key, options);
  17. };
  18. /*!
  19. * Inherits from SchemaType.
  20. */
  21. SchemaDate.prototype.__proto__ = SchemaType.prototype;
  22. /**
  23. * Declares a TTL index (rounded to the nearest second) for _Date_ types only.
  24. *
  25. * This sets the `expiresAfterSeconds` index option available in MongoDB >= 2.1.2.
  26. * This index type is only compatible with Date types.
  27. *
  28. * ####Example:
  29. *
  30. * // expire in 24 hours
  31. * new Schema({ createdAt: { type: Date, expires: 60*60*24 }});
  32. *
  33. * `expires` utilizes the `ms` module from [guille](https://github.com/guille/) allowing us to use a friendlier syntax:
  34. *
  35. * ####Example:
  36. *
  37. * // expire in 24 hours
  38. * new Schema({ createdAt: { type: Date, expires: '24h' }});
  39. *
  40. * // expire in 1.5 hours
  41. * new Schema({ createdAt: { type: Date, expires: '1.5h' }});
  42. *
  43. * // expire in 7 days
  44. * var schema = new Schema({ createdAt: Date });
  45. * schema.path('createdAt').expires('7d');
  46. *
  47. * @param {Number|String} when
  48. * @added 3.0.0
  49. * @return {SchemaType} this
  50. * @api public
  51. */
  52. SchemaDate.prototype.expires = function (when) {
  53. if (!this._index || 'Object' !== this._index.constructor.name) {
  54. this._index = {};
  55. }
  56. this._index.expires = when;
  57. utils.expires(this._index);
  58. return this;
  59. };
  60. /**
  61. * Required validator for date
  62. *
  63. * @api private
  64. */
  65. SchemaDate.prototype.checkRequired = function (value) {
  66. return value instanceof Date;
  67. };
  68. /**
  69. * Casts to date
  70. *
  71. * @param {Object} value to cast
  72. * @api private
  73. */
  74. SchemaDate.prototype.cast = function (value) {
  75. if (value === null || value === '')
  76. return null;
  77. if (value instanceof Date)
  78. return value;
  79. var date;
  80. // support for timestamps
  81. if (value instanceof Number || 'number' == typeof value
  82. || String(value) == Number(value))
  83. date = new Date(Number(value));
  84. // support for date strings
  85. else if (value.toString)
  86. date = new Date(value.toString());
  87. if (date.toString() != 'Invalid Date')
  88. return date;
  89. throw new CastError('date', value, this.path);
  90. };
  91. /*!
  92. * Date Query casting.
  93. *
  94. * @api private
  95. */
  96. function handleSingle (val) {
  97. return this.cast(val);
  98. }
  99. function handleArray (val) {
  100. var self = this;
  101. return val.map( function (m) {
  102. return self.cast(m);
  103. });
  104. }
  105. SchemaDate.prototype.$conditionalHandlers = {
  106. '$lt': handleSingle
  107. , '$lte': handleSingle
  108. , '$gt': handleSingle
  109. , '$gte': handleSingle
  110. , '$ne': handleSingle
  111. , '$in': handleArray
  112. , '$nin': handleArray
  113. , '$all': handleArray
  114. };
  115. /**
  116. * Casts contents for queries.
  117. *
  118. * @param {String} $conditional
  119. * @param {any} [value]
  120. * @api private
  121. */
  122. SchemaDate.prototype.castForQuery = function ($conditional, val) {
  123. var handler;
  124. if (2 !== arguments.length) {
  125. return this.cast($conditional);
  126. }
  127. handler = this.$conditionalHandlers[$conditional];
  128. if (!handler) {
  129. throw new Error("Can't use " + $conditional + " with Date.");
  130. }
  131. return handler.call(this, val);
  132. };
  133. /*!
  134. * Module exports.
  135. */
  136. module.exports = SchemaDate;