From e8b6cc538b1a7a38c0ec3f4c7c7a76eeff5d5579 Mon Sep 17 00:00:00 2001 From: Christiaan Westerbeek Date: Wed, 9 Jul 2014 09:24:10 +0200 Subject: [PATCH] Add support for mssql --- Readme.md | 1 + lib/Dialects/mssql.js | 66 ++++++++++++++++++ test/integration/test-dialect-mssql.js | 95 ++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 lib/Dialects/mssql.js create mode 100644 test/integration/test-dialect-mssql.js diff --git a/Readme.md b/Readme.md index f78809f..7bb37a2 100644 --- a/Readme.md +++ b/Readme.md @@ -13,6 +13,7 @@ npm install sql-query - MySQL - PostgreSQL - SQLite +- MSSQL ## About diff --git a/lib/Dialects/mssql.js b/lib/Dialects/mssql.js new file mode 100644 index 0000000..9937d34 --- /dev/null +++ b/lib/Dialects/mssql.js @@ -0,0 +1,66 @@ +var util = require("util"); +var helpers = require("../Helpers"); + +exports.DataTypes = { + id: 'INT IDENTITY(1,1) NOT NULL PRIMARY KEY', + int: 'INT', + float: 'FLOAT', + bool: 'BIT', + text: 'TEXT' +}; + + +exports.escape = function (query, args) { + return helpers.escapeQuery(exports, query, args); +} + +exports.escapeId = function () { + return Array.prototype.slice.apply(arguments).map(function (el) { + if (typeof el == "object") { + return el.str.replace(/\?:(id|value)/g, function (m) { + if (m == "?:id") { + return exports.escapeId(el.escapes.shift()); + } + // ?:value + return exports.escapeVal(el.escapes.shift()); + }); + } + return "[" + el + "]"; + }).join("."); +}; + +exports.escapeVal = function (val, timeZone) { + if (val === undefined || val === null) { + return 'NULL'; + } + + if (Array.isArray(val)) { + if (val.length === 1 && Array.isArray(val[0])) { + return "(" + val[0].map(exports.escapeVal.bind(this)) + ")"; + } + return "(" + val.map(exports.escapeVal.bind(this)).join(", ") + ")"; + } + + if (util.isDate(val)) { + return "'" + helpers.dateToString(val, timeZone || "local", { dialect: 'mssql' }) + "'"; + } + + if (Buffer.isBuffer(val)) { + return "X'" + val.toString("hex") + "'"; + } + + switch (typeof val) { + case "number": + if (!isFinite(val)) { + val = val.toString(); + break; + } + return val; + case "boolean": + return val ? 1 : 0; + case "function": + return val(exports); + } + + return "'" + val.replace(/\'/g, "''") + "'"; +}; diff --git a/test/integration/test-dialect-mssql.js b/test/integration/test-dialect-mssql.js new file mode 100644 index 0000000..db0d0f5 --- /dev/null +++ b/test/integration/test-dialect-mssql.js @@ -0,0 +1,95 @@ +var common = require('../common'); +var assert = require('assert'); +var dialect = common.getDialect('mssql'); +var d = new Date(1378322111133); +var tzOffsetMillis = (d.getTimezoneOffset() * 60 * 1000); + +assert.equal( + dialect.escapeId('col'), + "[col]" +); + +assert.equal( + dialect.escapeId('table', 'col'), + "[table].[col]" +); + +assert.equal( + dialect.escapeId('table', 'co\'l'), + "[table].[co\'l]" +); + +assert.equal( + dialect.escapeVal(undefined), + 'NULL' +); + +assert.equal( + dialect.escapeVal(null), + 'NULL' +); + +assert.equal( + dialect.escapeVal(123), + "123" +); + +assert.equal( + dialect.escapeVal(NaN), + "'NaN'" +); + +assert.equal( + dialect.escapeVal(Infinity), + "'Infinity'" +); + +assert.equal( + dialect.escapeVal('abc'), + "'abc'" +); + +assert.equal( + dialect.escapeVal('ab\'c'), + "'ab''c'" +); + +assert.equal( + dialect.escapeVal([ 1, 'abc', 'a\'' ]), + "(1, 'abc', 'a''')" +); + +assert.equal( + dialect.escapeVal(true), + "1" +); + +assert.equal( + dialect.escapeVal(false), + "0" +); + +assert.equal( + dialect.escapeVal(new Date(d.getTime() + tzOffsetMillis)), + "'2013-09-04T19:15:11.133Z'" +); + +assert.equal( + dialect.escapeVal(new Date(d.getTime()), 'Z'), + "'2013-09-04T19:15:11.133Z'" +); + +assert.equal( + dialect.escapeVal(new Date(d.getTime()), '-0000'), + "'2013-09-04T19:15:11.133Z'" +); + +assert.equal( + dialect.escapeVal(new Date(d.getTime()), '-0400'), + "'2013-09-04T15:15:11.133Z'" +); + +assert.equal( + dialect.escapeVal(new Date(d.getTime())), + dialect.escapeVal(new Date(d.getTime()), 'local') +);