arnaucube
arnaucube/thoughtsPublic Self-hosted repository
thoughts/node_modules/mongoose/lib/schema/number.js
node_modules/mongoose/lib/schema/number.jsRaw
  1/*!
  2 * Module requirements.
  3 */
  4
  5var SchemaType = require('../schematype');
  6var CastError = SchemaType.CastError;
  7var handleBitwiseOperator = require('./operators/bitwise');
  8var MongooseError = require('../error');
  9var utils = require('../utils');
 10var Document;
 11
 12/**
 13 * Number SchemaType constructor.
 14 *
 15 * @param {String} key
 16 * @param {Object} options
 17 * @inherits SchemaType
 18 * @api public
 19 */
 20
 21function SchemaNumber(key, options) {
 22  SchemaType.call(this, key, options, 'Number');
 23}
 24
 25/**
 26 * This schema type's name, to defend against minifiers that mangle
 27 * function names.
 28 *
 29 * @api public
 30 */
 31SchemaNumber.schemaName = 'Number';
 32
 33/*!
 34 * Inherits from SchemaType.
 35 */
 36SchemaNumber.prototype = Object.create(SchemaType.prototype);
 37SchemaNumber.prototype.constructor = SchemaNumber;
 38
 39/**
 40 * Check if the given value satisfies a required validator.
 41 *
 42 * @param {Any} value
 43 * @param {Document} doc
 44 * @return {Boolean}
 45 * @api public
 46 */
 47
 48SchemaNumber.prototype.checkRequired = function checkRequired(value, doc) {
 49  if (SchemaType._isRef(this, value, doc, true)) {
 50    return !!value;
 51  }
 52  return typeof value === 'number' || value instanceof Number;
 53};
 54
 55/**
 56 * Sets a minimum number validator.
 57 *
 58 * ####Example:
 59 *
 60 *     var s = new Schema({ n: { type: Number, min: 10 })
 61 *     var M = db.model('M', s)
 62 *     var m = new M({ n: 9 })
 63 *     m.save(function (err) {
 64 *       console.error(err) // validator error
 65 *       m.n = 10;
 66 *       m.save() // success
 67 *     })
 68 *
 69 *     // custom error messages
 70 *     // We can also use the special {MIN} token which will be replaced with the invalid value
 71 *     var min = [10, 'The value of path `{PATH}` ({VALUE}) is beneath the limit ({MIN}).'];
 72 *     var schema = new Schema({ n: { type: Number, min: min })
 73 *     var M = mongoose.model('Measurement', schema);
 74 *     var s= new M({ n: 4 });
 75 *     s.validate(function (err) {
 76 *       console.log(String(err)) // ValidationError: The value of path `n` (4) is beneath the limit (10).
 77 *     })
 78 *
 79 * @param {Number} value minimum number
 80 * @param {String} [message] optional custom error message
 81 * @return {SchemaType} this
 82 * @see Customized Error Messages #error_messages_MongooseError-messages
 83 * @api public
 84 */
 85
 86SchemaNumber.prototype.min = function(value, message) {
 87  if (this.minValidator) {
 88    this.validators = this.validators.filter(function(v) {
 89      return v.validator !== this.minValidator;
 90    }, this);
 91  }
 92
 93  if (value !== null && value !== undefined) {
 94    var msg = message || MongooseError.messages.Number.min;
 95    msg = msg.replace(/{MIN}/, value);
 96    this.validators.push({
 97      validator: this.minValidator = function(v) {
 98        return v == null || v >= value;
 99      },
100      message: msg,
101      type: 'min',
102      min: value
103    });
104  }
105
106  return this;
107};
108
109/**
110 * Sets a maximum number validator.
111 *
112 * ####Example:
113 *
114 *     var s = new Schema({ n: { type: Number, max: 10 })
115 *     var M = db.model('M', s)
116 *     var m = new M({ n: 11 })
117 *     m.save(function (err) {
118 *       console.error(err) // validator error
119 *       m.n = 10;
120 *       m.save() // success
121 *     })
122 *
123 *     // custom error messages
124 *     // We can also use the special {MAX} token which will be replaced with the invalid value
125 *     var max = [10, 'The value of path `{PATH}` ({VALUE}) exceeds the limit ({MAX}).'];
126 *     var schema = new Schema({ n: { type: Number, max: max })
127 *     var M = mongoose.model('Measurement', schema);
128 *     var s= new M({ n: 4 });
129 *     s.validate(function (err) {
130 *       console.log(String(err)) // ValidationError: The value of path `n` (4) exceeds the limit (10).
131 *     })
132 *
133 * @param {Number} maximum number
134 * @param {String} [message] optional custom error message
135 * @return {SchemaType} this
136 * @see Customized Error Messages #error_messages_MongooseError-messages
137 * @api public
138 */
139
140SchemaNumber.prototype.max = function(value, message) {
141  if (this.maxValidator) {
142    this.validators = this.validators.filter(function(v) {
143      return v.validator !== this.maxValidator;
144    }, this);
145  }
146
147  if (value !== null && value !== undefined) {
148    var msg = message || MongooseError.messages.Number.max;
149    msg = msg.replace(/{MAX}/, value);
150    this.validators.push({
151      validator: this.maxValidator = function(v) {
152        return v == null || v <= value;
153      },
154      message: msg,
155      type: 'max',
156      max: value
157    });
158  }
159
160  return this;
161};
162
163/**
164 * Casts to number
165 *
166 * @param {Object} value value to cast
167 * @param {Document} doc document that triggers the casting
168 * @param {Boolean} init
169 * @api private
170 */
171
172SchemaNumber.prototype.cast = function(value, doc, init) {
173  if (SchemaType._isRef(this, value, doc, init)) {
174    // wait! we may need to cast this to a document
175
176    if (value === null || value === undefined) {
177      return value;
178    }
179
180    // lazy load
181    Document || (Document = require('./../document'));
182
183    if (value instanceof Document) {
184      value.$__.wasPopulated = true;
185      return value;
186    }
187
188    // setting a populated path
189    if (typeof value === 'number') {
190      return value;
191    } else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
192      throw new CastError('number', value, this.path);
193    }
194
195    // Handle the case where user directly sets a populated
196    // path to a plain object; cast to the Model used in
197    // the population query.
198    var path = doc.$__fullPath(this.path);
199    var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
200    var pop = owner.populated(path, true);
201    var ret = new pop.options.model(value);
202    ret.$__.wasPopulated = true;
203    return ret;
204  }
205
206  var val = value && value._id
207      ? value._id // documents
208      : value;
209
210  if (!isNaN(val)) {
211    if (val === null) {
212      return val;
213    }
214    if (val === '') {
215      return null;
216    }
217    if (typeof val === 'string' || typeof val === 'boolean') {
218      val = Number(val);
219    }
220    if (val instanceof Number) {
221      return val;
222    }
223    if (typeof val === 'number') {
224      return val;
225    }
226    if (val.toString && !Array.isArray(val) && val.toString() == Number(val)) {
227      return new Number(val);
228    }
229  }
230
231  throw new CastError('number', value, this.path);
232};
233
234/*!
235 * ignore
236 */
237
238function handleSingle(val) {
239  return this.cast(val);
240}
241
242function handleArray(val) {
243  var _this = this;
244  if (!Array.isArray(val)) {
245    return [this.cast(val)];
246  }
247  return val.map(function(m) {
248    return _this.cast(m);
249  });
250}
251
252SchemaNumber.prototype.$conditionalHandlers =
253    utils.options(SchemaType.prototype.$conditionalHandlers, {
254      $bitsAllClear: handleBitwiseOperator,
255      $bitsAnyClear: handleBitwiseOperator,
256      $bitsAllSet: handleBitwiseOperator,
257      $bitsAnySet: handleBitwiseOperator,
258      $gt: handleSingle,
259      $gte: handleSingle,
260      $lt: handleSingle,
261      $lte: handleSingle,
262      $mod: handleArray
263    });
264
265/**
266 * Casts contents for queries.
267 *
268 * @param {String} $conditional
269 * @param {any} [value]
270 * @api private
271 */
272
273SchemaNumber.prototype.castForQuery = function($conditional, val) {
274  var handler;
275  if (arguments.length === 2) {
276    handler = this.$conditionalHandlers[$conditional];
277    if (!handler) {
278      throw new Error('Can\'t use ' + $conditional + ' with Number.');
279    }
280    return handler.call(this, val);
281  }
282  val = this.cast($conditional);
283  return val;
284};
285
286/*!
287 * Module exports.
288 */
289
290module.exports = SchemaNumber;