Recursively coerce nested properties in dao

This commit is contained in:
nVitius 2017-04-28 15:57:42 -07:00
parent 6d017c1e34
commit 8ebccb65d1
2 changed files with 63 additions and 24 deletions

View File

@ -1565,12 +1565,14 @@ function coerceArray(val) {
* @returns {Object} The coerced where clause
* @private
*/
DataAccessObject._coerce = function(where) {
DataAccessObject._coerce = function(where, props) {
var self = this;
if (!where) {
return where;
}
props = props || self.definition.properties;
var err;
if (typeof where !== 'object' || Array.isArray(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;
}
var props = self.definition.properties;
for (var p in where) {
// Handle logical operators
if (p === 'and' || p === 'or' || p === 'nor') {
@ -1597,6 +1598,22 @@ DataAccessObject._coerce = function(where) {
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;
if (!DataType) {
continue;

View File

@ -1374,6 +1374,11 @@ describe('DataAccessObject', function() {
age: Number,
vip: Boolean,
date: Date,
sub: {
date: Date,
bool: Boolean,
number: Number,
},
location: 'GeoPoint',
scores: [Number],
});
@ -1433,6 +1438,27 @@ describe('DataAccessObject', function() {
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() {
where = model._coerce({vip: 'true'});
assert.deepEqual(where, {vip: true});
@ -1518,8 +1544,7 @@ describe('DataAccessObject', function() {
INVALID_CLAUSES.forEach(function(where) {
var whereStr = JSON.stringify(where);
it('throws an error on malformed array-like object ' + whereStr,
function() {
it('throws an error on malformed array-like object ' + whereStr, function() {
assert.throws(
function() { model._coerce(where); },
/property has invalid clause/);
@ -1694,21 +1719,18 @@ describe('DataAccessObject', function() {
assert.deepEqual(where, {date: undefined});
});
it('does not coerce to a number for a simple value that produces NaN',
function() {
it('does not coerce to a number for a simple value that produces NaN', function() {
where = model._coerce({age: 'xyz'});
assert.deepEqual(where, {age: 'xyz'});
});
it('does not coerce to a number for a simple value in an array that produces NaN',
function() {
it('does not coerce to a number for a simple value in an array that produces NaN', function() {
where = model._coerce({age: {inq: ['xyz', '12']}});
assert.deepEqual(where, {age: {inq: ['xyz', 12]}});
});
// settings
it('gets settings in priority',
function() {
it('gets settings in priority', function() {
ds.settings.test = 'test';
assert.equal(model._getSetting('test'), ds.settings.test, 'Should get datasource setting');
ds.settings.test = undefined;