Merge pull request #725 from jrschumacher/feature-normalize-undefined-in-query

Ability to define normalization of undefined query

Close #725
This commit is contained in:
Miroslav Bajtoš 2015-10-07 09:27:26 -07:00
commit 98fb3c6832
4 changed files with 74 additions and 4 deletions

View File

@ -939,6 +939,27 @@ DataAccessObject.all = function () {
return DataAccessObject.find.apply(this, arguments);
};
/**
* Get settings via hiarchical determiniation
*
* @param {String} key The setting key
*/
DataAccessObject._getSetting = function(key) {
// Check for settings in model
var m = this.definition;
if(m && m.settings && m.settings[key]) {
return m.settings[key]
}
// Check for settings in connector
var ds = this.getDataSource();
if(ds && ds.settings && ds.settings[key]) {
return ds.settings[key];
}
return;
};
var operators = {
gt: '>',
gte: '>=',
@ -1037,7 +1058,9 @@ DataAccessObject._normalize = function (filter) {
Object.keys(this.definition.properties), this.settings.strict);
}
filter = removeUndefined(filter);
var handleUndefined = this._getSetting('normalizeUndefinedInQuery');
// alter configuration of how removeUndefined handles undefined values
filter = removeUndefined(filter, handleUndefined);
this._coerce(filter.where);
return filter;
};

View File

@ -294,9 +294,10 @@ function selectFields(fields) {
/**
* Remove undefined values from the queury object
* @param query
* @param handleUndefined {String} either "nullify", "throw" or "ignore" (default: "ignore")
* @returns {exports.map|*}
*/
function removeUndefined(query) {
function removeUndefined(query, handleUndefined) {
if (typeof query !== 'object' || query === null) {
return query;
}
@ -304,7 +305,17 @@ function removeUndefined(query) {
// as traverse doesn't transform the ObjectId correctly
return traverse(query).forEach(function (x) {
if (x === undefined) {
this.remove();
switch (handleUndefined) {
case 'nullify':
this.update(null);
break;
case 'throw':
throw new Error('Unexpected `undefined` in query');
break;
case 'ignore':
default:
this.remove();
}
}
if (!Array.isArray(x) && (typeof x === 'object' && x !== null

View File

@ -1487,6 +1487,22 @@ describe('DataAccessObject', function () {
assert.deepEqual(filter, {limit: 100, offset: 5, skip: 5});
});
it('should apply settings for handling undefined', function () {
filter = model._normalize({filter: { x: undefined }});
assert.deepEqual(filter, {filter: {}});
ds.settings.normalizeUndefinedInQuery = 'ignore';
filter = model._normalize({filter: { x: undefined }});
assert.deepEqual(filter, {filter: {}}, 'Should ignore undefined');
ds.settings.normalizeUndefinedInQuery = 'nullify';
filter = model._normalize({filter: { x: undefined }});
assert.deepEqual(filter, {filter: { x: null }}, 'Should nullify undefined');
ds.settings.normalizeUndefinedInQuery = 'throw';
(function(){ model._normalize({filter: { x: undefined }}) }).should.throw(/`undefined` in query/);
});
it('should skip GeoPoint', function () {
where = model._coerce({location: {near: {lng: 10, lat: 20}, maxDistance: 20}});
assert.deepEqual(where, {location: {near: {lng: 10, lat: 20}, maxDistance: 20}});
@ -1514,6 +1530,20 @@ describe('DataAccessObject', function () {
assert.deepEqual(where, {age: {inq: ['xyz', 12]}});
});
// settings
it('should get settings in priority',
function () {
ds.settings.test = 'test';
assert.equal(model._getSetting('test'), ds.settings.test, 'Should get datasource setting');
ds.settings.test = undefined;
model.settings.test = 'test';
assert.equal(model._getSetting('test'), model.settings.test, 'Should get model settings');
ds.settings.test = 'willNotGet';
assert.notEqual(model._getSetting('test'), ds.settings.test, 'Should not get datasource setting');
});
});
describe('Load models from json', function () {
@ -1796,4 +1826,3 @@ describe('ModelBuilder options.models', function () {
});
});

View File

@ -66,6 +66,13 @@ describe('util.removeUndefined', function () {
var q4 = {where: {x: 1, y: date}};
should.deepEqual(removeUndefined(q4), {where: {x: 1, y: date}});
// test handling of undefined
var q5 = {where: {x: 1, y: undefined}};
should.deepEqual(removeUndefined(q5, 'nullify'), {where: {x: 1, y: null}});
var q6 = {where: {x: 1, y: undefined}};
(function(){ removeUndefined(q6, 'throw') }).should.throw(/`undefined` in query/);
});
});