Honour allowExtendedOperators in "DAO.find"

Modify the coercion of filter.where to hounour "allowExtendedOperators"
and don't coerce property values of type object (extended operators).
This commit is contained in:
Miroslav Bajtoš 2016-12-05 16:04:54 +01:00
parent 80d2264bc9
commit 779cf6a370
2 changed files with 70 additions and 2 deletions

View File

@ -1658,13 +1658,19 @@ DataAccessObject._coerce = function(where) {
}
} else {
if (val != null) {
const dsSettings = this.getDataSource().settings;
const allowExtendedOperators = dsSettings.allowExtendedOperators;
if (operator === null && val instanceof RegExp) {
// Normalize {name: /A/} to {name: {regexp: /A/}}
operator = 'regexp';
} else if (operator === 'regexp' && val instanceof RegExp) {
// Do not coerce regex literals/objects
} else if (!((operator === 'like' || operator === 'nlike' ||
operator === 'ilike' || operator === 'nilike') && val instanceof RegExp)) {
} else if ((operator === 'like' || operator === 'nlike' ||
operator === 'ilike' || operator === 'nilike') && val instanceof RegExp) {
// Do not coerce RegExp operator value
} else if (allowExtendedOperators && typeof val === 'object') {
// Do not coerce object values when extended operators are allowed
} else {
val = DataType(val);
}
}

View File

@ -0,0 +1,62 @@
// Copyright IBM Corp. 2015,2016. All Rights Reserved.
// Node module: loopback-datasource-juggler
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const DataSource = require('..').DataSource;
const should = require('should');
describe('Model.settings.allowExtendedOperators', () => {
context('DAO.find()', () => {
it('converts extended operators to string value by default', () => {
const TestModel = createTestModel();
return TestModel.find(extendedQuery()).then((results) => {
should(results[0].value).eql('[object Object]');
});
});
it('preserves extended operators wit allowExtendedOperators set', () => {
const TestModel = createTestModel({allowExtendedOperators: true});
return TestModel.find(extendedQuery()).then((results) => {
should(results[0].value).eql({$exists: true});
});
});
function extendedQuery() {
// datasource modifies the query,
// we have to build a new object for each test
return {where: {value: {$exists: true}}};
}
});
function createTestModel(connectorSettings) {
const ds = createTestDataSource(connectorSettings);
return ds.createModel('TestModel', {value: String});
}
function createTestDataSource(connectorSettings) {
connectorSettings = connectorSettings || {};
connectorSettings.connector = {
initialize: (dataSource, cb) => {
dataSource.connector = new TestConnector(dataSource);
},
};
return new DataSource(connectorSettings);
}
class TestConnector {
constructor(dataSource) {
}
all(model, filter, options, callback) {
// return the raw "value" query
var instanceFound = {
value: filter.where.value,
};
callback(null, [instanceFound]);
}
}
});