Recursively coerce nested properties in dao
This commit is contained in:
parent
6d017c1e34
commit
8ebccb65d1
21
lib/dao.js
21
lib/dao.js
|
@ -1565,12 +1565,14 @@ function coerceArray(val) {
|
||||||
* @returns {Object} The coerced where clause
|
* @returns {Object} The coerced where clause
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
DataAccessObject._coerce = function(where) {
|
DataAccessObject._coerce = function(where, props) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!where) {
|
if (!where) {
|
||||||
return where;
|
return where;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
props = props || self.definition.properties;
|
||||||
|
|
||||||
var err;
|
var err;
|
||||||
if (typeof where !== 'object' || Array.isArray(where)) {
|
if (typeof where !== 'object' || Array.isArray(where)) {
|
||||||
err = new Error(g.f('The where clause %j is not an {{object}}', where));
|
err = new Error(g.f('The where clause %j is not an {{object}}', where));
|
||||||
|
@ -1578,7 +1580,6 @@ DataAccessObject._coerce = function(where) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
var props = self.definition.properties;
|
|
||||||
for (var p in where) {
|
for (var p in where) {
|
||||||
// Handle logical operators
|
// Handle logical operators
|
||||||
if (p === 'and' || p === 'or' || p === 'nor') {
|
if (p === 'and' || p === 'or' || p === 'nor') {
|
||||||
|
@ -1597,6 +1598,22 @@ DataAccessObject._coerce = function(where) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p.match(/\./)) {
|
||||||
|
var model = p.split('.')[0];
|
||||||
|
var prop = p.split('.').slice(1);
|
||||||
|
|
||||||
|
if (props[model]) {
|
||||||
|
var clause = {};
|
||||||
|
clause[prop] = where[p];
|
||||||
|
where[p] = Array.isArray(props[model].type) ?
|
||||||
|
self._coerce(clause, props[model].type[0].definition.properties)[prop] :
|
||||||
|
self._coerce(clause, props[model].type.definition.properties)[prop];
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var DataType = props[p] && props[p].type;
|
var DataType = props[p] && props[p].type;
|
||||||
if (!DataType) {
|
if (!DataType) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1374,6 +1374,11 @@ describe('DataAccessObject', function() {
|
||||||
age: Number,
|
age: Number,
|
||||||
vip: Boolean,
|
vip: Boolean,
|
||||||
date: Date,
|
date: Date,
|
||||||
|
sub: {
|
||||||
|
date: Date,
|
||||||
|
bool: Boolean,
|
||||||
|
number: Number,
|
||||||
|
},
|
||||||
location: 'GeoPoint',
|
location: 'GeoPoint',
|
||||||
scores: [Number],
|
scores: [Number],
|
||||||
});
|
});
|
||||||
|
@ -1433,6 +1438,27 @@ describe('DataAccessObject', function() {
|
||||||
assert.deepEqual(where, {date: d});
|
assert.deepEqual(where, {date: d});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('coerces where clause for date types in nested properties', function() {
|
||||||
|
var d = new Date();
|
||||||
|
where = model._coerce({'sub.date': d});
|
||||||
|
assert.deepEqual(where, {'sub.date': d});
|
||||||
|
|
||||||
|
where = model._coerce({'sub.date': d.toISOString()});
|
||||||
|
assert.deepEqual(where, {'sub.date': d});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('coerces where clause for Boolean types in nested properties', function() {
|
||||||
|
var bool = 'true';
|
||||||
|
where = model._coerce({'sub.bool': bool});
|
||||||
|
assert.strictEqual(where['sub.bool'], true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('coerces where clause for Number type in nested properties', function() {
|
||||||
|
var number = '123';
|
||||||
|
where = model._coerce({'sub.number': number});
|
||||||
|
assert.strictEqual(where['sub.number'], 123);
|
||||||
|
});
|
||||||
|
|
||||||
it('coerces where clause for boolean types', function() {
|
it('coerces where clause for boolean types', function() {
|
||||||
where = model._coerce({vip: 'true'});
|
where = model._coerce({vip: 'true'});
|
||||||
assert.deepEqual(where, {vip: true});
|
assert.deepEqual(where, {vip: true});
|
||||||
|
@ -1518,8 +1544,7 @@ describe('DataAccessObject', function() {
|
||||||
|
|
||||||
INVALID_CLAUSES.forEach(function(where) {
|
INVALID_CLAUSES.forEach(function(where) {
|
||||||
var whereStr = JSON.stringify(where);
|
var whereStr = JSON.stringify(where);
|
||||||
it('throws an error on malformed array-like object ' + whereStr,
|
it('throws an error on malformed array-like object ' + whereStr, function() {
|
||||||
function() {
|
|
||||||
assert.throws(
|
assert.throws(
|
||||||
function() { model._coerce(where); },
|
function() { model._coerce(where); },
|
||||||
/property has invalid clause/);
|
/property has invalid clause/);
|
||||||
|
@ -1694,21 +1719,18 @@ describe('DataAccessObject', function() {
|
||||||
assert.deepEqual(where, {date: undefined});
|
assert.deepEqual(where, {date: undefined});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not coerce to a number for a simple value that produces NaN',
|
it('does not coerce to a number for a simple value that produces NaN', function() {
|
||||||
function() {
|
|
||||||
where = model._coerce({age: 'xyz'});
|
where = model._coerce({age: 'xyz'});
|
||||||
assert.deepEqual(where, {age: 'xyz'});
|
assert.deepEqual(where, {age: 'xyz'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not coerce to a number for a simple value in an array that produces NaN',
|
it('does not coerce to a number for a simple value in an array that produces NaN', function() {
|
||||||
function() {
|
|
||||||
where = model._coerce({age: {inq: ['xyz', '12']}});
|
where = model._coerce({age: {inq: ['xyz', '12']}});
|
||||||
assert.deepEqual(where, {age: {inq: ['xyz', 12]}});
|
assert.deepEqual(where, {age: {inq: ['xyz', 12]}});
|
||||||
});
|
});
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
it('gets settings in priority',
|
it('gets settings in priority', function() {
|
||||||
function() {
|
|
||||||
ds.settings.test = 'test';
|
ds.settings.test = 'test';
|
||||||
assert.equal(model._getSetting('test'), ds.settings.test, 'Should get datasource setting');
|
assert.equal(model._getSetting('test'), ds.settings.test, 'Should get datasource setting');
|
||||||
ds.settings.test = undefined;
|
ds.settings.test = undefined;
|
||||||
|
|
Loading…
Reference in New Issue