Skip to content

Commit e5dc71e

Browse files
committed
fix idetifier wrapping, tests linting added
1 parent f0da682 commit e5dc71e

File tree

7 files changed

+75
-48
lines changed

7 files changed

+75
-48
lines changed

gulpfile.js

+6
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@ gulp.task('lint', function() {
1818
return gulp.src('./lib/**/*.js')
1919
.pipe(jshint())
2020
.pipe(jshint.reporter('unix'));
21+
});
22+
23+
gulp.task('lintTests', function() {
24+
return gulp.src('./tests/*.js')
25+
.pipe(jshint())
26+
.pipe(jshint.reporter('unix'));
2127
});

lib/dialects/base/index.js

+19-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
var _ = require('underscore');
34
var ValuesStore = require('../../valuesStore');
45

56
var templatesInit = require('./templates');
@@ -23,7 +24,11 @@ var Dialect = module.exports = function(builder) {
2324
modifiersInit(this);
2425
logicalOperatorsInit(this);
2526

26-
this.config.wrappedIdentifierRegexp = new RegExp(
27+
this.identifierPartsRegexp = new RegExp(
28+
'(\\' + this.config.identifierPrefix + '[^\\' + this.config.identifierSuffix + ']*\\' +
29+
this.config.identifierSuffix + '|[^\\.]+)', 'g'
30+
);
31+
this.wrappedIdentifierPartRegexp = new RegExp(
2732
'^\\' + this.config.identifierPrefix + '.*\\' + this.config.identifierSuffix + '$'
2833
);
2934
};
@@ -36,18 +41,19 @@ Dialect.prototype.config = {
3641
};
3742

3843
Dialect.prototype._wrapIdentifier = function(name) {
39-
if (name !== '*' && this.builder.options.wrappedIdentifiers &&
40-
!this.config.wrappedIdentifierRegexp.test(name)) {
41-
// try to split name by dot
42-
var nameParts = name.split('.');
43-
44-
if (nameParts.length > 2) {
45-
throw new Error('Identifier "' + name + '" contains more than one dot');
46-
} else if (nameParts.length === 2) {
47-
name = this._wrapIdentifier(nameParts[0]) + '.' + this._wrapIdentifier(nameParts[1]);
48-
} else {
49-
name = this.config.identifierPrefix + name + this.config.identifierSuffix;
50-
}
44+
if (this.builder.options.wrappedIdentifiers) {
45+
var self = this;
46+
var nameParts = name.match(this.identifierPartsRegexp);
47+
48+
return _(nameParts).map(function(namePart) {
49+
if (namePart !== '*') {
50+
if (!self.wrappedIdentifierPartRegexp.test(namePart)) {
51+
namePart = self.config.identifierPrefix + namePart + self.config.identifierSuffix;
52+
}
53+
}
54+
55+
return namePart;
56+
}).join('.');
5157
}
5258

5359
return name;

lib/dialects/postgresql/index.js

+2-9
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,10 @@ var Dialect = module.exports = function(builder) {
1313
util.inherits(Dialect, BaseDialect);
1414

1515
Dialect.prototype.config = _({
16-
jsonSeparatorRegexp: /->>?/g,
17-
jsonIdentifierWrap: '\''
16+
jsonSeparatorRegexp: /->>?/g
1817
}).extend(BaseDialect.prototype.config);
1918

20-
Dialect.prototype._wrapJsonIdentifier = function(name) {
21-
return this.config.jsonIdentifierWrap + name + this.config.jsonIdentifierWrap;
22-
};
23-
2419
Dialect.prototype._wrapIdentifier = function(name) {
25-
var self = this;
26-
2720
// split by json separator
2821
var nameParts = name.split(this.config.jsonSeparatorRegexp);
2922
var separators = name.match(this.config.jsonSeparatorRegexp);
@@ -33,7 +26,7 @@ Dialect.prototype._wrapIdentifier = function(name) {
3326

3427
// wrap all json identifier and join them with separators
3528
identifier += _(separators).reduce(function(memo, separator, index) {
36-
return memo + separator + self._wrapJsonIdentifier(nameParts[index + 1]);
29+
return memo + separator + '\'' + nameParts[index + 1] + '\'';
3730
}, '');
3831

3932
return identifier;

tests/0_base.js

+30-16
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ describe('Builder', function() {
218218
values: {name: 'John', surname: 'Doe'}
219219
});
220220

221-
expect(result.query).to.be.equal('insert into "users" ("name", "surname") values (\'John\', \'Doe\');');
221+
expect(result.query).to.be.equal('insert into "users" ("name", "surname") values ' +
222+
'(\'John\', \'Doe\');');
222223
expect(result.values).to.not.be.ok;
223224
});
224225

@@ -238,23 +239,24 @@ describe('Builder', function() {
238239
}
239240
);
240241

241-
it('should throw error if identifier contains more than one dot', function() {
242+
it('shouldn\'t wrap identifiers that already wrapped', function() {
242243
jsonSql.configure({
243244
wrappedIdentifiers: true
244245
});
245246

246-
expect(function() {
247-
jsonSql.build({
248-
type: 'insert',
249-
table: '"users"',
250-
values: {
251-
'users.a.b': 1
252-
}
253-
});
254-
}).to.throw('Identifier "users.a.b" contains more than one dot');
247+
var result = jsonSql.build({
248+
type: 'insert',
249+
table: '"users"',
250+
values: {
251+
'"name"': 'John',
252+
'"users"."age"': 22
253+
}
254+
});
255+
256+
expect(result.query).to.be.equal('insert into "users" ("name", "users"."age") values ($p1, 22);');
255257
});
256258

257-
it('shouldn\'t wrap identifiers twice', function() {
259+
it('shouldn\'t split identifiers by dots inside quotes', function() {
258260
jsonSql.configure({
259261
wrappedIdentifiers: true
260262
});
@@ -263,15 +265,27 @@ describe('Builder', function() {
263265
type: 'insert',
264266
table: '"users"',
265267
values: {
266-
'"name"': 'John',
267-
'"users"."age"': 22
268+
'"users.age"': 22
268269
}
269270
});
270271

271-
expect(result.query).to.be.equal('insert into "users" ("name", "users"."age") values ($p1, 22);');
272+
expect(result.query).to.be.equal('insert into "users" ("users.age") values (22);');
273+
});
274+
275+
it('shouldn\'t wrap asterisk identifier parts', function() {
276+
jsonSql.configure({
277+
wrappedIdentifiers: true
278+
});
279+
280+
var result = jsonSql.build({
281+
fields: ['users.*'],
282+
table: '"users"'
283+
});
284+
285+
expect(result.query).to.be.equal('select "users".* from "users";');
272286
});
273287

274-
it('should wrap identifiers with dots', function() {
288+
it('should split identifiers by dots and wrap each part', function() {
275289
jsonSql.configure({
276290
wrappedIdentifiers: true
277291
});

tests/1_select.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ describe('Select', function() {
5454
fields: {userAge: 'age', userScore: 'score'}
5555
});
5656

57-
expect(result.query).to.be.equal('select "userAge" as "age", "userScore" as "score" from "users";');
57+
expect(result.query).to.be.equal('select "userAge" as "age", "userScore" as "score" from ' +
58+
'"users";');
5859
expect(result.values).to.be.eql({});
5960
});
6061

@@ -693,7 +694,8 @@ describe('Select', function() {
693694
}
694695
});
695696

696-
expect(result.query).to.be.equal('select * from "users" where "age" in (select * from "test");');
697+
expect(result.query).to.be.equal('select * from "users" where "age" in (select * from ' +
698+
'"test");');
697699
expect(result.values).to.be.eql({});
698700
});
699701

@@ -870,7 +872,8 @@ describe('Select', function() {
870872
}
871873
});
872874

873-
expect(result.query).to.be.equal('select * from "users" where not ("name" = $p1 and "age" = 12);');
875+
expect(result.query).to.be.equal('select * from "users" where not ("name" = $p1 and ' +
876+
'"age" = 12);');
874877
expect(result.values).to.be.eql({
875878
p1: 'John'
876879
});
@@ -887,7 +890,8 @@ describe('Select', function() {
887890
}
888891
});
889892

890-
expect(result.query).to.be.equal('select * from "users" where not ("name" = $p1 and "age" = 12);');
893+
expect(result.query).to.be.equal('select * from "users" where not ("name" = $p1 and ' +
894+
'"age" = 12);');
891895
expect(result.values).to.be.eql({
892896
p1: 'John'
893897
});

tests/3_update.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ describe('Update', function() {
2626
}
2727
});
2828

29-
expect(result.query).to.be.equal('update "users" set "name" = $p1, "age" = 16, "lastVisit" = null, ' +
30-
'"active" = false;');
29+
expect(result.query).to.be.equal('update "users" set "name" = $p1, "age" = 16, ' +
30+
'"lastVisit" = null, "active" = false;');
3131
expect(result.values).to.be.eql({p1: 'Max'});
3232
});
3333

tests/5_union.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ describe('Union, except, intersect', function() {
6060
}]
6161
});
6262

