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:
commit
98fb3c6832
25
lib/dao.js
25
lib/dao.js
|
@ -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;
|
||||
};
|
||||
|
|
15
lib/utils.js
15
lib/utils.js
|
@ -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
|
||||
|
|
|
@ -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 () {
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -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/);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue