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')
  6  , CastError = SchemaType.CastError
  7  , utils = require('../utils')
  8  , Document
  9
 10/**
 11 * Number SchemaType constructor.
 12 *
 13 * @param {String} key
 14 * @param {Object} options
 15 * @inherits SchemaType
 16 * @api private
 17 */
 18
 19function SchemaNumber (key, options) {
 20  SchemaType.call(this, key, options, 'Number');
 21};
 22
 23/*!
 24 * Inherits from SchemaType.
 25 */
 26
 27SchemaNumber.prototype.__proto__ = SchemaType.prototype;
 28
 29/**
 30 * Required validator for number
 31 *
 32 * @api private
 33 */
 34
 35SchemaNumber.prototype.checkRequired = function checkRequired (value, doc) {
 36  if (SchemaType._isRef(this, value, doc, true)) {
 37    return null != value;
 38  } else {
 39    return typeof value == 'number' || value instanceof Number;
 40  }
 41};
 42
 43/**
 44 * Sets a minimum number validator.
 45 *
 46 * ####Example:
 47 *
 48 *     var s = new Schema({ n: { type: Number, min: 10 })
 49 *     var M = db.model('M', s)
 50 *     var m = new M({ n: 9 })
 51 *     m.save(function (err) {
 52 *       console.error(err) // validator error
 53 *       m.n = 10;
 54 *       m.save() // success
 55 *     })
 56 *
 57 * @param {Number} value minimum number
 58 * @return {SchemaType} this
 59 * @api public
 60 */
 61
 62SchemaNumber.prototype.min = function (value) {
 63  if (this.minValidator) {
 64    this.validators = this.validators.filter(function (v) {
 65      return 'min' != v[1];
 66    });
 67  }
 68
 69  if (value != null) {
 70    this.validators.push([this.minValidator = function (v) {
 71      return v === null || v >= value;
 72    }, 'min']);
 73  }
 74
 75  return this;
 76};
 77
 78/**
 79 * Sets a maximum number validator.
 80 *
 81 * ####Example:
 82 *
 83 *     var s = new Schema({ n: { type: Number, max: 10 })
 84 *     var M = db.model('M', s)
 85 *     var m = new M({ n: 11 })
 86 *     m.save(function (err) {
 87 *       console.error(err) // validator error
 88 *       m.n = 10;
 89 *       m.save() // success
 90 *     })
 91 *
 92 * @param {Number} maximum number
 93 * @return {SchemaType} this
 94 * @api public
 95 */
 96
 97SchemaNumber.prototype.max = function (value) {
 98  if (this.maxValidator) {
 99    this.validators = this.validators.filter(function(v){
100      return 'max' != v[1];
101    });
102  }
103
104  if (value != null) {
105    this.validators.push([this.maxValidator = function(v){
106      return v === null || v <= value;
107    }, 'max']);
108  }
109
110  return this;
111};
112
113/**
114 * Casts to number
115 *
116 * @param {Object} value value to cast
117 * @param {Document} doc document that triggers the casting
118 * @param {Boolean} init
119 * @api private
120 */
121
122SchemaNumber.prototype.cast = function (value, doc, init) {
123  if (SchemaType._isRef(this, value, doc, init)) {
124    // wait! we may need to cast this to a document
125
126    if (null == value) {
127      return value;
128    }
129
130    // lazy load
131    Document || (Document = require('./../document'));
132
133    if (value instanceof Document) {
134      value.$__.wasPopulated = true;
135      return value;
136    }
137
138    // setting a populated path
139    if ('number' == typeof value) {
140      return value;
141    } else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
142      throw new CastError('number', value, this.path);
143    }
144
145    // Handle the case where user directly sets a populated
146    // path to a plain object; cast to the Model used in
147    // the population query.
148    var path = doc.$__fullPath(this.path);
149    var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
150    var pop = owner.populated(path, true);
151    var ret = new pop.options.model(value);
152    ret.$__.wasPopulated = true;
153    return ret;
154  }
155
156  var val = value && value._id
157    ? value._id // documents
158    : value;
159
160  if (!isNaN(val)){
161    if (null === val) return val;
162    if ('' === val) return null;
163    if ('string' == typeof val) val = Number(val);
164    if (val instanceof Number) return val
165    if ('number' == typeof val) return val;
166    if (val.toString && !Array.isArray(val) &&
167        val.toString() == Number(val)) {
168      return new Number(val)
169    }
170  }
171
172  throw new CastError('number', value, this.path);
173};
174
175/*!
176 * ignore
177 */
178
179function handleSingle (val) {
180  return this.cast(val)
181}
182
183function handleArray (val) {
184  var self = this;
185  return val.map(function (m) {
186    return self.cast(m)
187  });
188}
189
190SchemaNumber.prototype.$conditionalHandlers = {
191    '$lt' : handleSingle
192  , '$lte': handleSingle
193  , '$gt' : handleSingle
194  , '$gte': handleSingle
195  , '$ne' : handleSingle
196  , '$in' : handleArray
197  , '$nin': handleArray
198  , '$mod': handleArray
199  , '$all': handleArray
200};
201
202/**
203 * Casts contents for queries.
204 *
205 * @param {String} $conditional
206 * @param {any} [value]
207 * @api private
208 */
209
210SchemaNumber.prototype.castForQuery = function ($conditional, val) {
211  var handler;
212  if (arguments.length === 2) {
213    handler = this.$conditionalHandlers[$conditional];
214    if (!handler)
215      throw new Error("Can't use " + $conditional + " with Number.");
216    return handler.call(this, val);
217  } else {
218    val = this.cast($conditional);
219    return val == null ? val : val
220  }
221};
222
223/*!
224 * Module exports.
225 */
226
227module.exports = SchemaNumber;