Skip to content

Commit

Permalink
feat(query): add ability to pass arrays as replacements (#9050) (#9054)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirill89 authored and sushantdhiman committed Feb 25, 2018
1 parent 222b13f commit 60c04d9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
17 changes: 16 additions & 1 deletion lib/sql-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ const dataTypes = require('./data-types');
const util = require('util');
const _ = require('lodash');

function arrayToList(array, timeZone, dialect, format) {
return array.reduce((sql, val, i) => {
if (i !== 0) {
sql += ', ';
}
if (Array.isArray(val)) {
sql += `(${arrayToList(val, timeZone, dialect, format)})`;
} else {
sql += escape(val, timeZone, dialect, format);
}
return sql;
}, '');
}
exports.arrayToList = arrayToList;

function escape(val, timeZone, dialect, format) {
let prependN = false;
if (val === undefined || val === null) {
Expand Down Expand Up @@ -44,7 +59,7 @@ function escape(val, timeZone, dialect, format) {
if (dialect === 'postgres' && !format) {
return dataTypes.ARRAY.prototype.stringify(val, {escape: partialEscape});
}
return val.map(partialEscape);
return arrayToList(val, timeZone, dialect, format);
}

if (!val.replace) {
Expand Down
17 changes: 17 additions & 0 deletions test/integration/sequelize.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,23 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => {
return this.sequelize.query(this.insertQuery);
});

it('executes a query if a placeholder value is an array', function() {
return this.sequelize.query(`INSERT INTO ${qq(this.User.tableName)} (username, email_address, ` +
`${qq('createdAt')}, ${qq('updatedAt')}) VALUES ?;`, {
replacements: [[
['john', 'john@gmail.com', '2012-01-01 10:10:10', '2012-01-01 10:10:10'],
['michael', 'michael@gmail.com', '2012-01-01 10:10:10', '2012-01-01 10:10:10']
]]
})
.then(() => this.sequelize.query(`SELECT * FROM ${qq(this.User.tableName)};`, {
type: this.sequelize.QueryTypes.SELECT
}))
.then(rows => {
expect(rows).to.be.lengthOf(2);
expect(rows[0].username).to.be.equal('john');
expect(rows[1].username).to.be.equal('michael');
});
});

describe('logging', () => {
it('executes a query with global benchmarking option and default logger', () => {
Expand Down
9 changes: 9 additions & 0 deletions test/unit/dialects/abstract/query-generator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ const chai = require('chai'),
getAbstractQueryGenerator = require(__dirname + '/../../support').getAbstractQueryGenerator;

describe('QueryGenerator', () => {
describe('selectQuery', () => {
it('should generate correct query using array placeholder', function() {
const QG = getAbstractQueryGenerator(this.sequelize);

QG.selectQuery('foo', {where: {bar: {[Op.like]: {[Op.any]: ['a', 'b']}}}})
.should.be.equal('SELECT * FROM foo WHERE foo.bar LIKE ANY (\'a\', \'b\');');
});
});

describe('whereItemQuery', () => {
it('should generate correct query for Symbol operators', function() {
const QG = getAbstractQueryGenerator(this.sequelize);
Expand Down

0 comments on commit 60c04d9

Please sign in to comment.