63-
expect(result.query).to.be.equal('(select * from "users") union all (select * from "vipUsers");');
63+
expect(result.query).to.be.equal('(select * from "users") union all (select * from ' +
64+
'"vipUsers");');
6465
expect(result.values).to.be.eql({});
6566
});
6667

@@ -89,7 +90,8 @@ describe('Union, except, intersect', function() {
8990
}]
9091
});
9192

92-
expect(result.query).to.be.equal('(select * from "users") except all (select * from "vipUsers");');
93+
expect(result.query).to.be.equal('(select * from "users") except all (select * from ' +
94+
'"vipUsers");');
9395
expect(result.values).to.be.eql({});
9496
});
9597

@@ -103,7 +105,8 @@ describe('Union, except, intersect', function() {
103105
}]
104106
});
105107

106-
expect(result.query).to.be.equal('(select * from "users") intersect (select * from "vipUsers");');
108+
expect(result.query).to.be.equal('(select * from "users") intersect (select * from ' +
109+
'"vipUsers");');
107110
expect(result.values).to.be.eql({});
108111
});
109112

@@ -118,7 +121,8 @@ describe('Union, except, intersect', function() {
118121
}]
119122
});
120123

121-
expect(result.query).to.be.equal('(select * from "users") intersect all (select * from "vipUsers");');
124+
expect(result.query).to.be.equal('(select * from "users") intersect all (select * from ' +
125+
'"vipUsers");');
122126
expect(result.values).to.be.eql({});
123127
});
124128

0 commit comments

Comments
 (0)