Skip to content

Commit 1b5b89e

Browse files
committed
add Date values support, 2do2go#22
1 parent 32aa01b commit 1b5b89e

File tree

8 files changed

+93
-53
lines changed

8 files changed

+93
-53
lines changed

lib/builder.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,20 @@ Builder.prototype._pushValue = function(value) {
4242
return 'null';
4343
} else if (_.isNumber(value) || _.isBoolean(value)) {
4444
return String(value);
45-
} else if (_.isString(value)) {
45+
} else if (_.isString(value) || _.isDate(value)) {
4646
if (this.options.separatedValues) {
4747
var placeholder = this._getPlaceholder();
48+
4849
if (this.options.namedValues) {
4950
this._values[placeholder] = value;
5051
} else {
5152
this._values.push(value);
5253
}
54+
5355
return this._wrapPlaceholder(placeholder);
5456
} else {
57+
if (_.isDate(value)) value = value.toISOString();
58+
5559
return '\'' + value + '\'';
5660
}
5761
} else {

lib/dialects/base/blocks.js

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
var _ = require('underscore');
4+
var objectUtils = require('../../utils/object');
45

56
var removeTopBrackets = function(condition) {
67
if (condition.length && condition[0] === '(' &&
@@ -11,29 +12,9 @@ var removeTopBrackets = function(condition) {
1112
return condition;
1213
};
1314

14-
// check if object contains any of expected keys
15-
var hasSome = function(obj, keys) {
16-
var objKeys = _(obj).keys();
17-
return _(keys).some(function(key) {
18-
return _(objKeys).contains(key);
19-
});
20-
};
21-
2215
var termKeys = ['select', 'query', 'field', 'value', 'func', 'expression'];
2316
var isTerm = function(obj) {
24-
return _.isObject(obj) && !_.isArray(obj) && hasSome(obj, termKeys);
25-
};
26-
27-
var isSimpleValue = function(value) {
28-
return (
29-
_.isString(value) ||
30-
_.isNumber(value) ||
31-
_.isBoolean(value) ||
32-
_.isNull(value) ||
33-
_.isUndefined(value) ||
34-
_.isRegExp(value) ||
35-
_.isDate(value)
36-
);
17+
return objectUtils.isObjectObject(obj) && objectUtils.hasSome(obj, termKeys);
3718
};
3819

3920
module.exports = function(dialect) {
@@ -53,7 +34,7 @@ module.exports = function(dialect) {
5334
// If fields is array: ['a', {b: 'c'}, {name: '', table: 't', alias: 'r'}]
5435
if (_.isArray(fields)) {
5536
fields = _(fields).map(function(field) {
56-
if (isSimpleValue(field) || isTerm(field) || _.has(field, 'name')) {
37+
if (objectUtils.isSimpleValue(field) || isTerm(field) || _.has(field, 'name')) {
5738
// if field has simple type or is field object: {name: '', table: 't', alias: 'r'}
5839
return dialect.buildBlock('term', {term: field, type: 'field'});
5940
} else {
@@ -83,11 +64,12 @@ module.exports = function(dialect) {
8364
var term = params.term;
8465
var type = params.type || 'field';
8566

86-
var notObject = isSimpleValue(term) || _.isArray(term);
67+
var isSimpleValue = objectUtils.isSimpleValue(term);
68+
var isArray = _.isArray(term);
8769

88-
if (notObject && !_.isString(term)) type = 'value';
70+
if (isSimpleValue && !_.isString(term) || isArray) type = 'value';
8971

90-
if (notObject || !isTerm(term)) {
72+
if (isSimpleValue || !isTerm(term) || isArray) {
9173
term = _(term).chain().pick('cast', 'alias').extend(_.object([type], [term])).value();
9274
}
9375

@@ -253,7 +235,7 @@ module.exports = function(dialect) {
253235
// if join is object -> set table name from key and make each joinItem
254236
} else if (_.isObject(join)) {
255237
result = _(join).map(function(joinItem, table) {
256-
if (!hasSome(joinItem, ['table', 'query', 'select', 'expression'])) {
238+
if (!objectUtils.hasSome(joinItem, ['table', 'query', 'select', 'expression'])) {
257239
joinItem = _.defaults({table: table}, joinItem);
258240
}
259241

lib/dialects/base/index.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
var _ = require('underscore');
44
var ValuesStore = require('../../utils/valuesStore');
5+
var objectUtils = require('../../utils/object');
56

67
var templatesInit = require('./templates');
78
var blocksInit = require('./blocks');
@@ -72,7 +73,9 @@ Dialect.prototype.buildLogicalOperator = function(params) {
7273
var operator = params.operator;
7374
var value = params.value;
7475

75-
if (!_.isObject(value)) value = _.object([params.defaultFetchingOperator], [value]);
76+
if (objectUtils.isSimpleValue(value)) {
77+
value = _.object([params.defaultFetchingOperator], [value]);
78+
}
7679

7780
if (_.isEmpty(value)) return '';
7881

@@ -94,7 +97,9 @@ Dialect.prototype.buildLogicalOperator = function(params) {
9497
result = _(value).map(function(item, field) {
9598
// if field name is not a operator convert it to {$field: {name: 'a', $eq: 'b'}}
9699
if (field[0] !== '$') {
97-
if (!_.isObject(item) || _.isArray(item)) item = {$eq: item};
100+
if (objectUtils.isSimpleValue(item) || _.isArray(item)) {
101+
item = {$eq: item};
102+
}
98103
item = _.defaults({name: field}, item);
99104
field = '$field';
100105
}
@@ -143,7 +148,7 @@ Dialect.prototype.buildFetchingOperator = function(params) {
143148
var field = this.operators.fetching.get(operator).fn(value, params.end);
144149

145150
var result;
146-
if (params.end || !_.isObject(value)) {
151+
if (params.end || objectUtils.isSimpleValue(value)) {
147152
result = field;
148153
} else {
149154
result = this.buildOperatorsGroup({
@@ -166,7 +171,7 @@ Dialect.prototype.buildEndFetchingOperator = function(params) {
166171
var value = params.value;
167172
var operator;
168173

169-
if (_.isObject(value) && !_.isArray(value)) {
174+
if (objectUtils.isObjectObject(value)) {
170175
// get first query operator
171176
operator = _(value).findKey(function(item, operator) {
172177
return operator[0] === '$' && self.operators.fetching.has(operator);
@@ -199,7 +204,7 @@ Dialect.prototype.buildOperatorsGroup = function(params) {
199204
var value = params.value;
200205

201206
var result;
202-
if (_.isObject(value) && !_.isArray(value)) {
207+
if (objectUtils.isObjectObject(value)) {
203208
result = this.operators.logical.get(params.operator).fn(
204209
_(value)
205210
.chain()

lib/utils/object.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
var _ = require('underscore');
4+
5+
// check if object contains any of expected keys
6+
exports.hasSome = function(obj, keys) {
7+
var objKeys = _(obj).keys();
8+
return _(keys).some(function(key) {
9+
return _(objKeys).contains(key);
10+
});
11+
};
12+
13+
exports.isSimpleValue = function(value) {
14+
return (
15+
_.isString(value) ||
16+
_.isNumber(value) ||
17+
_.isBoolean(value) ||
18+
_.isNull(value) ||
19+
_.isUndefined(value) ||
20+
_.isRegExp(value) ||
21+
_.isDate(value)
22+
);
23+
};
24+
25+
exports.isObjectObject = function(obj) {
26+
return _.isObject(obj) && Object.prototype.toString.call(obj) === '[object Object]';
27+
}

tests/0_base.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,19 @@ describe('Builder', function() {
297297
expect(jsonSql._values).to.not.be.ok;
298298
expect(jsonSql._placeholderId).to.not.be.ok;
299299

300+
var date = new Date();
300301
var result = jsonSql.build({
301302
type: 'insert',
302303
table: 'users',
303-
values: {name: 'John', surname: 'Doe'}
304+
values: {
305+
name: 'John',
306+
surname: 'Doe',
307+
date: date
308+
}
304309
});
305310

306-
expect(result.query).to.be.equal('insert into "users" ("name", "surname") values ' +
307-
'(\'John\', \'Doe\');');
311+
expect(result.query).to.be.equal('insert into "users" ("name", "surname", "date") values ' +
312+
'(\'John\', \'Doe\', \'' + date.toISOString() + '\');');
308313
expect(result.values).to.not.be.ok;
309314
});
310315

tests/1_select.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,31 +1221,37 @@ describe('Select', function() {
12211221
});
12221222

12231223
it('should be ok with `$or`:[`$or`, `$or`]', function() {
1224+
var date1 = new Date();
1225+
var date2 = new Date();
12241226
var result = jsonSql.build({
12251227
table: 'users',
12261228
condition: {
12271229
$or: [{
12281230
$or: {
12291231
name: 'John',
1230-
age: 12
1232+
age: 12,
1233+
date: date1
12311234
}
12321235
}, {
12331236
$or: {
12341237
name: 'Mark',
1235-
age: 14
1238+
age: 14,
1239+
date: date2
12361240
}
12371241
}]
12381242
}
12391243
});
12401244

12411245
expect(result.query).to.be.equal(
12421246
'select * from "users" ' +
1243-
'where ("name" = $p1 or "age" = 12) or ' +
1244-
'("name" = $p2 or "age" = 14);'
1247+
'where ("name" = $p1 or "age" = 12 or "date" = $p2) or ' +
1248+
'("name" = $p3 or "age" = 14 or "date" = $p4);'
12451249
);
12461250
expect(result.values).to.be.eql({
12471251
p1: 'John',
1248-
p2: 'Mark'
1252+
p2: date1,
1253+
p3: 'Mark',
1254+
p4: date2
12491255
});
12501256
});
12511257
});

tests/2_insert.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,25 @@ describe('Insert', function() {
1414
});
1515

1616
it('should be ok with `values` property', function() {
17+
var date = new Date();
1718
var result = jsonSql.build({
1819
type: 'insert',
1920
table: 'users',
2021
values: {
21-
name: 'Max'
22+
id: 1,
23+
name: 'Max',
24+
date: date
2225
}
2326
});
2427

25-
expect(result.query).to.be.equal('insert into "users" ("name") values ($p1);');
26-
expect(result.values).to.be.eql({p1: 'Max'});
28+
expect(result.query).to.be.equal(
29+
'insert into "users" ("id", "name", "date") values (1, $p1, $p2);'
30+
);
31+
expect(result.values).to.be.eql({p1: 'Max', p2: date});
2732
});
2833

2934
it('should be ok with `with` property', function() {
35+
var date = new Date();
3036
var result = jsonSql.build({
3137
'with': [{
3238
name: 't_1',
@@ -40,34 +46,37 @@ describe('Insert', function() {
4046
name: 'Max',
4147
age: 17,
4248
lastVisit: null,
43-
active: true
49+
active: true,
50+
date: date
4451
}
4552
});
4653

4754
expect(result.query).to.be.equal(
4855
'with "t_1" as (select * from "t_1") insert into "users" ' +
49-
'("name", "age", "lastVisit", "active") values ($p1, 17, null, true);'
56+
'("name", "age", "lastVisit", "active", "date") values ($p1, 17, null, true, $p2);'
5057
);
51-
expect(result.values).to.be.eql({p1: 'Max'});
58+
expect(result.values).to.be.eql({p1: 'Max', p2: date});
5259
});
5360

5461
it('should be ok with `returning` property', function() {
62+
var date = new Date();
5563
var result = jsonSql.build({
5664
type: 'insert',
5765
table: 'users',
5866
values: {
5967
name: 'Max',
6068
age: 17,
6169
lastVisit: null,
62-
active: true
70+
active: true,
71+
date: date
6372
},
6473
returning: ['users.*']
6574
});
6675

6776
expect(result.query).to.be.equal(
68-
'insert into "users" ("name", "age", "lastVisit", "active") ' +
69-
'values ($p1, 17, null, true) returning "users".*;'
77+
'insert into "users" ("name", "age", "lastVisit", "active", "date") ' +
78+
'values ($p1, 17, null, true, $p2) returning "users".*;'
7079
);
71-
expect(result.values).to.be.eql({p1: 'Max'});
80+
expect(result.values).to.be.eql({p1: 'Max', p2: date});
7281
});
7382
});

tests/3_update.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,22 @@ describe('Update', function() {
1515
});
1616

1717
it('should be ok with default(`$set`)', function() {
18+
var date = new Date();
1819
var result = jsonSql.build({
1920
type: 'update',
2021
table: 'users',
2122
modifier: {
2223
name: 'Max',
2324
age: 16,
2425
lastVisit: null,
25-
active: false
26+
active: false,
27+
date: date
2628
}
2729
});
2830

2931
expect(result.query).to.be.equal('update "users" set "name" = $p1, "age" = 16, ' +
30-
'"lastVisit" = null, "active" = false;');
31-
expect(result.values).to.be.eql({p1: 'Max'});
32+
'"lastVisit" = null, "active" = false, "date" = $p2;');
33+
expect(result.values).to.be.eql({p1: 'Max', p2: date});
3234
});
3335

3436
it('should be ok with `$set`', function() {

0 commit comments

Comments
 (0)