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

Commit 9d5fcc2a by Mick Hansen

test(unit/sql): cover additional cases + postgres array cases

1 parent a7405663
......@@ -1559,13 +1559,15 @@ module.exports = (function() {
}).join(binding) || '';
},
whereItemQuery: function(key, value, options) {
options = options || {};
var self = this
, binding
, comparatorMap
, aliasMap
, comparator = '=';
options = options || {};
, comparator = '='
, field = options.field || options.model && options.model.rawAttributes && options.model.rawAttributes[key] && options.model.rawAttributes[key]
, fieldType = options.type || (field && field.type);
comparatorMap = {
$eq: '=',
......@@ -1581,7 +1583,10 @@ module.exports = (function() {
$iLike: 'ILIKE',
$notILike: 'NOT ILIKE',
$between: 'BETWEEN',
$notBetween: 'NOT BETWEEN'
$notBetween: 'NOT BETWEEN',
$overlap: "&&",
$contains: "@>",
$contained: "<@"
};
// Maintain BC
......@@ -1604,7 +1609,11 @@ module.exports = (function() {
"between": "$between",
"!..": "$notBetween",
"notbetween": "$notBetween",
"nbetween": "$notBetween"
"nbetween": "$notBetween",
"overlap": "$overlap",
"&&": "$overlap",
"@>": "$contains",
"<@": "$contained"
};
key = aliasMap[key] || key;
......@@ -1664,9 +1673,10 @@ module.exports = (function() {
}
// Setup keys and comparators
if (options.model && options.model.rawAttributes && options.model.rawAttributes[key] && typeof options.model.rawAttributes[key].type === "string" && options.model.rawAttributes[key].type.substr(-2) === '[]') {
// Stupid horrible ARRAY checking, need a new way
value = this.escape(value, options.model.rawAttributes[key]);
if (Array.isArray(value) && typeof fieldType === "string" && fieldType.substr(-2) === '[]') {
// Stupid horrible PG ARRAY checking, need a new way
value = this.escape(value, field);
} else if (value && (value.$in || Array.isArray(value) || (value.$not && Array.isArray(value.$not)) || value.$notIn)) {
comparator = 'IN';
if (value.$not || value.$notIn) comparator = 'NOT IN';
......@@ -1696,7 +1706,7 @@ module.exports = (function() {
comparator = 'IS NOT';
}
value = this.escape(value);
value = this.escape(value, field);
}
key = this.quoteIdentifier(key);
......
......@@ -22,6 +22,7 @@ PostgresDialect.prototype.supports = _.merge(_.cloneDeep(Abstract.prototype.supp
'EXCEPTION': true,
'ON DUPLICATE KEY': false,
'ORDER NULLS': true,
'ARRAY': true,
returnValues: {
returning: true
},
......
......@@ -902,7 +902,7 @@ module.exports = (function() {
}
} else if (Utils._.isObject(value) && field && (field.type === DataTypes.JSON || field.type === DataTypes.JSONB)) {
value = JSON.stringify(value);
} else if (Array.isArray(value) && field.type === DataTypes.ARRAY(DataTypes.JSON)) {
} else if (Array.isArray(value) && field && field.type === DataTypes.ARRAY(DataTypes.JSON)) {
return "ARRAY[" + value.map(function (v) {
return SqlString.escape(JSON.stringify(v), false, this.options.timezone, this.dialect, field);
}, this).join(",") + "]::JSON[]";
......
......@@ -196,11 +196,12 @@ var Support = {
expectsql: function(query, expectations) {
var expectation = expectations[Support.sequelize.dialect.name];
if (!expectation && Support.sequelize.dialect.name !== 'mssql') {
if (!expectation) {
expectation = expectations['default']
.replace(/\[/g, Support.sequelize.dialect.TICK_CHAR_LEFT)
.replace(/\]/g, Support.sequelize.dialect.TICK_CHAR_RIGHT);
}
expect(query).to.equal(expectation);
}
};
......
'use strict';
var Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + '/../../../lib/data-types')
, util = require('util')
, expectsql = Support.expectsql
, current = Support.sequelize
......@@ -16,7 +17,7 @@ suite('SQL', function() {
options = undefined;
}
test(util.inspect(params)+(options && ', '+util.inspect(options) || ''), function () {
test(util.inspect(params, {depth: 10})+(options && ', '+util.inspect(options) || ''), function () {
return expectsql(sql.whereQuery(params, options), expectation);
});
};
......@@ -36,9 +37,33 @@ suite('SQL', function() {
test("{ id: 1 }, { prefix: current.literal(sql.quoteTable.call(current.dialect.QueryGenerator, {schema: 'yolo', tableName: 'User'})) }", function () {
expectsql(sql.whereQuery({id: 1}, {prefix: current.literal(sql.quoteTable.call(current.dialect.QueryGenerator, {schema: 'yolo', tableName: 'User'}))}), {
default: 'WHERE [yolo.User].[id] = 1'
default: 'WHERE [yolo.User].[id] = 1',
postgres: 'WHERE "yolo"."User"."id" = 1',
mssql: 'WHERE [yolo].[User].[id] = 1',
});
});
testsql({
name: 'a project',
$or: [
{ id: [1,2,3] },
{ id: { $gt: 10 } }
]
}, {
default: "WHERE [name] = 'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)"
});
testsql({
name: 'a project',
id: {
$or: [
[1,2,3],
{ $gt: 10 }
]
}
}, {
default: "WHERE [name] = 'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)"
});
});
suite('whereItemQuery', function () {
......@@ -48,7 +73,7 @@ suite('SQL', function() {
options = undefined;
}
test(key+": "+util.inspect(value), function () {
test(key+": "+util.inspect(value, {depth: 10})+(options && ', '+util.inspect(options) || ''), function () {
return expectsql(sql.whereItemQuery(key, value, options), expectation);
});
};
......@@ -101,58 +126,60 @@ suite('SQL', function() {
});
});
suite('$or', function () {
testsql('email', {
$or: ['maker@mhansen.io', 'janzeh@gmail.com']
}, {
default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')'
});
testsql('$or', [
{email: 'maker@mhansen.io'},
{email: 'janzeh@gmail.com'}
], {
default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')'
});
suite('$and/$or', function () {
suite('$or', function () {
testsql('email', {
$or: ['maker@mhansen.io', 'janzeh@gmail.com']
}, {
default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')'
});
testsql('$or', {
email: 'maker@mhansen.io',
name: 'Mick Hansen'
}, {
default: '([email] = \'maker@mhansen.io\' OR [name] = \'Mick Hansen\')'
});
testsql('$or', [
{email: 'maker@mhansen.io'},
{email: 'janzeh@gmail.com'}
], {
default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')'
});
testsql('$or', {
equipment: [1, 3],
muscles: {
$in: [2, 4]
}
}, {
default: '([equipment] IN (1, 3) OR [muscles] IN (2, 4))'
});
testsql('$or', {
email: 'maker@mhansen.io',
name: 'Mick Hansen'
}, {
default: '([email] = \'maker@mhansen.io\' OR [name] = \'Mick Hansen\')'
});
test("sequelize.or({group_id: 1}, {user_id: 2})", function () {
expectsql(sql.whereItemQuery(undefined, this.sequelize.or({group_id: 1}, {user_id: 2})), {
default: "([group_id] = 1 OR [user_id] = 2)"
testsql('$or', {
equipment: [1, 3],
muscles: {
$in: [2, 4]
}
}, {
default: '([equipment] IN (1, 3) OR [muscles] IN (2, 4))'
});
});
});
suite('$and', function () {
testsql('$and', {
shared: 1,
$or: {
group_id: 1,
user_id: 2
}
}, {
default: "([shared] = 1 AND ([group_id] = 1 OR [user_id] = 2))"
test("sequelize.or({group_id: 1}, {user_id: 2})", function () {
expectsql(sql.whereItemQuery(undefined, this.sequelize.or({group_id: 1}, {user_id: 2})), {
default: "([group_id] = 1 OR [user_id] = 2)"
});
});
});
test("sequelize.and({shared: 1, sequelize.or({group_id: 1}, {user_id: 2}))", function () {
expectsql(sql.whereItemQuery(undefined, this.sequelize.and({shared: 1}, this.sequelize.or({group_id: 1}, {user_id: 2}))), {
suite('$and', function () {
testsql('$and', {
shared: 1,
$or: {
group_id: 1,
user_id: 2
}
}, {
default: "([shared] = 1 AND ([group_id] = 1 OR [user_id] = 2))"
});
test("sequelize.and({shared: 1, sequelize.or({group_id: 1}, {user_id: 2}))", function () {
expectsql(sql.whereItemQuery(undefined, this.sequelize.and({shared: 1}, this.sequelize.or({group_id: 1}, {user_id: 2}))), {
default: "([shared] = 1 AND ([group_id] = 1 OR [user_id] = 2))"
});
});
});
});
......@@ -194,5 +221,43 @@ suite('SQL', function() {
default: "[date] NOT BETWEEN '2013-01-01' AND '2013-01-11'"
});
});
if (current.dialect.supports['ARRAY']) {
suite('ARRAY', function () {
testsql('muscles', {
$contains: [2, 3]
}, {
postgres: '"muscles" @> ARRAY[2,3]'
});
testsql('muscles', {
$contained: [6, 8]
}, {
postgres: '"muscles" <@ ARRAY[6,8]'
});
testsql('muscles', {
$overlap: [3, 11]
}, {
postgres: '"muscles" && ARRAY[3,11]'
});
testsql('muscles', {
$overlap: [3, 1]
}, {
postgres: '"muscles" && ARRAY[3,1]'
});
testsql('muscles', {
$contains: [2, 5]
}, {
field: {
type: DataTypes.ARRAY(DataTypes.INTEGER)
}
}, {
postgres: '"muscles" @> ARRAY[2,5]::INTEGER[]'
});
});
}
});
});
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!