From 2d7a38270cce4ef31f65a5b063c75e0b4c1ef082 Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Mon, 2 Jan 2017 11:08:22 +0100 Subject: [PATCH 1/8] Fixed support for mssql limit/offset --- lib/dialects/mssql/index.js | 57 +++++++++++++++++++++++++++++++++++++ package.json | 4 +-- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index 8374184..ac47a20 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -3,9 +3,66 @@ var BaseDialect = require('../base'); var _ = require('underscore'); var util = require('util'); +var templateChecks = require('../../utils/templateChecks'); var Dialect = module.exports = function(builder) { BaseDialect.call(this, builder); + + this.blocks.set('limit', function(params) { + return (params.offset) ? '' : 'TOP(' + builder._pushValue(params.limit) + ')'; + }); + + this.blocks.set('offset', function(params) { + var pre = (!params.sort) ? 'ORDER BY 1 ' : ''; + if (params.limit) { + return pre + 'OFFSET ' + params.offset + ' ROWS FETCH NEXT ' + params.limit + ' ROWS ONLY'; + }else { + return pre + 'OFFSET ' + params.offset + ' ROWS'; + } + }); + + this.templates.set('select', { + pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + + 'from {from} {table} {query} {select} {expression} {alias} ' + + '{join} {condition} {group} {having} {sort} {offset}', + defaults: { + fields: {} + }, + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); + + templateChecks.propType(type, params, 'distinct', 'boolean'); + + templateChecks.propType(type, params, 'fields', ['array', 'object']); + + templateChecks.propType(type, params, 'from', ['string', 'array', 'object']); + + templateChecks.atLeastOneOfProps(type, params, ['table', 'query', 'select', 'expression']); + templateChecks.onlyOneOfProps(type, params, ['table', 'query', 'select', 'expression']); + + templateChecks.propType(type, params, 'table', 'string'); + templateChecks.propType(type, params, 'query', 'object'); + templateChecks.propType(type, params, 'select', 'object'); + templateChecks.propType(type, params, 'expression', ['string', 'object']); + + templateChecks.propType(type, params, 'alias', ['string', 'object']); + + templateChecks.propType(type, params, 'join', ['array', 'object']); + + templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'having', ['array', 'object']); + + templateChecks.propType(type, params, 'group', ['string', 'array']); + + templateChecks.propType(type, params, 'sort', ['string', 'array', 'object']); + + templateChecks.propType(type, params, 'offset', ['number', 'string']); + templateChecks.propType(type, params, 'limit', ['number', 'string']); + } + }); + }; util.inherits(Dialect, BaseDialect); diff --git a/package.json b/package.json index ffe55e3..5464137 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "json-sql", "description": "node.js json to sql queries mapper", - "version": "0.3.8", + "version": "0.3.9", "author": "Artem Zhukov ", "license": "MIT", "repository": { @@ -18,7 +18,7 @@ "database" ], "dependencies": { - "underscore": "1.8.2" + "underscore": "1.8.3" }, "devDependencies": { "chai": "2.2.0", From ce084efbafcfb52cd421e912a87f2621eab500f1 Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Mon, 2 Jan 2017 11:50:26 +0100 Subject: [PATCH 2/8] Changed default valuesPrefix for mssql to "@" Mssql is now using builder._pushValue for limit/offset Replaced whitspaces with tabs --- lib/dialects/mssql/index.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index ac47a20..4884b00 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -6,22 +6,25 @@ var util = require('util'); var templateChecks = require('../../utils/templateChecks'); var Dialect = module.exports = function(builder) { + builder.options.valuesPrefix = '@'; BaseDialect.call(this, builder); - this.blocks.set('limit', function(params) { + this.blocks.set('limit', function(params) { return (params.offset) ? '' : 'TOP(' + builder._pushValue(params.limit) + ')'; }); - this.blocks.set('offset', function(params) { - var pre = (!params.sort) ? 'ORDER BY 1 ' : ''; - if (params.limit) { - return pre + 'OFFSET ' + params.offset + ' ROWS FETCH NEXT ' + params.limit + ' ROWS ONLY'; - }else { - return pre + 'OFFSET ' + params.offset + ' ROWS'; - } + this.blocks.set('offset', function(params) { + var pre = (!params.sort) ? 'ORDER BY 1 ' : ''; + if (params.limit) { + var str = pre + 'OFFSET ' + builder._pushValue(params.offset); + str += ' ROWS FETCH NEXT ' + builder._pushValue(params.limit) + ' ROWS ONLY'; + return str; + }else { + return pre + 'OFFSET ' + builder._pushValue(params.offset) + ' ROWS'; + } }); - this.templates.set('select', { + this.templates.set('select', { pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + 'from {from} {table} {query} {select} {expression} {alias} ' + '{join} {condition} {group} {having} {sort} {offset}', @@ -58,7 +61,7 @@ var Dialect = module.exports = function(builder) { templateChecks.propType(type, params, 'sort', ['string', 'array', 'object']); - templateChecks.propType(type, params, 'offset', ['number', 'string']); + templateChecks.propType(type, params, 'offset', ['number', 'string']); templateChecks.propType(type, params, 'limit', ['number', 'string']); } }); From c0a60426632e95f4243d4504bf3c283706b6175f Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Fri, 6 Jan 2017 15:00:05 +0100 Subject: [PATCH 3/8] Fixed MSSQL limit support --- lib/dialects/mssql/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index 4884b00..24828fb 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -10,7 +10,7 @@ var Dialect = module.exports = function(builder) { BaseDialect.call(this, builder); this.blocks.set('limit', function(params) { - return (params.offset) ? '' : 'TOP(' + builder._pushValue(params.limit) + ')'; + return (!isNaN(params.offset)) ? '' : 'TOP(' + builder._pushValue(params.limit) + ')'; }); this.blocks.set('offset', function(params) { From a138b2cb02c9c07996a249028aa108a145745cd0 Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Thu, 2 Mar 2017 17:04:46 +0100 Subject: [PATCH 4/8] Fixed MSSQl boolean support --- lib/dialects/mssql/index.js | 29 +++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index 24828fb..46f49cc 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -7,6 +7,35 @@ var templateChecks = require('../../utils/templateChecks'); var Dialect = module.exports = function(builder) { builder.options.valuesPrefix = '@'; + + builder._pushValue = function(value) { + if (_.isUndefined(value) || _.isNull(value)) { + return 'null'; + } else if (_.isBoolean(value)) { + return String(Number(value)); + } else if (_.isNumber(value)) { + return String(value); + } else if (_.isString(value) || _.isDate(value)) { + if (this.options.separatedValues) { + var placeholder = this._getPlaceholder(); + + if (this.options.namedValues) { + this._values[placeholder] = value; + } else { + this._values.push(value); + } + + return this._wrapPlaceholder(placeholder); + } else { + if (_.isDate(value)) value = value.toISOString(); + + return '\'' + value + '\''; + } + } else { + throw new Error('Wrong value type "' + (typeof value) + '"'); + } + }; + BaseDialect.call(this, builder); this.blocks.set('limit', function(params) { diff --git a/package.json b/package.json index 1963789..166b77e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "json-sql", "description": "node.js json to sql queries mapper", - "version": "0.3.10", + "version": "0.3.11", "author": "Artem Zhukov ", "license": "MIT", "repository": { From dd3467de3652b82fc1e88fcb4a97ddf37180dfd3 Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Wed, 10 May 2017 16:29:21 +0200 Subject: [PATCH 5/8] Added returning support for mssql. --- lib/dialects/mssql/blocks.js | 59 ++++++++++++++ lib/dialects/mssql/index.js | 124 +++++++++--------------------- lib/dialects/mssql/templates.js | 131 ++++++++++++++++++++++++++++++++ tests/6_dialects/1_mssql.js | 60 +++++++++++++++ 4 files changed, 287 insertions(+), 87 deletions(-) create mode 100644 lib/dialects/mssql/blocks.js create mode 100644 lib/dialects/mssql/templates.js create mode 100644 tests/6_dialects/1_mssql.js diff --git a/lib/dialects/mssql/blocks.js b/lib/dialects/mssql/blocks.js new file mode 100644 index 0000000..102f3c5 --- /dev/null +++ b/lib/dialects/mssql/blocks.js @@ -0,0 +1,59 @@ +'use strict'; + +var _ = require('underscore'); + +module.exports = function(dialect) { + dialect.blocks.set('limit', function(params) { + return (!isNaN(params.offset)) ? '' : 'top(' + dialect.builder._pushValue(params.limit) + ')'; + }); + + dialect.blocks.set('offset', function(params) { + var pre = (!params.sort) ? 'order by 1 ' : ''; + if (params.limit) { + var str = pre + 'offset ' + dialect.builder._pushValue(params.offset); + str += ' rows fetch next ' + dialect.builder._pushValue(params.limit) + ' rows only'; + return str; + }else { + return pre + 'OFFSET ' + dialect.builder._pushValue(params.offset) + ' rows'; + } + }); + + dialect.blocks.set('returning', function(params) { + var result = dialect.buildBlock('fields', {fields: params.returning}); + + if (result) result = 'output ' + result; + + return result; + }); + + dialect.blocks.set('insert:values', function(params) { + var values = params.values; + + if (!_.isArray(values)) values = [values]; + + var fields = params.fields || _(values) + .chain() + .map(function(row) { + return _(row).keys(); + }) + .flatten() + .uniq() + .value(); + + return dialect.buildTemplate('insertValues', { + fields: fields, + returning: params.returning || undefined, + values: _(values).map(function(row) { + return _(fields).map(function(field) { + return dialect.buildBlock('value', {value: row[field]}); + }); + }) + }); + }); + + dialect.blocks.add('insertValues:values', function(params) { + return _(params.values).map(function(row) { + return '(' + row.join(', ') + ')'; + }).join(', '); + }); +}; diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index 46f49cc..a8bddd8 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -3,97 +3,47 @@ var BaseDialect = require('../base'); var _ = require('underscore'); var util = require('util'); +var templatesInit = require('./templates'); +var blocksInit = require('./blocks'); var templateChecks = require('../../utils/templateChecks'); var Dialect = module.exports = function(builder) { - builder.options.valuesPrefix = '@'; - - builder._pushValue = function(value) { - if (_.isUndefined(value) || _.isNull(value)) { - return 'null'; - } else if (_.isBoolean(value)) { - return String(Number(value)); - } else if (_.isNumber(value)) { - return String(value); - } else if (_.isString(value) || _.isDate(value)) { - if (this.options.separatedValues) { - var placeholder = this._getPlaceholder(); - if (this.options.namedValues) { - this._values[placeholder] = value; - } else { - this._values.push(value); - } - - return this._wrapPlaceholder(placeholder); - } else { - if (_.isDate(value)) value = value.toISOString(); - - return '\'' + value + '\''; - } - } else { - throw new Error('Wrong value type "' + (typeof value) + '"'); - } - }; - - BaseDialect.call(this, builder); - - this.blocks.set('limit', function(params) { - return (!isNaN(params.offset)) ? '' : 'TOP(' + builder._pushValue(params.limit) + ')'; - }); - - this.blocks.set('offset', function(params) { - var pre = (!params.sort) ? 'ORDER BY 1 ' : ''; - if (params.limit) { - var str = pre + 'OFFSET ' + builder._pushValue(params.offset); - str += ' ROWS FETCH NEXT ' + builder._pushValue(params.limit) + ' ROWS ONLY'; - return str; - }else { - return pre + 'OFFSET ' + builder._pushValue(params.offset) + ' ROWS'; - } - }); - - this.templates.set('select', { - pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + - 'from {from} {table} {query} {select} {expression} {alias} ' + - '{join} {condition} {group} {having} {sort} {offset}', - defaults: { - fields: {} - }, - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); - - templateChecks.propType(type, params, 'distinct', 'boolean'); - - templateChecks.propType(type, params, 'fields', ['array', 'object']); - - templateChecks.propType(type, params, 'from', ['string', 'array', 'object']); - - templateChecks.atLeastOneOfProps(type, params, ['table', 'query', 'select', 'expression']); - templateChecks.onlyOneOfProps(type, params, ['table', 'query', 'select', 'expression']); - - templateChecks.propType(type, params, 'table', 'string'); - templateChecks.propType(type, params, 'query', 'object'); - templateChecks.propType(type, params, 'select', 'object'); - templateChecks.propType(type, params, 'expression', ['string', 'object']); - - templateChecks.propType(type, params, 'alias', ['string', 'object']); - - templateChecks.propType(type, params, 'join', ['array', 'object']); - - templateChecks.propType(type, params, 'condition', ['array', 'object']); - templateChecks.propType(type, params, 'having', ['array', 'object']); - - templateChecks.propType(type, params, 'group', ['string', 'array']); - - templateChecks.propType(type, params, 'sort', ['string', 'array', 'object']); - - templateChecks.propType(type, params, 'offset', ['number', 'string']); - templateChecks.propType(type, params, 'limit', ['number', 'string']); - } - }); + builder._pushValue = function(value) { + if (_.isUndefined(value) || _.isNull(value)) { + return 'null'; + } else if (_.isBoolean(value)) { + return String(Number(value)); + } else if (_.isNumber(value)) { + return String(value); + } else if (_.isString(value) || _.isDate(value)) { + if (this.options.separatedValues) { + var placeholder = this._getPlaceholder(); + + if (this.options.namedValues) { + this._values[placeholder] = value; + } else { + this._values.push(value); + } + + return this._wrapPlaceholder(placeholder); + } else { + if (_.isDate(value)) value = value.toISOString(); + + return '\'' + value + '\''; + } + } else { + throw new Error('Wrong value type "' + (typeof value) + '"'); + } + }; + + BaseDialect.call(this, builder); + + // init templates + templatesInit(this); + + // init blocks + blocksInit(this); }; diff --git a/lib/dialects/mssql/templates.js b/lib/dialects/mssql/templates.js new file mode 100644 index 0000000..0330749 --- /dev/null +++ b/lib/dialects/mssql/templates.js @@ -0,0 +1,131 @@ +'use strict'; + +var _ = require('underscore'); +var templateChecks = require('../../utils/templateChecks'); +var orRegExp = /^(rollback|abort|replace|fail|ignore)$/i; + +module.exports = function(dialect) { + dialect.templates.set('select', { + pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + + 'from {from} {table} {query} {select} {expression} {alias} ' + + '{join} {condition} {group} {having} {sort} {offset}', + defaults: { + fields: {} + }, + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); + + templateChecks.propType(type, params, 'distinct', 'boolean'); + + templateChecks.propType(type, params, 'fields', ['array', 'object']); + + templateChecks.propType(type, params, 'from', ['string', 'array', 'object']); + + templateChecks.atLeastOneOfProps(type, params, ['table', 'query', 'select', 'expression']); + templateChecks.onlyOneOfProps(type, params, ['table', 'query', 'select', 'expression']); + + templateChecks.propType(type, params, 'table', 'string'); + templateChecks.propType(type, params, 'query', 'object'); + templateChecks.propType(type, params, 'select', 'object'); + templateChecks.propType(type, params, 'expression', ['string', 'object']); + + templateChecks.propType(type, params, 'alias', ['string', 'object']); + + templateChecks.propType(type, params, 'join', ['array', 'object']); + + templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'having', ['array', 'object']); + + templateChecks.propType(type, params, 'group', ['string', 'array']); + + templateChecks.propType(type, params, 'sort', ['string', 'array', 'object']); + + templateChecks.propType(type, params, 'offset', ['number', 'string']); + templateChecks.propType(type, params, 'limit', ['number', 'string']); + } + }); + + + dialect.templates.add('insert', { + pattern: '{with} {withRecursive} insert {or} into {table} {values} ' + + '{condition}', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); + + templateChecks.propType(type, params, 'or', 'string'); + templateChecks.propMatch(type, params, 'or', orRegExp); + + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); + + templateChecks.requiredProp(type, params, 'values'); + templateChecks.propType(type, params, 'values', ['array', 'object']); + + templateChecks.propType(type, params, 'condition', ['array', 'object']); + + } + }); + + dialect.templates.add('insertValues', { + pattern: '({fields}) {returning} values {values}', + validate: function(type, params) { + templateChecks.requiredProp('values', params, 'fields'); + templateChecks.propType('values', params, 'fields', 'array'); + templateChecks.minPropLength('values', params, 'fields', 1); + + templateChecks.propType(type, params, 'returning', ['array', 'object']); + + templateChecks.requiredProp('values', params, 'values'); + templateChecks.propType('values', params, 'values', 'array'); + templateChecks.minPropLength('values', params, 'values', 1); + } + }); + + dialect.templates.add('update', { + pattern: '{with} {withRecursive} update {or} {table} {alias} {modifier} {returning} {condition} ', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); + + templateChecks.propType(type, params, 'or', 'string'); + templateChecks.propMatch(type, params, 'or', orRegExp); + + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); + + templateChecks.propType(type, params, 'returning', ['array', 'object']); + + templateChecks.propType(type, params, 'alias', 'string'); + + templateChecks.requiredProp(type, params, 'modifier'); + templateChecks.propType(type, params, 'modifier', 'object'); + + templateChecks.propType(type, params, 'condition', ['array', 'object']); + + } + }); + + dialect.templates.add('remove', { + pattern: '{with} {withRecursive} delete from {table} {returning} {alias} {condition} ', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); + + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); + + templateChecks.propType(type, params, 'returning', ['array', 'object']); + + templateChecks.propType(type, params, 'alias', 'string'); + + templateChecks.propType(type, params, 'condition', ['array', 'object']); + + } + }); +}; diff --git a/tests/6_dialects/1_mssql.js b/tests/6_dialects/1_mssql.js new file mode 100644 index 0000000..41b69da --- /dev/null +++ b/tests/6_dialects/1_mssql.js @@ -0,0 +1,60 @@ +'use strict'; + +var jsonSql = require('../../lib')({ + dialect: 'mssql', + namedValues: false +}); +var expect = require('chai').expect; + +describe('MSSQL dialect', function() { + describe('limit', function() { + it('should be ok with `limit` property', function() { + var result = jsonSql.build({ + table: 'test', + fields: ['user'], + limit: 1, + condition: { + 'name': {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('select top(1) "user" from "test" where "name" = $1;'); + }); + + it('should be ok with `limit` and `offset` properties', function() { + var result = jsonSql.build({ + table: 'test', + fields: ['user'], + limit: 4, + offset: 2, + condition: { + 'name': {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('select "user" from "test" where "name" = $1 order by 1 offset 2 rows fetch next 4 rows only;'); + }); + }); + describe('returning', function() { + it('should be ok with `remove` type', function() { + var result = jsonSql.build({ + type: 'remove', + table: 'test', + returning: ['DELETED.*'], + condition: { + Description: {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('delete from "test" output "DELETED".* where "Description" = $1;'); + }); + it('should be ok with `insert` type', function() { + var result = jsonSql.build({ + type: 'insert', + table: 'test', + returning: ['INSERTED.*'], + values: { + Description: 'test', + } + }); + expect(result.query).to.be.equal('insert into "test" ("Description") output "INSERTED".* values ($1);'); + }); + }); +}); From 0262ad1d4c33e0cebacfa65c883f2b0d7b476df2 Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Wed, 10 May 2017 16:33:48 +0200 Subject: [PATCH 6/8] Fixed code style --- lib/dialects/mssql/blocks.js | 54 +++++++++---------- lib/dialects/mssql/templates.js | 87 +++++++++++++++---------------- tests/6_dialects/1_mssql.js | 92 ++++++++++++++++----------------- 3 files changed, 116 insertions(+), 117 deletions(-) diff --git a/lib/dialects/mssql/blocks.js b/lib/dialects/mssql/blocks.js index 102f3c5..a89b4c6 100644 --- a/lib/dialects/mssql/blocks.js +++ b/lib/dialects/mssql/blocks.js @@ -19,41 +19,41 @@ module.exports = function(dialect) { }); dialect.blocks.set('returning', function(params) { - var result = dialect.buildBlock('fields', {fields: params.returning}); + var result = dialect.buildBlock('fields', {fields: params.returning}); - if (result) result = 'output ' + result; + if (result) result = 'output ' + result; - return result; - }); + return result; + }); dialect.blocks.set('insert:values', function(params) { - var values = params.values; + var values = params.values; - if (!_.isArray(values)) values = [values]; + if (!_.isArray(values)) values = [values]; - var fields = params.fields || _(values) - .chain() - .map(function(row) { - return _(row).keys(); - }) - .flatten() - .uniq() - .value(); + var fields = params.fields || _(values) + .chain() + .map(function(row) { + return _(row).keys(); + }) + .flatten() + .uniq() + .value(); - return dialect.buildTemplate('insertValues', { - fields: fields, + return dialect.buildTemplate('insertValues', { + fields: fields, returning: params.returning || undefined, - values: _(values).map(function(row) { - return _(fields).map(function(field) { - return dialect.buildBlock('value', {value: row[field]}); - }); - }) - }); - }); + values: _(values).map(function(row) { + return _(fields).map(function(field) { + return dialect.buildBlock('value', {value: row[field]}); + }); + }) + }); + }); dialect.blocks.add('insertValues:values', function(params) { - return _(params.values).map(function(row) { - return '(' + row.join(', ') + ')'; - }).join(', '); - }); + return _(params.values).map(function(row) { + return '(' + row.join(', ') + ')'; + }).join(', '); + }); }; diff --git a/lib/dialects/mssql/templates.js b/lib/dialects/mssql/templates.js index 0330749..4fba772 100644 --- a/lib/dialects/mssql/templates.js +++ b/lib/dialects/mssql/templates.js @@ -47,28 +47,27 @@ module.exports = function(dialect) { } }); - dialect.templates.add('insert', { - pattern: '{with} {withRecursive} insert {or} into {table} {values} ' + - '{condition}', - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + pattern: '{with} {withRecursive} insert {or} into {table} {values} ' + + '{condition}', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.propType(type, params, 'or', 'string'); - templateChecks.propMatch(type, params, 'or', orRegExp); + templateChecks.propType(type, params, 'or', 'string'); + templateChecks.propMatch(type, params, 'or', orRegExp); - templateChecks.requiredProp(type, params, 'table'); - templateChecks.propType(type, params, 'table', 'string'); + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); - templateChecks.requiredProp(type, params, 'values'); - templateChecks.propType(type, params, 'values', ['array', 'object']); + templateChecks.requiredProp(type, params, 'values'); + templateChecks.propType(type, params, 'values', ['array', 'object']); - templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); - } - }); + } + }); dialect.templates.add('insertValues', { pattern: '({fields}) {returning} values {values}', @@ -85,47 +84,47 @@ module.exports = function(dialect) { } }); - dialect.templates.add('update', { - pattern: '{with} {withRecursive} update {or} {table} {alias} {modifier} {returning} {condition} ', - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + dialect.templates.add('update', { + pattern: '{with} {withRecursive} update {or} {table} {alias} {modifier} {returning} {condition} ', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.propType(type, params, 'or', 'string'); - templateChecks.propMatch(type, params, 'or', orRegExp); + templateChecks.propType(type, params, 'or', 'string'); + templateChecks.propMatch(type, params, 'or', orRegExp); - templateChecks.requiredProp(type, params, 'table'); - templateChecks.propType(type, params, 'table', 'string'); + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); templateChecks.propType(type, params, 'returning', ['array', 'object']); - templateChecks.propType(type, params, 'alias', 'string'); + templateChecks.propType(type, params, 'alias', 'string'); - templateChecks.requiredProp(type, params, 'modifier'); - templateChecks.propType(type, params, 'modifier', 'object'); + templateChecks.requiredProp(type, params, 'modifier'); + templateChecks.propType(type, params, 'modifier', 'object'); - templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); - } - }); + } + }); - dialect.templates.add('remove', { - pattern: '{with} {withRecursive} delete from {table} {returning} {alias} {condition} ', - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + dialect.templates.add('remove', { + pattern: '{with} {withRecursive} delete from {table} {returning} {alias} {condition} ', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.requiredProp(type, params, 'table'); - templateChecks.propType(type, params, 'table', 'string'); + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); templateChecks.propType(type, params, 'returning', ['array', 'object']); - templateChecks.propType(type, params, 'alias', 'string'); + templateChecks.propType(type, params, 'alias', 'string'); - templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); - } - }); + } + }); }; diff --git a/tests/6_dialects/1_mssql.js b/tests/6_dialects/1_mssql.js index 41b69da..d3ec491 100644 --- a/tests/6_dialects/1_mssql.js +++ b/tests/6_dialects/1_mssql.js @@ -1,60 +1,60 @@ 'use strict'; var jsonSql = require('../../lib')({ - dialect: 'mssql', - namedValues: false + dialect: 'mssql', + namedValues: false }); var expect = require('chai').expect; describe('MSSQL dialect', function() { - describe('limit', function() { - it('should be ok with `limit` property', function() { - var result = jsonSql.build({ - table: 'test', - fields: ['user'], + describe('limit', function() { + it('should be ok with `limit` property', function() { + var result = jsonSql.build({ + table: 'test', + fields: ['user'], limit: 1, - condition: { - 'name': {$eq: 'test'} - } - }); - expect(result.query).to.be.equal('select top(1) "user" from "test" where "name" = $1;'); - }); + condition: { + 'name': {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('select top(1) "user" from "test" where "name" = $1;'); + }); it('should be ok with `limit` and `offset` properties', function() { - var result = jsonSql.build({ - table: 'test', - fields: ['user'], + var result = jsonSql.build({ + table: 'test', + fields: ['user'], limit: 4, offset: 2, - condition: { - 'name': {$eq: 'test'} - } - }); - expect(result.query).to.be.equal('select "user" from "test" where "name" = $1 order by 1 offset 2 rows fetch next 4 rows only;'); - }); + condition: { + 'name': {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('select "user" from "test" where "name" = $1 order by 1 offset 2 rows fetch next 4 rows only;'); + }); + }); + describe('returning', function() { + it('should be ok with `remove` type', function() { + var result = jsonSql.build({ + type: 'remove', + table: 'test', + returning: ['DELETED.*'], + condition: { + Description: {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('delete from "test" output "DELETED".* where "Description" = $1;'); + }); + it('should be ok with `insert` type', function() { + var result = jsonSql.build({ + type: 'insert', + table: 'test', + returning: ['INSERTED.*'], + values: { + Description: 'test', + } + }); + expect(result.query).to.be.equal('insert into "test" ("Description") output "INSERTED".* values ($1);'); + }); }); - describe('returning', function() { - it('should be ok with `remove` type', function() { - var result = jsonSql.build({ - type: 'remove', - table: 'test', - returning: ['DELETED.*'], - condition: { - Description: {$eq: 'test'} - } - }); - expect(result.query).to.be.equal('delete from "test" output "DELETED".* where "Description" = $1;'); - }); - it('should be ok with `insert` type', function() { - var result = jsonSql.build({ - type: 'insert', - table: 'test', - returning: ['INSERTED.*'], - values: { - Description: 'test', - } - }); - expect(result.query).to.be.equal('insert into "test" ("Description") output "INSERTED".* values ($1);'); - }); - }); }); From df972bc8b54b33abe74cbf3adbf8cc14608a4d08 Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Thu, 11 May 2017 10:26:25 +0200 Subject: [PATCH 7/8] Fixed code style Replaced spaces with tabs Reverted package.json --- lib/dialects/mssql/blocks.js | 106 +++++++++---------- lib/dialects/mssql/index.js | 71 +++++++------ lib/dialects/mssql/templates.js | 178 ++++++++++++++++---------------- lib/utils/object.js | 2 +- package.json | 4 +- tests/6_dialects/1_mssql.js | 105 ++++++++++--------- 6 files changed, 234 insertions(+), 232 deletions(-) diff --git a/lib/dialects/mssql/blocks.js b/lib/dialects/mssql/blocks.js index a89b4c6..163fc5c 100644 --- a/lib/dialects/mssql/blocks.js +++ b/lib/dialects/mssql/blocks.js @@ -3,57 +3,57 @@ var _ = require('underscore'); module.exports = function(dialect) { - dialect.blocks.set('limit', function(params) { - return (!isNaN(params.offset)) ? '' : 'top(' + dialect.builder._pushValue(params.limit) + ')'; - }); - - dialect.blocks.set('offset', function(params) { - var pre = (!params.sort) ? 'order by 1 ' : ''; - if (params.limit) { - var str = pre + 'offset ' + dialect.builder._pushValue(params.offset); - str += ' rows fetch next ' + dialect.builder._pushValue(params.limit) + ' rows only'; - return str; - }else { - return pre + 'OFFSET ' + dialect.builder._pushValue(params.offset) + ' rows'; - } - }); - - dialect.blocks.set('returning', function(params) { - var result = dialect.buildBlock('fields', {fields: params.returning}); - - if (result) result = 'output ' + result; - - return result; - }); - - dialect.blocks.set('insert:values', function(params) { - var values = params.values; - - if (!_.isArray(values)) values = [values]; - - var fields = params.fields || _(values) - .chain() - .map(function(row) { - return _(row).keys(); - }) - .flatten() - .uniq() - .value(); - - return dialect.buildTemplate('insertValues', { - fields: fields, - returning: params.returning || undefined, - values: _(values).map(function(row) { - return _(fields).map(function(field) { - return dialect.buildBlock('value', {value: row[field]}); - }); - }) - }); - }); - - dialect.blocks.add('insertValues:values', function(params) { - return _(params.values).map(function(row) { - return '(' + row.join(', ') + ')'; - }).join(', '); - }); + dialect.blocks.set('limit', function(params) { + return (!isNaN(params.offset)) ? '' : 'top(' + dialect.builder._pushValue(params.limit) + ')'; + }); + + dialect.blocks.set('offset', function(params) { + var pre = (!params.sort) ? 'order by 1 ' : ''; + if (params.limit) { + var str = pre + 'offset ' + dialect.builder._pushValue(params.offset); + str += ' rows fetch next ' + dialect.builder._pushValue(params.limit) + ' rows only'; + return str; + }else { + return pre + 'OFFSET ' + dialect.builder._pushValue(params.offset) + ' rows'; + } + }); + + dialect.blocks.set('returning', function(params) { + var result = dialect.buildBlock('fields', {fields: params.returning}); + + if (result) result = 'output ' + result; + + return result; + }); + + dialect.blocks.set('insert:values', function(params) { + var values = params.values; + + if (!_.isArray(values)) values = [values]; + + var fields = params.fields || _(values) + .chain() + .map(function(row) { + return _(row).keys(); + }) + .flatten() + .uniq() + .value(); + + return dialect.buildTemplate('insertValues', { + fields: fields, + returning: params.returning || undefined, + values: _(values).map(function(row) { + return _(fields).map(function(field) { + return dialect.buildBlock('value', {value: row[field]}); + }); + }) + }); + }); + + dialect.blocks.add('insertValues:values', function(params) { + return _(params.values).map(function(row) { + return '(' + row.join(', ') + ')'; + }).join(', '); + }); }; diff --git a/lib/dialects/mssql/index.js b/lib/dialects/mssql/index.js index a8bddd8..569d6d8 100644 --- a/lib/dialects/mssql/index.js +++ b/lib/dialects/mssql/index.js @@ -5,45 +5,44 @@ var _ = require('underscore'); var util = require('util'); var templatesInit = require('./templates'); var blocksInit = require('./blocks'); -var templateChecks = require('../../utils/templateChecks'); var Dialect = module.exports = function(builder) { - builder._pushValue = function(value) { - if (_.isUndefined(value) || _.isNull(value)) { - return 'null'; - } else if (_.isBoolean(value)) { - return String(Number(value)); - } else if (_.isNumber(value)) { - return String(value); - } else if (_.isString(value) || _.isDate(value)) { - if (this.options.separatedValues) { - var placeholder = this._getPlaceholder(); - - if (this.options.namedValues) { - this._values[placeholder] = value; - } else { - this._values.push(value); - } - - return this._wrapPlaceholder(placeholder); - } else { - if (_.isDate(value)) value = value.toISOString(); - - return '\'' + value + '\''; - } - } else { - throw new Error('Wrong value type "' + (typeof value) + '"'); - } - }; - - BaseDialect.call(this, builder); - - // init templates - templatesInit(this); - - // init blocks - blocksInit(this); + builder._pushValue = function(value) { + if (_.isUndefined(value) || _.isNull(value)) { + return 'null'; + } else if (_.isBoolean(value)) { + return String(Number(value)); + } else if (_.isNumber(value)) { + return String(value); + } else if (_.isString(value) || _.isDate(value)) { + if (this.options.separatedValues) { + var placeholder = this._getPlaceholder(); + + if (this.options.namedValues) { + this._values[placeholder] = value; + } else { + this._values.push(value); + } + + return this._wrapPlaceholder(placeholder); + } else { + if (_.isDate(value)) value = value.toISOString(); + + return '\'' + value + '\''; + } + } else { + throw new Error('Wrong value type "' + (typeof value) + '"'); + } + }; + + BaseDialect.call(this, builder); + + // init templates + templatesInit(this); + + // init blocks + blocksInit(this); }; diff --git a/lib/dialects/mssql/templates.js b/lib/dialects/mssql/templates.js index 4fba772..79dbd0f 100644 --- a/lib/dialects/mssql/templates.js +++ b/lib/dialects/mssql/templates.js @@ -1,130 +1,130 @@ 'use strict'; -var _ = require('underscore'); var templateChecks = require('../../utils/templateChecks'); var orRegExp = /^(rollback|abort|replace|fail|ignore)$/i; module.exports = function(dialect) { - dialect.templates.set('select', { - pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + - 'from {from} {table} {query} {select} {expression} {alias} ' + - '{join} {condition} {group} {having} {sort} {offset}', - defaults: { - fields: {} - }, - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + dialect.templates.set('select', { + pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + + 'from {from} {table} {query} {select} {expression} {alias} ' + + '{join} {condition} {group} {having} {sort} {offset}', + defaults: { + fields: {} + }, + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.propType(type, params, 'distinct', 'boolean'); + templateChecks.propType(type, params, 'distinct', 'boolean'); - templateChecks.propType(type, params, 'fields', ['array', 'object']); + templateChecks.propType(type, params, 'fields', ['array', 'object']); - templateChecks.propType(type, params, 'from', ['string', 'array', 'object']); + templateChecks.propType(type, params, 'from', ['string', 'array', 'object']); - templateChecks.atLeastOneOfProps(type, params, ['table', 'query', 'select', 'expression']); - templateChecks.onlyOneOfProps(type, params, ['table', 'query', 'select', 'expression']); + templateChecks.atLeastOneOfProps(type, params, ['table', 'query', 'select', 'expression']); + templateChecks.onlyOneOfProps(type, params, ['table', 'query', 'select', 'expression']); - templateChecks.propType(type, params, 'table', 'string'); - templateChecks.propType(type, params, 'query', 'object'); - templateChecks.propType(type, params, 'select', 'object'); - templateChecks.propType(type, params, 'expression', ['string', 'object']); + templateChecks.propType(type, params, 'table', 'string'); + templateChecks.propType(type, params, 'query', 'object'); + templateChecks.propType(type, params, 'select', 'object'); + templateChecks.propType(type, params, 'expression', ['string', 'object']); - templateChecks.propType(type, params, 'alias', ['string', 'object']); + templateChecks.propType(type, params, 'alias', ['string', 'object']); - templateChecks.propType(type, params, 'join', ['array', 'object']); + templateChecks.propType(type, params, 'join', ['array', 'object']); - templateChecks.propType(type, params, 'condition', ['array', 'object']); - templateChecks.propType(type, params, 'having', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'having', ['array', 'object']); - templateChecks.propType(type, params, 'group', ['string', 'array']); + templateChecks.propType(type, params, 'group', ['string', 'array']); - templateChecks.propType(type, params, 'sort', ['string', 'array', 'object']); + templateChecks.propType(type, params, 'sort', ['string', 'array', 'object']); - templateChecks.propType(type, params, 'offset', ['number', 'string']); - templateChecks.propType(type, params, 'limit', ['number', 'string']); - } - }); + templateChecks.propType(type, params, 'offset', ['number', 'string']); + templateChecks.propType(type, params, 'limit', ['number', 'string']); + } + }); - dialect.templates.add('insert', { - pattern: '{with} {withRecursive} insert {or} into {table} {values} ' + - '{condition}', - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + dialect.templates.add('insert', { + pattern: '{with} {withRecursive} insert {or} into {table} {values} ' + + '{condition}', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.propType(type, params, 'or', 'string'); - templateChecks.propMatch(type, params, 'or', orRegExp); + templateChecks.propType(type, params, 'or', 'string'); + templateChecks.propMatch(type, params, 'or', orRegExp); - templateChecks.requiredProp(type, params, 'table'); - templateChecks.propType(type, params, 'table', 'string'); + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); - templateChecks.requiredProp(type, params, 'values'); - templateChecks.propType(type, params, 'values', ['array', 'object']); + templateChecks.requiredProp(type, params, 'values'); + templateChecks.propType(type, params, 'values', ['array', 'object']); - templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); - } - }); + } + }); - dialect.templates.add('insertValues', { - pattern: '({fields}) {returning} values {values}', - validate: function(type, params) { - templateChecks.requiredProp('values', params, 'fields'); - templateChecks.propType('values', params, 'fields', 'array'); - templateChecks.minPropLength('values', params, 'fields', 1); + dialect.templates.add('insertValues', { + pattern: '({fields}) {returning} values {values}', + validate: function(type, params) { + templateChecks.requiredProp('values', params, 'fields'); + templateChecks.propType('values', params, 'fields', 'array'); + templateChecks.minPropLength('values', params, 'fields', 1); - templateChecks.propType(type, params, 'returning', ['array', 'object']); + templateChecks.propType(type, params, 'returning', ['array', 'object']); - templateChecks.requiredProp('values', params, 'values'); - templateChecks.propType('values', params, 'values', 'array'); - templateChecks.minPropLength('values', params, 'values', 1); - } - }); + templateChecks.requiredProp('values', params, 'values'); + templateChecks.propType('values', params, 'values', 'array'); + templateChecks.minPropLength('values', params, 'values', 1); + } + }); - dialect.templates.add('update', { - pattern: '{with} {withRecursive} update {or} {table} {alias} {modifier} {returning} {condition} ', - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + dialect.templates.add('update', { + pattern: '{with} {withRecursive} update {or} {table} {alias} {modifier} {returning} ' + + '{condition} ', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.propType(type, params, 'or', 'string'); - templateChecks.propMatch(type, params, 'or', orRegExp); + templateChecks.propType(type, params, 'or', 'string'); + templateChecks.propMatch(type, params, 'or', orRegExp); - templateChecks.requiredProp(type, params, 'table'); - templateChecks.propType(type, params, 'table', 'string'); + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); - templateChecks.propType(type, params, 'returning', ['array', 'object']); + templateChecks.propType(type, params, 'returning', ['array', 'object']); - templateChecks.propType(type, params, 'alias', 'string'); + templateChecks.propType(type, params, 'alias', 'string'); - templateChecks.requiredProp(type, params, 'modifier'); - templateChecks.propType(type, params, 'modifier', 'object'); + templateChecks.requiredProp(type, params, 'modifier'); + templateChecks.propType(type, params, 'modifier', 'object'); - templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); - } - }); + } + }); - dialect.templates.add('remove', { - pattern: '{with} {withRecursive} delete from {table} {returning} {alias} {condition} ', - validate: function(type, params) { - templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); - templateChecks.propType(type, params, 'with', 'object'); - templateChecks.propType(type, params, 'withRecursive', 'object'); + dialect.templates.add('remove', { + pattern: '{with} {withRecursive} delete from {table} {returning} {alias} {condition} ', + validate: function(type, params) { + templateChecks.onlyOneOfProps(type, params, ['with', 'withRecursive']); + templateChecks.propType(type, params, 'with', 'object'); + templateChecks.propType(type, params, 'withRecursive', 'object'); - templateChecks.requiredProp(type, params, 'table'); - templateChecks.propType(type, params, 'table', 'string'); + templateChecks.requiredProp(type, params, 'table'); + templateChecks.propType(type, params, 'table', 'string'); - templateChecks.propType(type, params, 'returning', ['array', 'object']); + templateChecks.propType(type, params, 'returning', ['array', 'object']); - templateChecks.propType(type, params, 'alias', 'string'); + templateChecks.propType(type, params, 'alias', 'string'); - templateChecks.propType(type, params, 'condition', ['array', 'object']); + templateChecks.propType(type, params, 'condition', ['array', 'object']); - } - }); + } + }); }; diff --git a/lib/utils/object.js b/lib/utils/object.js index 6c13319..e31215d 100644 --- a/lib/utils/object.js +++ b/lib/utils/object.js @@ -24,4 +24,4 @@ exports.isSimpleValue = function(value) { exports.isObjectObject = function(obj) { return _.isObject(obj) && Object.prototype.toString.call(obj) === '[object Object]'; -} +}; diff --git a/package.json b/package.json index 166b77e..cab8336 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "json-sql", "description": "node.js json to sql queries mapper", - "version": "0.3.11", + "version": "0.3.10", "author": "Artem Zhukov ", "license": "MIT", "repository": { @@ -18,7 +18,7 @@ "database" ], "dependencies": { - "underscore": "1.8.3" + "underscore": "1.8.2" }, "devDependencies": { "chai": "2.2.0", diff --git a/tests/6_dialects/1_mssql.js b/tests/6_dialects/1_mssql.js index d3ec491..625ef91 100644 --- a/tests/6_dialects/1_mssql.js +++ b/tests/6_dialects/1_mssql.js @@ -1,60 +1,63 @@ 'use strict'; var jsonSql = require('../../lib')({ - dialect: 'mssql', - namedValues: false + dialect: 'mssql', + namedValues: false }); var expect = require('chai').expect; describe('MSSQL dialect', function() { - describe('limit', function() { - it('should be ok with `limit` property', function() { - var result = jsonSql.build({ - table: 'test', - fields: ['user'], - limit: 1, - condition: { - 'name': {$eq: 'test'} - } - }); - expect(result.query).to.be.equal('select top(1) "user" from "test" where "name" = $1;'); - }); + describe('limit', function() { + it('should be ok with `limit` property', function() { + var result = jsonSql.build({ + table: 'test', + fields: ['user'], + limit: 1, + condition: { + 'name': {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('select top(1) "user" from "test" where "name" = $1;'); + }); - it('should be ok with `limit` and `offset` properties', function() { - var result = jsonSql.build({ - table: 'test', - fields: ['user'], - limit: 4, - offset: 2, - condition: { - 'name': {$eq: 'test'} - } - }); - expect(result.query).to.be.equal('select "user" from "test" where "name" = $1 order by 1 offset 2 rows fetch next 4 rows only;'); - }); - }); - describe('returning', function() { - it('should be ok with `remove` type', function() { - var result = jsonSql.build({ - type: 'remove', - table: 'test', - returning: ['DELETED.*'], - condition: { - Description: {$eq: 'test'} - } - }); - expect(result.query).to.be.equal('delete from "test" output "DELETED".* where "Description" = $1;'); - }); - it('should be ok with `insert` type', function() { - var result = jsonSql.build({ - type: 'insert', - table: 'test', - returning: ['INSERTED.*'], - values: { - Description: 'test', - } - }); - expect(result.query).to.be.equal('insert into "test" ("Description") output "INSERTED".* values ($1);'); - }); - }); + it('should be ok with `limit` and `offset` properties', function() { + var result = jsonSql.build({ + table: 'test', + fields: ['user'], + limit: 4, + offset: 2, + condition: { + 'name': {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('select "user" from "test" where "name" = $1 order by 1' + + ' offset 2 rows fetch next 4 rows only;'); + }); + }); + describe('returning', function() { + it('should be ok with `remove` type', function() { + var result = jsonSql.build({ + type: 'remove', + table: 'test', + returning: ['DELETED.*'], + condition: { + Description: {$eq: 'test'} + } + }); + expect(result.query).to.be.equal('delete from "test" output "DELETED".* where ' + + '"Description" = $1;'); + }); + it('should be ok with `insert` type', function() { + var result = jsonSql.build({ + type: 'insert', + table: 'test', + returning: ['INSERTED.*'], + values: { + Description: 'test', + } + }); + expect(result.query).to.be.equal('insert into "test" ("Description") output ' + + '"INSERTED".* values ($1);'); + }); + }); }); From 6124cfc91beb39f837d108636e1f3a04eca4781e Mon Sep 17 00:00:00 2001 From: Allan Amstadt Date: Mon, 10 Dec 2018 16:34:31 +0100 Subject: [PATCH 8/8] Fixed MSSQL Distinct not working --- lib/dialects/mssql/templates.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dialects/mssql/templates.js b/lib/dialects/mssql/templates.js index 79dbd0f..bbda467 100644 --- a/lib/dialects/mssql/templates.js +++ b/lib/dialects/mssql/templates.js @@ -5,7 +5,7 @@ var orRegExp = /^(rollback|abort|replace|fail|ignore)$/i; module.exports = function(dialect) { dialect.templates.set('select', { - pattern: '{with} {withRecursive} select {limit} {distinct} {fields} ' + + pattern: '{with} {withRecursive} select {distinct} {limit} {fields} ' + 'from {from} {table} {query} {select} {expression} {alias} ' + '{join} {condition} {group} {having} {sort} {offset}', defaults: {