waterline
Advanced tools
Comparing version 0.9.11 to 0.9.12
@@ -91,2 +91,8 @@ /** | ||
// Check if the adapter overrides the autoPK setting | ||
var autoPK = Object.getPrototypeOf(this).hasOwnProperty('autoPK'); | ||
if(adapterInfo.adapter.defaults && adapterInfo.adapter.defaults.hasOwnProperty('autoPK')) { | ||
if(!autoPK) this.autoPK = adapterInfo.adapter.defaults.autoPK; | ||
} | ||
// Normalize Adapter Definition with actual methods | ||
@@ -93,0 +99,0 @@ this.adapter = adapterInfo.adapter; |
@@ -56,3 +56,3 @@ /** | ||
for(var prop in attrsVal) { | ||
if(/^(defaultsTo|primaryKey|autoIncrement|unique|index|columnName)$/.test(prop)) continue; | ||
if(/^(defaultsTo|primaryKey|autoIncrement|unique|index|columnName|size)$/.test(prop)) continue; | ||
@@ -113,3 +113,3 @@ // use the Anchor `in` method for enums | ||
// If Boolean and required manually check | ||
if(curValidation.required && curValidation.type === 'boolean') { | ||
if(curValidation.required && curValidation.type === 'boolean' && (typeof value !== 'undefined' && value !== null)) { | ||
if(value.toString() == 'true' || value.toString() == 'false') return cb(); | ||
@@ -116,0 +116,0 @@ } |
@@ -56,3 +56,5 @@ /** | ||
if(record[key] === undefined && self.attributes[key].hasOwnProperty('defaultsTo')) { | ||
record[key] = _.clone(self.attributes[key].defaultsTo); | ||
var defaultObj = self.attributes[key].defaultsTo; | ||
var defaultValue = typeof defaultObj === 'function' ? defaultObj(record) : defaultObj; | ||
record[key] = _.clone(defaultValue); | ||
} | ||
@@ -214,3 +216,5 @@ } | ||
if(record[key] === undefined && self.attributes[key].hasOwnProperty('defaultsTo')) { | ||
record[key] = _.clone(self.attributes[key].defaultsTo); | ||
var defaultObj = self.attributes[key].defaultsTo; | ||
var defaultValue = typeof defaultObj === 'function' ? defaultObj(record) : defaultObj; | ||
record[key] = _.clone(defaultValue); | ||
} | ||
@@ -217,0 +221,0 @@ } |
@@ -83,6 +83,7 @@ /** | ||
Deferred.prototype.paginate = function(options) { | ||
if(options == undefined) var options = {page: 0, limit: 0}; | ||
var defaultLimit = 10; | ||
if(options == undefined) var options = {page: 0, limit: defaultLimit}; | ||
var page = options.page || 0, | ||
limit = options.limit || 0, | ||
limit = options.limit || defaultLimit, | ||
skip = 0; | ||
@@ -89,0 +90,0 @@ |
@@ -56,3 +56,5 @@ /** | ||
if(values[key] === undefined && this.attributes[key].hasOwnProperty('defaultsTo')) { | ||
values[key] = _.clone(this.attributes[key].defaultsTo); | ||
var defaultObj = this.attributes[key].defaultsTo; | ||
var defaultValue = typeof defaultObj === 'function' ? defaultObj(values) : defaultObj; | ||
values[key] = _.clone(defaultValue); | ||
} | ||
@@ -59,0 +61,0 @@ } |
{ | ||
"name": "waterline", | ||
"description": "An ORM for Node.js and the Sails framework", | ||
"version": "0.9.11", | ||
"version": "0.9.12", | ||
"contributors": [ | ||
@@ -22,3 +22,3 @@ { | ||
"async": "~0.2.9", | ||
"anchor": "~0.9.7", | ||
"anchor": "~0.9.12", | ||
"q": "~0.9.7" | ||
@@ -25,0 +25,0 @@ }, |
@@ -83,3 +83,3 @@ ![image_squidhome@2x.png](http://i.imgur.com/7rMxw.png) | ||
- `tableName` Define a custom table name to store the models | ||
- `adapters` the name of the adapter you would like to use for this collection | ||
- `adapter` the name of the adapter you would like to use for this collection | ||
- `schema` Set schema true/false to only allow fields defined in `attributes` to be saved. Only for schemaless adapters. | ||
@@ -217,3 +217,3 @@ - `attributes` A hash of attributes to be defined for a model | ||
Each result that gets returned from a Waterline query will be an instance of [Model](https://github.com/balderdashy/waterline/blob/master/lib/waterline/model/index.js). This will add in any instance methods defined in your collection along with some CRUD helper methods. View [Core Instance Methods](https://github.com/balderdashy/waterline/blob/master/lib/waterline/core/instanceMethods.js) to see how the methods are implemented. | ||
Each result that gets returned from a Waterline query will be an instance of [Model](https://github.com/balderdashy/waterline/blob/master/lib/waterline/model/index.js). This will add in any instance methods defined in your collection along with some CRUD helper methods. View the [Core Instance Methods](https://github.com/balderdashy/waterline/blob/master/lib/waterline/model/index.js) to see how they are implemented. | ||
@@ -329,3 +329,43 @@ Default CRUD instance methods: | ||
## Pagination | ||
In addition to the other find methods, there are a few helper methods to take care of pagination: | ||
- skip | ||
- limit | ||
- paginate | ||
Skip takes an integer and can be used to skip records: | ||
``` javascript | ||
User.find().skip(20); | ||
``` | ||
Limit takes an integer and limits the amount of records returned: | ||
``` javascript | ||
User.find().limit(10); | ||
``` | ||
And put together they create the ability to paginate through records as you would pages. For example, if I wanted 'page 2' of a given record set, and I only want to see 10 records at a time, I know that I need to ```skip(10)``` and ```limit(10)``` like so: | ||
``` javascript | ||
User.find().skip(10).limit(10); | ||
``` | ||
But, while we are thinking in terms of pagination, or pages, it might be easier to use the final helper - paginate: | ||
``` javascript | ||
User.find().paginate({page: 2, limit: 10}); | ||
``` | ||
Paginate has several options: | ||
- ```paginate()``` defaults options to ```{page: 0, limit: 10}``` | ||
- ```paginate({page: 2})``` uses ```{page: 2, limit: 10}``` as the options | ||
- ```paginate({limit: 20})``` uses ```{page: 0, limit: 20}``` as the options | ||
- ```paginate({page: 1, limit: 20})``` uses ```{page: 1, limit: 20}``` as the options | ||
It returns a deferred object so that you can continue to chain your helpers. | ||
## Sorting | ||
@@ -351,2 +391,4 @@ | ||
Validation rules may be defined as simple values or functions (both sync and async) that return the value to test against. | ||
```javascript | ||
@@ -374,8 +416,41 @@ var User = Waterline.Collection.extend({ | ||
after: '12/12/2001' | ||
}, | ||
website: { | ||
type: 'string', | ||
// Validation rule may be defined as a function. Here, an async function is mimicked. | ||
contains: function(cb) { | ||
setTimeout(function() { | ||
cb('http://'); | ||
}, 1); | ||
} | ||
} | ||
} | ||
}); | ||
var Event = Waterline.Collection.extend({ | ||
attributes: { | ||
startDate: { | ||
type: 'date', | ||
// Validation rule functions allow you to validate values against other attributes | ||
before: function() { | ||
return this.endDate; | ||
} | ||
}, | ||
endDate: { | ||
type: 'date', | ||
after: function() { | ||
return this.startDate; | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
## Custom Types | ||
You can define your own types and their validation with the `types` hash | ||
You can define your own types and their validation with the `types` hash. It's possible to access and compare values to other attributes. | ||
@@ -387,3 +462,7 @@ ```javascript | ||
return latlng.x && latlng.y | ||
} | ||
}, | ||
password: function(password) { | ||
return password === this.passwordConfirmation; | ||
}); | ||
}, | ||
@@ -403,2 +482,11 @@ | ||
point: true | ||
}, | ||
password: { | ||
type: 'string', | ||
password: true | ||
}, | ||
passwordConfirmation: { | ||
type: 'string' | ||
} | ||
@@ -405,0 +493,0 @@ } |
@@ -18,2 +18,14 @@ var Collection = require('../../../lib/waterline/collection'), | ||
attributes: { | ||
first:{ | ||
type: 'string', | ||
defaultsTo: 'Foo' | ||
}, | ||
second: { | ||
type: 'string', | ||
defaultsTo: 'Bar' | ||
}, | ||
full: { | ||
type: 'string', | ||
defaultsTo: function(self){ return self.first + " " + self.second} | ||
}, | ||
name: { | ||
@@ -43,2 +55,9 @@ type: 'string', | ||
it('should set default values when function', function(done) { | ||
query.create({}, function(err, status) { | ||
assert(status.full === 'Foo Bar'); | ||
done(); | ||
}); | ||
}); | ||
it('should add timestamps', function(done) { | ||
@@ -45,0 +64,0 @@ query.create({}, function(err, status) { |
@@ -18,2 +18,14 @@ var Collection = require('../../../lib/waterline/collection'), | ||
attributes: { | ||
first:{ | ||
type: 'string', | ||
defaultsTo: 'Foo' | ||
}, | ||
second: { | ||
type: 'string', | ||
defaultsTo: 'Bar' | ||
}, | ||
full: { | ||
type: 'string', | ||
defaultsTo: function(self){ return self.first + " " + self.second} | ||
}, | ||
name: { | ||
@@ -64,2 +76,11 @@ type: 'string', | ||
it('should add default values to each record when function', function(done) { | ||
query.createEach([{},{}], function(err, values) { | ||
assert(Array.isArray(values)); | ||
assert(values[0].full === 'Foo Bar'); | ||
assert(values[1].full === 'Foo Bar'); | ||
done(); | ||
}); | ||
}); | ||
it('should clone default values for each record', function(done) { | ||
@@ -66,0 +87,0 @@ query.createEach([{},{}], function(err, values) { |
@@ -77,3 +77,3 @@ var Collection = require('../../../lib/waterline/collection'), | ||
describe('.paginate()', function() { | ||
it('should not set skip and limit by default', function(done) { | ||
it('should skip to 0 and limit to 10 by default', function(done) { | ||
query.find() | ||
@@ -85,4 +85,4 @@ .paginate() | ||
assert(results[0].skip == undefined); | ||
assert(results[0].limit == undefined); | ||
assert(results[0].skip === 0); | ||
assert(results[0].limit === 10); | ||
@@ -93,7 +93,7 @@ done(); | ||
it('should not set skip from page 0', function(done) { | ||
it('should set skip to 0 from page 0', function(done) { | ||
query.find() | ||
.paginate({page: 1}) | ||
.exec(function(err, results) { | ||
assert(results[0].skip == undefined); | ||
assert(results[0].skip === 0); | ||
@@ -104,7 +104,7 @@ done(); | ||
it('should not set skip from page 1', function(done) { | ||
it('should set skip to 0 from page 1', function(done) { | ||
query.find() | ||
.paginate({page: 1}) | ||
.exec(function(err, results) { | ||
assert(results[0].skip == undefined); | ||
assert(results[0].skip === 0); | ||
@@ -115,7 +115,7 @@ done(); | ||
it('should set skip to 1', function(done) { | ||
it('should set skip to 10', function(done) { | ||
query.find() | ||
.paginate({page: 2}) | ||
.exec(function(err, results) { | ||
assert(results[0].skip == 1); | ||
assert(results[0].skip === 10); | ||
@@ -130,3 +130,3 @@ done(); | ||
.exec(function(err, results) { | ||
assert(results[0].limit == 1); | ||
assert(results[0].limit === 1); | ||
@@ -141,4 +141,4 @@ done(); | ||
.exec(function(err, results) { | ||
assert(results[0].skip == 10); | ||
assert(results[0].limit == 10); | ||
assert(results[0].skip === 10); | ||
assert(results[0].limit === 10); | ||
@@ -153,4 +153,4 @@ done(); | ||
.exec(function(err, results) { | ||
assert(results[0].skip == 20); | ||
assert(results[0].limit == 10); | ||
assert(results[0].skip === 20); | ||
assert(results[0].limit === 10); | ||
@@ -157,0 +157,0 @@ done(); |
@@ -16,2 +16,6 @@ var Validator = require('../../../lib/waterline/core/validations'), | ||
}, | ||
employed: { | ||
type: 'boolean', | ||
required: true | ||
}, | ||
age: { type: 'integer' } | ||
@@ -24,4 +28,4 @@ }; | ||
it('should error if no value is set', function(done) { | ||
validator.validate({ name: ' ', age: 27 }, function(errors) { | ||
it('should error if no value is set for required string field', function(done) { | ||
validator.validate({ name: ' ', employed: true, age: 27 }, function(errors) { | ||
assert(errors.ValidationError); | ||
@@ -33,5 +37,15 @@ assert(errors.ValidationError.name); | ||
}); | ||
it('should error if no value is set for required boolean field', function(done) { | ||
validator.validate({ name: 'Frederick P. Frederickson', age: 27 }, function(errors) { | ||
assert(errors.ValidationError); | ||
assert(errors.ValidationError.employed); | ||
assert(errors.ValidationError.employed[0].rule === 'boolean'); | ||
assert(errors.ValidationError.employed[1].rule === 'required'); | ||
done(); | ||
}); | ||
}); | ||
it('should NOT error if value is set', function(done) { | ||
validator.validate({ name: 'Foo Bar', age: 27 }, function(errors) { | ||
it('should NOT error if all required values are set', function(done) { | ||
validator.validate({ name: 'Foo Bar', employed: true, age: 27 }, function(errors) { | ||
assert(!errors); | ||
@@ -38,0 +52,0 @@ done(); |
Sorry, the diff of this file is not supported yet
291486
8720
544
Updatedanchor@~0.9.12