不要怂,就是干,撸起袖子干!

Commit 9b204af6 by Muhammad AbdulMoiz Committed by Sushant

try catch block added for formatting parameters process (#6999)

* try catch block added for formatting parameters process

* new line space added before braces

* query function processing wrapped to Promise.try

* processQuery method removed from var

* binding context changed to arrow function

* promise.try chaining added

* extra Promise.resolve removed code refactored

* space added

* test cases for 'query' method updated with respect to new rejection structure instead of throwing error

* it block messages corrected

* return added and code structured

* line space added

* line space added

* code style fixed
1 parent cc09a3c7
...@@ -455,112 +455,107 @@ class Sequelize { ...@@ -455,112 +455,107 @@ class Sequelize {
* *
* @see {@link Model#build} for more information about instance option. * @see {@link Model#build} for more information about instance option.
*/ */
query(sql, options) {
if (arguments.length > 2) {
// TODO: Remove this note in the next major version (4.0)
throw new Error('Sequelize.query was refactored to only use the parameters `sql` and `options`. Please read the changelog about BC.');
}
options = _.assign({}, this.options.query, options);
if (options.instance && !options.model) { query(sql, options) {
options.model = options.instance.constructor; let bindParameters;
}
// Map raw fields to model field names using the `fieldAttributeMap` return Promise.try(() => {
if (options.model && options.mapToModel && !Utils._.isEmpty(options.model.fieldAttributeMap)) { options = _.assign({}, this.options.query, options);
options.fieldMap = options.model.fieldAttributeMap;
}
if (typeof sql === 'object') { if (options.instance && !options.model) {
if (sql.values !== undefined) { options.model = options.instance.constructor;
if (options.replacements !== undefined) { }
throw new Error('Both `sql.values` and `options.replacements` cannot be set at the same time');
}
options.replacements = sql.values; // Map raw fields to model field names using the `fieldAttributeMap`
if (options.model && options.mapToModel && !Utils._.isEmpty(options.model.fieldAttributeMap)) {
options.fieldMap = options.model.fieldAttributeMap;
} }
if (sql.bind !== undefined) { if (typeof sql === 'object') {
if (options.bind !== undefined) { if (sql.values !== undefined) {
throw new Error('Both `sql.bind` and `options.bind` cannot be set at the same time'); if (options.replacements !== undefined) {
throw new Error('Both `sql.values` and `options.replacements` cannot be set at the same time');
}
options.replacements = sql.values;
} }
options.bind = sql.bind; if (sql.bind !== undefined) {
} if (options.bind !== undefined) {
throw new Error('Both `sql.bind` and `options.bind` cannot be set at the same time');
}
options.bind = sql.bind;
}
if (sql.query !== undefined) { if (sql.query !== undefined) {
sql = sql.query; sql = sql.query;
}
} }
}
sql = sql.trim(); sql = sql.trim();
if (!options.instance && !options.model) { if (!options.instance && !options.model) {
options.raw = true; options.raw = true;
} }
if (options.replacements && options.bind) { if (options.replacements && options.bind) {
throw new Error('Both `replacements` and `bind` cannot be set at the same time'); throw new Error('Both `replacements` and `bind` cannot be set at the same time');
}
if (options.replacements) {
if (Array.isArray(options.replacements)) {
sql = Utils.format([sql].concat(options.replacements), this.options.dialect);
} }
else {
sql = Utils.formatNamedParameters(sql, options.replacements, this.options.dialect); if (options.replacements) {
if (Array.isArray(options.replacements)) {
sql = Utils.format([sql].concat(options.replacements), this.options.dialect);
} else {
sql = Utils.formatNamedParameters(sql, options.replacements, this.options.dialect);
}
} }
}
let bindParameters;
if (options.bind) {
const bindSql = this.dialect.Query.formatBindParameters(sql, options.bind, this.options.dialect);
sql = bindSql[0];
bindParameters = bindSql[1];
}
options = _.defaults(options, { if (options.bind) {
logging: this.options.hasOwnProperty('logging') ? this.options.logging : console.log, const bindSql = this.dialect.Query.formatBindParameters(sql, options.bind, this.options.dialect);
searchPath: this.options.hasOwnProperty('searchPath') ? this.options.searchPath : 'DEFAULT' sql = bindSql[0];
}); bindParameters = bindSql[1];
}
if (options.transaction === undefined && Sequelize._cls) { options = _.defaults(options, {
options.transaction = Sequelize._cls.get('transaction'); logging: this.options.hasOwnProperty('logging') ? this.options.logging : console.log,
} searchPath: this.options.hasOwnProperty('searchPath') ? this.options.searchPath : 'DEFAULT'
});
if (!options.type) { if (options.transaction === undefined && Sequelize._cls) {
if (options.model || options.nest || options.plain) { options.transaction = Sequelize._cls.get('transaction');
options.type = QueryTypes.SELECT;
} else {
options.type = QueryTypes.RAW;
} }
}
if (options.transaction && options.transaction.finished) {
const error = new Error(options.transaction.finished+' has been called on this transaction('+options.transaction.id+'), you can no longer use it. (The rejected query is attached as the \'sql\' property of this error)');
error.sql = sql;
return Promise.reject(error);
}
if (this.test._trackRunningQueries) { if (!options.type) {
this.test._runningQueries++; if (options.model || options.nest || options.plain) {
} options.type = QueryTypes.SELECT;
} else {
options.type = QueryTypes.RAW;
}
}
//if dialect doesn't support search_path or dialect option if (options.transaction && options.transaction.finished) {
//to prepend searchPath is not true delete the searchPath option const error = new Error(options.transaction.finished+' has been called on this transaction('+options.transaction.id+'), you can no longer use it. (The rejected query is attached as the \'sql\' property of this error)');
if (!this.dialect.supports.searchPath || !this.options.dialectOptions || !this.options.dialectOptions.prependSearchPath || error.sql = sql;
options.supportsSearchPath === false) { return Promise.reject(error);
delete options.searchPath; }
} else if (!options.searchPath) {
//if user wants to always prepend searchPath (dialectOptions.preprendSearchPath = true)
//then set to DEFAULT if none is provided
options.searchPath = 'DEFAULT';
}
return Promise.resolve( if (this.test._trackRunningQueries) {
options.transaction ? options.transaction.connection : this.connectionManager.getConnection(options) this.test._runningQueries++;
).then(connection => { }
//if dialect doesn't support search_path or dialect option
//to prepend searchPath is not true delete the searchPath option
if (!this.dialect.supports.searchPath || !this.options.dialectOptions || !this.options.dialectOptions.prependSearchPath ||
options.supportsSearchPath === false) {
delete options.searchPath;
} else if (!options.searchPath) {
//if user wants to always prepend searchPath (dialectOptions.preprendSearchPath = true)
//then set to DEFAULT if none is provided
options.searchPath = 'DEFAULT';
}
return options.transaction ? options.transaction.connection : this.connectionManager.getConnection(options);
}).then(connection => {
const query = new this.dialect.Query(connection, this, options); const query = new this.dialect.Query(connection, this, options);
return retry(() => query.run(sql, bindParameters).finally(() => { return retry(() => query.run(sql, bindParameters).finally(() => {
if (!options.transaction) { if (!options.transaction) {
return this.connectionManager.releaseConnection(connection); return this.connectionManager.releaseConnection(connection);
......
...@@ -425,46 +425,34 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() { ...@@ -425,46 +425,34 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
}); });
}); });
it('throw an exception if `values` and `options.replacements` are both passed', function() { it('reject if `values` and `options.replacements` are both passed', function() {
var self = this; return this.sequelize.query({ query: 'select ? as foo, ? as bar', values: [1, 2] }, { raw: true, replacements: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, 'Both `sql.values` and `options.replacements` cannot be set at the same time');
return self.sequelize.query({ query: 'select ? as foo, ? as bar', values: [1, 2] }, { raw: true, replacements: [1, 2] });
}).to.throw(Error, 'Both `sql.values` and `options.replacements` cannot be set at the same time');
}); });
it('throw an exception if `sql.bind` and `options.bind` are both passed', function() { it('reject if `sql.bind` and `options.bind` are both passed', function() {
var self = this; return this.sequelize.query({ query: 'select $1 + ? as foo, $2 + ? as bar', bind: [1, 2] }, { raw: true, bind: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, 'Both `sql.bind` and `options.bind` cannot be set at the same time');
return self.sequelize.query({ query: 'select $1 + ? as foo, $2 + ? as bar', bind: [1, 2] }, { raw: true, bind: [1, 2] });
}).to.throw(Error, 'Both `sql.bind` and `options.bind` cannot be set at the same time');
}); });
it('throw an exception if `options.replacements` and `options.bind` are both passed', function() { it('reject if `options.replacements` and `options.bind` are both passed', function() {
var self = this; return this.sequelize.query('select $1 + ? as foo, $2 + ? as bar', { raw: true, bind: [1, 2], replacements: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, 'Both `replacements` and `bind` cannot be set at the same time');
return self.sequelize.query('select $1 + ? as foo, $2 + ? as bar', { raw: true, bind: [1, 2], replacements: [1, 2] });
}).to.throw(Error, 'Both `replacements` and `bind` cannot be set at the same time');
}); });
it('throw an exception if `sql.bind` and `sql.values` are both passed', function() { it('reject if `sql.bind` and `sql.values` are both passed', function() {
var self = this; return this.sequelize.query({ query: 'select $1 + ? as foo, $2 + ? as bar', bind: [1, 2], values: [1, 2] }, { raw: true })
expect(function() { .should.be.rejectedWith(Error, 'Both `replacements` and `bind` cannot be set at the same time');
return self.sequelize.query({ query: 'select $1 + ? as foo, $2 + ? as bar', bind: [1, 2], values: [1, 2] }, { raw: true });
}).to.throw(Error, 'Both `replacements` and `bind` cannot be set at the same time');
}); });
it('throw an exception if `sql.bind` and `options.replacements`` are both passed', function() { it('reject if `sql.bind` and `options.replacements`` are both passed', function() {
var self = this; return this.sequelize.query({ query: 'select $1 + ? as foo, $2 + ? as bar', bind: [1, 2] }, { raw: true, replacements: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, 'Both `replacements` and `bind` cannot be set at the same time');
return self.sequelize.query({ query: 'select $1 + ? as foo, $2 + ? as bar', bind: [1, 2] }, { raw: true, replacements: [1, 2] });
}).to.throw(Error, 'Both `replacements` and `bind` cannot be set at the same time');
}); });
it('throw an exception if `options.bind` and `sql.replacements` are both passed', function() { it('reject if `options.bind` and `sql.replacements` are both passed', function() {
var self = this; return this.sequelize.query({ query: 'select $1 + ? as foo, $1 _ ? as bar', values: [1, 2] }, { raw: true, bind: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, 'Both `replacements` and `bind` cannot be set at the same time');
return self.sequelize.query({ query: 'select $1 + ? as foo, $1 _ ? as bar', values: [1, 2] }, { raw: true, bind: [1, 2] });
}).to.throw(Error, 'Both `replacements` and `bind` cannot be set at the same time');
}); });
it('properly adds and escapes replacement value', function () { it('properly adds and escapes replacement value', function () {
...@@ -580,39 +568,29 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() { ...@@ -580,39 +568,29 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
.to.eventually.deep.equal([{ foo: 1, bar: null }]); .to.eventually.deep.equal([{ foo: 1, bar: null }]);
}); });
it('throw an exception when key is missing in the passed object', function() { it('reject when key is missing in the passed object', function() {
var self = this; return this.sequelize.query('select :one as foo, :two as bar, :three as baz', { raw: true, replacements: { one: 1, two: 2 }})
expect(function() { .should.be.rejectedWith(Error, /Named parameter ":\w+" has no value in the given object\./g);
self.sequelize.query('select :one as foo, :two as bar, :three as baz', { raw: true, replacements: { one: 1, two: 2 }});
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed number', function() { it('reject with the passed number', function() {
var self = this; return this.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: 2 })
expect(function() { .should.be.rejectedWith(Error, /Named parameter ":\w+" has no value in the given object\./g);
self.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: 2 });
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed empty object', function() { it('reject with the passed empty object', function() {
var self = this; return this.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: {}})
expect(function() { .should.be.rejectedWith(Error, /Named parameter ":\w+" has no value in the given object\./g);
self.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: {}});
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed string', function() { it('reject with the passed string', function() {
var self = this; return this.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: 'foobar'})
expect(function() { .should.be.rejectedWith(Error, /Named parameter ":\w+" has no value in the given object\./g);
self.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: 'foobar'});
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed date', function() { it('reject with the passed date', function() {
var self = this; return this.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: new Date()})
expect(function() { .should.be.rejectedWith(Error, /Named parameter ":\w+" has no value in the given object\./g);
self.sequelize.query('select :one as foo, :two as bar', { raw: true, replacements: new Date()});
}).to.throw(Error, /Named parameter ":\w+" has no value in the given object\./g);
}); });
it('binds token with the passed array', function() { it('binds token with the passed array', function() {
...@@ -689,78 +667,58 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() { ...@@ -689,78 +667,58 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
}); });
} }
it('throw an exception when binds passed with object and numeric $1 is also present', function() { it('reject when binds passed with object and numeric $1 is also present', function() {
var self = this;
var typeCast = (dialect === 'postgres') ? '::int' : ''; var typeCast = (dialect === 'postgres') ? '::int' : '';
var logSql; var logSql;
expect(function() { return this.sequelize.query('select $one'+typeCast+' as foo, $two'+typeCast+' as bar, \'$1\' as baz', { raw: true, bind: { one: 1, two: 2 }, logging: function(s) { logSql = s; } })
self.sequelize.query('select $one'+typeCast+' as foo, $two'+typeCast+' as bar, \'$1\' as baz', { raw: true, bind: { one: 1, two: 2 }, logging: function(s) { logSql = s; } }); .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception when binds passed as array and $alpha is also present', function() { it('reject when binds passed as array and $alpha is also present', function() {
var self = this;
var typeCast = (dialect === 'postgres') ? '::int' : ''; var typeCast = (dialect === 'postgres') ? '::int' : '';
var logSql; var logSql;
expect(function() { return this.sequelize.query('select $1'+typeCast+' as foo, $2'+typeCast+' as bar, \'$foo\' as baz', { raw: true, bind: [1, 2], logging: function(s) { logSql = s; } })
self.sequelize.query('select $1'+typeCast+' as foo, $2'+typeCast+' as bar, \'$foo\' as baz', { raw: true, bind: [1, 2], logging: function(s) { logSql = s; } }); .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception when bind key is $0 with the passed array', function() { it('reject when bind key is $0 with the passed array', function() {
var self = this; return this.sequelize.query('select $1 as foo, $0 as bar, $3 as baz', { raw: true, bind: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $1 as foo, $0 as bar, $3 as baz', { raw: true, bind: [1, 2] });
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception when bind key is $01 with the passed array', function() { it('reject when bind key is $01 with the passed array', function() {
var self = this; return this.sequelize.query('select $1 as foo, $01 as bar, $3 as baz', { raw: true, bind: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $1 as foo, $01 as bar, $3 as baz', { raw: true, bind: [1, 2] });
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception when bind key is missing in the passed array', function() { it('reject when bind key is missing in the passed array', function() {
var self = this; return this.sequelize.query('select $1 as foo, $2 as bar, $3 as baz', { raw: true, bind: [1, 2] })
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $1 as foo, $2 as bar, $3 as baz', { raw: true, bind: [1, 2] });
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception when bind key is missing in the passed object', function() { it('reject when bind key is missing in the passed object', function() {
var self = this; return this.sequelize.query('select $one as foo, $two as bar, $three as baz', { raw: true, bind: { one: 1, two: 2 }})
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $one as foo, $two as bar, $three as baz', { raw: true, bind: { one: 1, two: 2 }});
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed number for bind', function() { it('reject with the passed number for bind', function() {
var self = this; return this.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: 2 })
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: 2 });
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed empty object for bind', function() { it('reject with the passed empty object for bind', function() {
var self = this; return this.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: {}})
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: {}});
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed string for bind', function() { it('reject with the passed string for bind', function() {
var self = this; return this.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: 'foobar'})
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: 'foobar'});
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('throw an exception with the passed date for bind', function() { it('reject with the passed date for bind', function() {
var self = this; return this.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: new Date()})
expect(function() { .should.be.rejectedWith(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
self.sequelize.query('select $one as foo, $two as bar', { raw: true, bind: new Date()});
}).to.throw(Error, /Named bind parameter "\$\w+" has no value in the given object\./g);
}); });
it('handles AS in conjunction with functions just fine', function() { it('handles AS in conjunction with functions just fine', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!