Skip to content

Commit 3048af0

Browse files
committed
new "expression" clause and object aliases added
1 parent 1d7fe4b commit 3048af0

File tree

4 files changed

+100
-13
lines changed

4 files changed

+100
-13
lines changed

lib/dialects/base/blocks.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,36 @@ module.exports = function(dialect) {
128128
return this.dialect._wrapIdentifier(params.table);
129129
});
130130

131+
dialect.blocks.add('expression', function(params) {
132+
return params.expression;
133+
});
134+
131135
dialect.blocks.add('name', function(params) {
132136
return this.dialect._wrapIdentifier(params.name);
133137
});
134138

135139
dialect.blocks.add('alias', function(params) {
136-
return 'as ' + this.dialect._wrapIdentifier(params.alias);
140+
var self = this;
141+
142+
var result;
143+
144+
if (_.isObject(params.alias)) {
145+
if (!params.alias.name) {
146+
throw new Error('Alias `name` property is required');
147+
}
148+
149+
result = this.dialect._wrapIdentifier(params.alias.name);
150+
151+
if (_.isArray(params.alias.columns)) {
152+
result += '(' + _(params.alias.columns).map(function(column) {
153+
return self.dialect._wrapIdentifier(column);
154+
}).join(', ') + ')';
155+
}
156+
} else {
157+
result = this.dialect._wrapIdentifier(params.alias);
158+
}
159+
160+
return 'as ' + result;
137161
});
138162

139163
dialect.blocks.add('condition', function(params) {

lib/dialects/base/templates.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
var _ = require('underscore');
44

55
module.exports = function(dialect) {
6-
var availableSourceProps = ['table', 'query', 'select'];
6+
var availableSourceProps = ['table', 'query', 'select', 'expression'];
77
var availableJoinTypes = ['natural', 'cross', 'inner', 'outer', 'left', 'right', 'full', 'self'];
88
var orRegExp = /^(rollback|abort|replace|fail|ignore)$/i;
99

@@ -52,7 +52,7 @@ module.exports = function(dialect) {
5252

5353

5454
dialect.templates.add('joinItem', {
55-
pattern: '{type} join {table} {query} {select} {alias} {on}',
55+
pattern: '{type} join {table} {query} {select} {expression} {alias} {on}',
5656
validate: function(type, params) {
5757
hasOneOfProps('join', params, availableSourceProps);
5858

@@ -69,16 +69,16 @@ module.exports = function(dialect) {
6969

7070

7171
dialect.templates.add('withItem', {
72-
pattern: '{name} {fields} as {query} {select}',
72+
pattern: '{name} {fields} as {query} {select} {expression}',
7373
validate: function(type, params) {
7474
hasRequiredProp('with', params, 'name');
75-
hasOneOfProps('with', params, ['query', 'select']);
75+
hasOneOfProps('with', params, ['query', 'select', 'expression']);
7676
}
7777
});
7878

7979

8080
dialect.templates.add('fromItem', {
81-
pattern: '{table} {query} {select}',
81+
pattern: '{table} {query} {select} {expression}',
8282
validate: function(type, params) {
8383
hasOneOfProps('from', params, availableSourceProps);
8484
}
@@ -89,7 +89,7 @@ module.exports = function(dialect) {
8989

9090
dialect.templates.add('select', {
9191
pattern: '{with} select {distinct} {fields} ' +
92-
'from {from} {table} {query} {select} {alias} ' +
92+
'from {from} {table} {query} {select} {expression} {alias} ' +
9393
'{join} {condition} {group} {sort} {limit} {offset}',
9494
defaults: {
9595
fields: {}

tests/0_base.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ describe('Builder', function() {
3737
jsonSql.build({});
3838
}).to.throwError(function(e) {
3939
expect(e).to.be.a(Error);
40-
expect(e.message).to.be('Neither `table`, `query`, `select` properties are not set in ' +
41-
'`select` clause');
40+
expect(e.message).to.be('Neither `table`, `query`, `select`, `expression` properties ' +
41+
'are not set in `select` clause');
4242
});
4343
});
4444

@@ -104,7 +104,8 @@ describe('Builder', function() {
104104
});
105105
}).to.throwError(function(e) {
106106
expect(e).to.be.a(Error);
107-
expect(e.message).to.be('Neither `query`, `select` properties are not set in `with` clause');
107+
expect(e.message).to.be('Neither `query`, `select`, `expression` properties ' +
108+
'are not set in `with` clause');
108109
});
109110
});
110111

tests/1_select.js

+65-3
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ describe('Select', function() {
203203
});
204204

205205
describe('alias', function() {
206-
it('should be ok with `alias` property', function() {
206+
it('should be ok with string `alias` property', function() {
207207
var result = jsonSql.build({
208208
table: 'users',
209209
alias: 'u'
@@ -212,6 +212,57 @@ describe('Select', function() {
212212
expect(result.query).to.be('select * from "users" as "u";');
213213
expect(result.values).to.eql({});
214214
});
215+
216+
it('should throw error if object `alias` does not have `name` property', function() {
217+
expect(function() {
218+
jsonSql.build({
219+
table: 'users',
220+
alias: {}
221+
});
222+
}).to.throwError(function(e) {
223+
expect(e).to.be.an(Error);
224+
expect(e.message).to.be('Alias `name` property is required');
225+
});
226+
});
227+
228+
it('should be ok with object `alias`(`name`) property', function() {
229+
var result = jsonSql.build({
230+
table: 'users',
231+
alias: {
232+
name: 'u'
233+
}
234+
});
235+
236+
expect(result.query).to.be('select * from "users" as "u";');
237+
expect(result.values).to.eql({});
238+
});
239+
240+
it('should be ok with object `alias`(`name`, `columns`) property', function() {
241+
var result = jsonSql.build({
242+
table: 'users',
243+
alias: {
244+
name: 'u',
245+
columns: ['a', 'b']
246+
}
247+
});
248+
249+
expect(result.query).to.be('select * from "users" as "u"("a", "b");');
250+
expect(result.values).to.eql({});
251+
});
252+
});
253+
254+
describe('query', function() {
255+
it('should be ok with `query` property', function() {
256+
var result = jsonSql.build({
257+
query: {
258+
type: 'select',
259+
table: 't'
260+
}
261+
});
262+
263+
expect(result.query).to.be('select * from (select * from "t");');
264+
expect(result.values).to.eql({});
265+
});
215266
});
216267

217268
describe('select', function() {
@@ -227,6 +278,17 @@ describe('Select', function() {
227278
});
228279
});
229280

281+
describe('expression', function() {
282+
it('should be ok with `expression` property', function() {
283+
var result = jsonSql.build({
284+
expression: 'function()'
285+
});
286+
287+
expect(result.query).to.be('select * from function();');
288+
expect(result.values).to.eql({});
289+
});
290+
});
291+
230292
describe('join', function() {
231293
it('should throw error without `table`, `query` and `select` properties',
232294
function() {
@@ -237,8 +299,8 @@ describe('Select', function() {
237299
});
238300
}).to.throwError(function(e) {
239301
expect(e).to.be.a(Error);
240-
expect(e.message).to.be('Neither `table`, `query`, `select` properties are not set in ' +
241-
'`join` clause');
302+
expect(e.message).to.be('Neither `table`, `query`, `select`, `expression` properties ' +
303+
'are not set in `join` clause');
242304
});
243305
}
244306
);

0 commit comments

Comments
 (0)