From f6e1df87be599eecfe5238e1047458d10f7985a9 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Fri, 9 Nov 2018 09:33:05 -0800 Subject: [PATCH] Allow flags to be passed via options --- lib/dao.js | 45 ++++++++++++++--------------------- test/model-definition.test.js | 24 +++++++++++++++++++ 2 files changed, 42 insertions(+), 27 deletions(-) diff --git a/lib/dao.js b/lib/dao.js index da9a6546..9a63f84e 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -236,22 +236,7 @@ DataAccessObject.getConnector = function() { * @returns {Boolean} Returns `true` if allowExtendedOperators is enabled, else `false`. */ DataAccessObject._allowExtendedOperators = function(options) { - options = options || {}; - - var Model = this; - var dsSettings = this.getDataSource().settings; - var allowExtendedOperators = dsSettings.allowExtendedOperators; - // options settings enable allowExtendedOperators per request (for example if - // enable allowExtendedOperators only server side); - // model settings enable allowExtendedOperators only for specific model. - // dataSource settings enable allowExtendedOperators globally (all models); - // options -> model -> dataSource (connector) - if (options.hasOwnProperty('allowExtendedOperators')) { - allowExtendedOperators = options.allowExtendedOperators === true; - } else if (Model.settings && Model.settings.hasOwnProperty('allowExtendedOperators')) { - allowExtendedOperators = Model.settings.allowExtendedOperators === true; - } - return allowExtendedOperators; + return this._getSetting('allowExtendedOperators', options) === true; }; // Empty callback function @@ -803,7 +788,7 @@ DataAccessObject.upsertWithWhere = function(where, data, options, cb) { function callConnector() { try { - ctx.where = Model._sanitizeQuery(ctx.where); + ctx.where = Model._sanitizeQuery(ctx.where, options); ctx.where = Model._coerce(ctx.where, options); update = Model._sanitizeData(update); update = Model._coerce(update, options); @@ -1454,14 +1439,20 @@ DataAccessObject.all = function() { /** * Get settings via hierarchical determination + * - method level options + * - model level settings + * - datasource level settings * * @param {String} key The setting key */ -DataAccessObject._getSetting = function(key) { +DataAccessObject._getSetting = function(key, options) { + // Check method level options + var val = options && options[key]; + if (val !== undefined) return val; // Check for settings in model var m = this.definition; if (m && m.settings) { - var val = m.settings[key]; + val = m.settings[key]; if (val !== undefined) { return m.settings[key]; } @@ -1580,7 +1571,7 @@ DataAccessObject._normalize = function(filter, options) { Object.keys(this.definition.properties), this.settings.strict); } - filter = this._sanitizeQuery(filter); + filter = this._sanitizeQuery(filter, options); this._coerce(filter.where, options); return filter; }; @@ -1676,16 +1667,16 @@ DataAccessObject._sanitizeQuery = function(query, options) { options = options || {}; // Get settings to normalize `undefined` values - var normalizeUndefinedInQuery = this._getSetting('normalizeUndefinedInQuery'); + var normalizeUndefinedInQuery = this._getSetting('normalizeUndefinedInQuery', options); // Get setting to prohibit hidden/protected properties in query - var prohibitHiddenPropertiesInQuery = this._getSetting('prohibitHiddenPropertiesInQuery'); + var prohibitHiddenPropertiesInQuery = this._getSetting('prohibitHiddenPropertiesInQuery', options); if (prohibitHiddenPropertiesInQuery == null) { // By default, hidden properties are prohibited in query prohibitHiddenPropertiesInQuery = true; } // See https://github.com/strongloop/loopback-datasource-juggler/issues/1651 - var maxDepthOfQuery = (+this._getSetting('maxDepthOfQuery')) || 12; + var maxDepthOfQuery = (+this._getSetting('maxDepthOfQuery', options)) || 12; var prohibitedKeys = []; // Check violation of keys @@ -1706,7 +1697,7 @@ DataAccessObject._sanitizeQuery = function(query, options) { DataAccessObject._sanitizeData = function(data, options) { options = options || {}; // See https://github.com/strongloop/loopback-datasource-juggler/issues/1651 - var maxDepthOfQuery = (+this._getSetting('maxDepthOfQuery')) || 12; + var maxDepthOfQuery = (+this._getSetting('maxDepthOfQuery', options)) || 12; return sanitizeQueryOrData(data, Object.assign({ maxDepth: maxDepthOfQuery, @@ -2363,7 +2354,7 @@ DataAccessObject.destroyAll = function destroyAll(where, options, cb) { try { // Support an optional where object // alter configuration of how sanitizeQuery handles undefined values - where = Model._sanitizeQuery(where); + where = Model._sanitizeQuery(where, options); where = Model._coerce(where, options); } catch (err) { return process.nextTick(function() { @@ -2517,7 +2508,7 @@ DataAccessObject.count = function(where, options, cb) { try { // alter configuration of how sanitizeQuery handles undefined values - where = Model._sanitizeQuery(where); + where = Model._sanitizeQuery(where, options); where = this._coerce(where, options); } catch (err) { process.nextTick(function() { @@ -2810,7 +2801,7 @@ DataAccessObject.updateAll = function(where, data, options, cb) { function doUpdate(where, data) { try { // alter configuration of how sanitizeQuery handles undefined values - where = Model._sanitizeQuery(where); + where = Model._sanitizeQuery(where, options); where = Model._coerce(where, options); data = Model._sanitizeData(data); data = Model._coerce(data, options); diff --git a/test/model-definition.test.js b/test/model-definition.test.js index 053f6067..09d1e1a1 100644 --- a/test/model-definition.test.js +++ b/test/model-definition.test.js @@ -285,6 +285,19 @@ describe('ModelDefinition class', function() { }); }); + it('should honor maxDepthOfQuery in options', function(done) { + var MyModel = memory.createModel('my-model', {}, { + maxDepthOfQuery: 5, + }); + + var filter = givenComplexFilter(); + + MyModel.find(filter, {maxDepthOfQuery: 20}, function(err) { + should.not.exist(err); + done(); + }); + }); + function givenComplexFilter() { var filter = {where: {and: [{and: [{and: [{and: [{and: [{and: [{and: [{and: [{and: [{x: 1}]}]}]}]}]}]}]}]}]}}; @@ -406,6 +419,17 @@ describe('ModelDefinition class', function() { children[0].secret.should.equal('guess'); }); }); + + it('should be allowed if prohibitHiddenPropertiesInQuery is `false` in options', function() { + return Child.find({ + where: {secret: 'guess'}, + }, { + prohibitHiddenPropertiesInQuery: false, + }).then(function(children) { + children.length.should.equal(1); + children[0].secret.should.equal('guess'); + }); + }); }); describe('with hidden object', function() {