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

Commit 2f7c717f by Mick Hansen

Merge pull request #5039 from zapatek/zapatek

Prefix string literals with N in mssql
2 parents 54c57a74 5a28c41e
# Future
- [FIXED] Support Unicode strings in mssql [#3752](https://github.com/sequelize/sequelize/issues/3752)
# 3.15.1 # 3.15.1
- [FIXED] calling Model.update() modifies passed values [#4520](https://github.com/sequelize/sequelize/issues/4520) - [FIXED] calling Model.update() modifies passed values [#4520](https://github.com/sequelize/sequelize/issues/4520)
- [FIXED] Instance can be chained on .set() and other methods [#4702](https://github.com/sequelize/sequelize/issues/4702) - [FIXED] Instance can be chained on .set() and other methods [#4702](https://github.com/sequelize/sequelize/issues/4702)
......
...@@ -13,6 +13,7 @@ SqlString.escapeId = function(val, forbidQualified) { ...@@ -13,6 +13,7 @@ SqlString.escapeId = function(val, forbidQualified) {
}; };
SqlString.escape = function(val, timeZone, dialect, format) { SqlString.escape = function(val, timeZone, dialect, format) {
var prependN = false;
if (val === undefined || val === null) { if (val === undefined || val === null) {
return 'NULL'; return 'NULL';
} }
...@@ -27,6 +28,11 @@ SqlString.escape = function(val, timeZone, dialect, format) { ...@@ -27,6 +28,11 @@ SqlString.escape = function(val, timeZone, dialect, format) {
return '' + !!val; return '' + !!val;
case 'number': case 'number':
return val + ''; return val + '';
case 'string':
// In mssql, prepend N to all quoted vals which are originally a string (for
// unicode compatibility)
prependN = dialect === 'mssql';
break;
} }
if (val instanceof Date) { if (val instanceof Date) {
...@@ -66,7 +72,7 @@ SqlString.escape = function(val, timeZone, dialect, format) { ...@@ -66,7 +72,7 @@ SqlString.escape = function(val, timeZone, dialect, format) {
} }
}); });
} }
return "'" + val + "'"; return (prependN ? "N'" : "'") + val + "'";
}; };
SqlString.format = function(sql, values, timeZone, dialect) { SqlString.format = function(sql, values, timeZone, dialect) {
......
...@@ -712,7 +712,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -712,7 +712,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
intVal: this.sequelize.cast('1', type) intVal: this.sequelize.cast('1', type)
}, { }, {
logging: function(sql) { logging: function(sql) {
expect(sql).to.match(new RegExp("CAST\\('1' AS " + type.toUpperCase() + '\\)')); expect(sql).to.match(new RegExp("CAST\\(N?'1' AS " + type.toUpperCase() + '\\)'));
match = true; match = true;
} }
}).then(function(user) { }).then(function(user) {
......
...@@ -121,7 +121,7 @@ describe(Support.getTestDialectTeaser('Model'), function() { ...@@ -121,7 +121,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
where: ['specialkey = ?', 'awesome'], where: ['specialkey = ?', 'awesome'],
logging: function(sql) { logging: function(sql) {
test = true; test = true;
expect(sql).to.contain("WHERE specialkey = 'awesome'"); expect(sql).to.match(/WHERE specialkey = N?'awesome'/);
} }
}).then(function() { }).then(function() {
expect(test).to.be.true; expect(test).to.be.true;
......
...@@ -23,7 +23,7 @@ describe(Support.getTestDialectTeaser('SQL'), function() { ...@@ -23,7 +23,7 @@ describe(Support.getTestDialectTeaser('SQL'), function() {
sqlite: 'CREATE TABLE IF NOT EXISTS `foo.users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `mood` TEXT);', sqlite: 'CREATE TABLE IF NOT EXISTS `foo.users` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `mood` TEXT);',
postgres: 'CREATE TABLE IF NOT EXISTS "foo"."users" ("id" SERIAL , "mood" "foo"."enum_users_mood", PRIMARY KEY ("id"));', postgres: 'CREATE TABLE IF NOT EXISTS "foo"."users" ("id" SERIAL , "mood" "foo"."enum_users_mood", PRIMARY KEY ("id"));',
mysql: "CREATE TABLE IF NOT EXISTS `foo.users` (`id` INTEGER NOT NULL auto_increment , `mood` ENUM('happy', 'sad'), PRIMARY KEY (`id`)) ENGINE=InnoDB;", mysql: "CREATE TABLE IF NOT EXISTS `foo.users` (`id` INTEGER NOT NULL auto_increment , `mood` ENUM('happy', 'sad'), PRIMARY KEY (`id`)) ENGINE=InnoDB;",
mssql: "IF OBJECT_ID('[foo].[users]', 'U') IS NULL CREATE TABLE [foo].[users] ([id] INTEGER NOT NULL IDENTITY(1,1) , [mood] VARCHAR(255) CHECK (mood IN('happy', 'sad')), PRIMARY KEY ([id]));" mssql: "IF OBJECT_ID('[foo].[users]', 'U') IS NULL CREATE TABLE [foo].[users] ([id] INTEGER NOT NULL IDENTITY(1,1) , [mood] VARCHAR(255) CHECK (mood IN(N'happy', N'sad')), PRIMARY KEY ([id]));"
}); });
}); });
}); });
......
...@@ -28,7 +28,7 @@ describe(Support.getTestDialectTeaser('SQL'), function() { ...@@ -28,7 +28,7 @@ describe(Support.getTestDialectTeaser('SQL'), function() {
}; };
expectsql(sql.insertQuery(User.tableName,{user_name: 'triggertest'},User.rawAttributes,options), expectsql(sql.insertQuery(User.tableName,{user_name: 'triggertest'},User.rawAttributes,options),
{ {
mssql:'declare @tmp table ([id] INTEGER,[user_name] NVARCHAR(255));INSERT INTO [users] ([user_name]) OUTPUT INSERTED.[id],INSERTED.[user_name] into @tmp VALUES (\'triggertest\');select * from @tmp;', mssql:'declare @tmp table ([id] INTEGER,[user_name] NVARCHAR(255));INSERT INTO [users] ([user_name]) OUTPUT INSERTED.[id],INSERTED.[user_name] into @tmp VALUES (N\'triggertest\');select * from @tmp;',
postgres: 'INSERT INTO "users" ("user_name") VALUES (\'triggertest\') RETURNING *;', postgres: 'INSERT INTO "users" ("user_name") VALUES (\'triggertest\') RETURNING *;',
default: "INSERT INTO `users` (`user_name`) VALUES ('triggertest');", default: "INSERT INTO `users` (`user_name`) VALUES ('triggertest');",
}); });
......
...@@ -147,7 +147,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -147,7 +147,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
] ]
}).include[0] }).include[0]
}, { }, {
default: "LEFT OUTER JOIN [company] AS [Company] ON [User].[companyId] = [Company].[id] AND [Company].[name] = 'ABC'" default: "LEFT OUTER JOIN [company] AS [Company] ON [User].[companyId] = [Company].[id] AND [Company].[name] = 'ABC'",
mssql: "LEFT OUTER JOIN [company] AS [Company] ON [User].[companyId] = [Company].[id] AND [Company].[name] = N'ABC'"
}); });
testsql({ testsql({
......
...@@ -38,7 +38,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -38,7 +38,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
email: 'jon.snow@gmail.com' email: 'jon.snow@gmail.com'
} }
}, { }, {
default: "SELECT [email], [first_name] AS [firstName] FROM [User] WHERE [User].[email] = 'jon.snow@gmail.com';" default: "SELECT [email], [first_name] AS [firstName] FROM [User] WHERE [User].[email] = 'jon.snow@gmail.com';",
mssql: "SELECT [email], [first_name] AS [firstName] FROM [User] WHERE [User].[email] = N'jon.snow@gmail.com';"
}); });
testsql({ testsql({
......
...@@ -28,7 +28,7 @@ describe(Support.getTestDialectTeaser('SQL'), function() { ...@@ -28,7 +28,7 @@ describe(Support.getTestDialectTeaser('SQL'), function() {
}; };
expectsql(sql.updateQuery(User.tableName,{user_name: 'triggertest'},{id:2},options,User.rawAttributes), expectsql(sql.updateQuery(User.tableName,{user_name: 'triggertest'},{id:2},options,User.rawAttributes),
{ {
mssql: 'declare @tmp table ([id] INTEGER,[user_name] NVARCHAR(255));UPDATE [users] SET [user_name]=\'triggertest\' OUTPUT INSERTED.[id],INSERTED.[user_name] into @tmp WHERE [id] = 2;select * from @tmp', mssql: 'declare @tmp table ([id] INTEGER,[user_name] NVARCHAR(255));UPDATE [users] SET [user_name]=N\'triggertest\' OUTPUT INSERTED.[id],INSERTED.[user_name] into @tmp WHERE [id] = 2;select * from @tmp',
postgres:'UPDATE "users" SET "user_name"=\'triggertest\' WHERE "id" = 2 RETURNING *', postgres:'UPDATE "users" SET "user_name"=\'triggertest\' WHERE "id" = 2 RETURNING *',
default: "UPDATE `users` SET `user_name`=\'triggertest\' WHERE `id` = 2", default: "UPDATE `users` SET `user_name`=\'triggertest\' WHERE `id` = 2",
}); });
......
...@@ -51,7 +51,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -51,7 +51,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
{ id: { $gt: 10 } } { id: { $gt: 10 } }
] ]
}, { }, {
default: "WHERE [name] = 'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)" default: "WHERE [name] = 'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)",
mssql: "WHERE [name] = N'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)"
}); });
testsql({ testsql({
...@@ -63,7 +64,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -63,7 +64,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
] ]
} }
}, { }, {
default: "WHERE [name] = 'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)" default: "WHERE [name] = 'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)",
mssql: "WHERE [name] = N'a project' AND ([id] IN (1, 2, 3) OR [id] > 10)"
}); });
}); });
...@@ -174,7 +176,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -174,7 +176,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
testsql('email', { testsql('email', {
$ne: 'jack.bauer@gmail.com' $ne: 'jack.bauer@gmail.com'
}, { }, {
default: "[email] != 'jack.bauer@gmail.com'" default: "[email] != 'jack.bauer@gmail.com'",
mssql: "[email] != N'jack.bauer@gmail.com'"
}); });
}); });
...@@ -183,7 +186,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -183,7 +186,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
testsql('email', { testsql('email', {
$or: ['maker@mhansen.io', 'janzeh@gmail.com'] $or: ['maker@mhansen.io', 'janzeh@gmail.com']
}, { }, {
default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')' default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')',
mssql: '([email] = N\'maker@mhansen.io\' OR [email] = N\'janzeh@gmail.com\')'
}); });
testsql('rank', { testsql('rank', {
...@@ -199,14 +203,16 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -199,14 +203,16 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
{email: 'maker@mhansen.io'}, {email: 'maker@mhansen.io'},
{email: 'janzeh@gmail.com'} {email: 'janzeh@gmail.com'}
], { ], {
default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')' default: '([email] = \'maker@mhansen.io\' OR [email] = \'janzeh@gmail.com\')',
mssql: '([email] = N\'maker@mhansen.io\' OR [email] = N\'janzeh@gmail.com\')'
}); });
testsql('$or', { testsql('$or', {
email: 'maker@mhansen.io', email: 'maker@mhansen.io',
name: 'Mick Hansen' name: 'Mick Hansen'
}, { }, {
default: '([email] = \'maker@mhansen.io\' OR [name] = \'Mick Hansen\')' default: '([email] = \'maker@mhansen.io\' OR [name] = \'Mick Hansen\')',
mssql: '([email] = N\'maker@mhansen.io\' OR [name] = N\'Mick Hansen\')'
}); });
testsql('$or', { testsql('$or', {
...@@ -226,7 +232,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -226,7 +232,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
type: 'CLIENT' type: 'CLIENT'
} }
], { ], {
default: "([roleName] = 'NEW' OR ([roleName] = 'CLIENT' AND [type] = 'CLIENT'))" default: "([roleName] = 'NEW' OR ([roleName] = 'CLIENT' AND [type] = 'CLIENT'))",
mssql: "([roleName] = N'NEW' OR ([roleName] = N'CLIENT' AND [type] = N'CLIENT'))"
}); });
test('sequelize.or({group_id: 1}, {user_id: 2})', function () { test('sequelize.or({group_id: 1}, {user_id: 2})', function () {
...@@ -237,7 +244,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -237,7 +244,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
test("sequelize.or({group_id: 1}, {user_id: 2, role: 'admin'})", function () { test("sequelize.or({group_id: 1}, {user_id: 2, role: 'admin'})", function () {
expectsql(sql.whereItemQuery(undefined, this.sequelize.or({group_id: 1}, {user_id: 2, role: 'admin'})), { expectsql(sql.whereItemQuery(undefined, this.sequelize.or({group_id: 1}, {user_id: 2, role: 'admin'})), {
default: "([group_id] = 1 OR ([user_id] = 2 AND [role] = 'admin'))" default: "([group_id] = 1 OR ([user_id] = 2 AND [role] = 'admin'))",
mssql: "([group_id] = 1 OR ([user_id] = 2 AND [role] = N'admin'))"
}); });
}); });
}); });
...@@ -265,7 +273,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -265,7 +273,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
} }
} }
], { ], {
default: "([name] LIKE '%hello' AND [name] LIKE 'hello%')" default: "([name] LIKE '%hello' AND [name] LIKE 'hello%')",
mssql: "([name] LIKE N'%hello' AND [name] LIKE N'hello%')"
}); });
testsql('rank', { testsql('rank', {
...@@ -283,7 +292,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -283,7 +292,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
{like : '%someValue2%'} {like : '%someValue2%'}
] ]
}, { }, {
default: "([name] LIKE '%someValue1%' AND [name] LIKE '%someValue2%')" default: "([name] LIKE '%someValue1%' AND [name] LIKE '%someValue2%')",
mssql: "([name] LIKE N'%someValue1%' AND [name] LIKE N'%someValue2%')"
}); });
test('sequelize.and({shared: 1, sequelize.or({group_id: 1}, {user_id: 2}))', function () { test('sequelize.and({shared: 1, sequelize.or({group_id: 1}, {user_id: 2}))', function () {
...@@ -377,7 +387,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -377,7 +387,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
testsql('username', { testsql('username', {
$like: '%swagger' $like: '%swagger'
}, { }, {
default: "[username] LIKE '%swagger'" default: "[username] LIKE '%swagger'",
mssql: "[username] LIKE N'%swagger'"
}); });
}); });
...@@ -385,14 +396,16 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -385,14 +396,16 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
testsql('date', { testsql('date', {
$between: ['2013-01-01', '2013-01-11'] $between: ['2013-01-01', '2013-01-11']
}, { }, {
default: "[date] BETWEEN '2013-01-01' AND '2013-01-11'" default: "[date] BETWEEN '2013-01-01' AND '2013-01-11'",
mssql: "[date] BETWEEN N'2013-01-01' AND N'2013-01-11'"
}); });
testsql('date', { testsql('date', {
between: ['2012-12-10', '2013-01-02'], between: ['2012-12-10', '2013-01-02'],
nbetween: ['2013-01-04', '2013-01-20'] nbetween: ['2013-01-04', '2013-01-20']
}, { }, {
default: "([date] BETWEEN '2012-12-10' AND '2013-01-02' AND [date] NOT BETWEEN '2013-01-04' AND '2013-01-20')" default: "([date] BETWEEN '2012-12-10' AND '2013-01-02' AND [date] NOT BETWEEN '2013-01-04' AND '2013-01-20')",
mssql: "([date] BETWEEN N'2012-12-10' AND N'2013-01-02' AND [date] NOT BETWEEN N'2013-01-04' AND N'2013-01-20')"
}); });
}); });
...@@ -400,7 +413,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -400,7 +413,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
testsql('date', { testsql('date', {
$notBetween: ['2013-01-01', '2013-01-11'] $notBetween: ['2013-01-01', '2013-01-11']
}, { }, {
default: "[date] NOT BETWEEN '2013-01-01' AND '2013-01-11'" default: "[date] NOT BETWEEN '2013-01-01' AND '2013-01-11'",
mssql: "[date] NOT BETWEEN N'2013-01-01' AND N'2013-01-11'"
}); });
}); });
...@@ -751,7 +765,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() { ...@@ -751,7 +765,8 @@ suite(Support.getTestDialectTeaser('SQL'), function() {
suite('fn', function () { suite('fn', function () {
test('{name: this.sequelize.fn(\'LOWER\', \'DERP\')}', function () { test('{name: this.sequelize.fn(\'LOWER\', \'DERP\')}', function () {
expectsql(sql.whereQuery({name: this.sequelize.fn('LOWER', 'DERP')}), { expectsql(sql.whereQuery({name: this.sequelize.fn('LOWER', 'DERP')}), {
default: "WHERE [name] = LOWER('DERP')" default: "WHERE [name] = LOWER('DERP')",
mssql: "WHERE [name] = LOWER(N'DERP')"
}); });
}); });
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!