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;