Skip to content

Commit 4be018c

Browse files
Merge pull request #50 from KvSrg31sq/master
add array operators
2 parents c2a96d8 + 6b4cae5 commit 4be018c

File tree

4 files changed

+174
-3
lines changed

4 files changed

+174
-3
lines changed

lib/dialects/postgresql/blocks.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@ module.exports = function(dialect) {
99

1010
var result;
1111
if (_.isArray(value)) {
12-
result = 'array[' + _(value).map(function(item) {
13-
return dialect.builder._pushValue(item);
14-
}).join(', ') + ']';
12+
if (value.length) {
13+
result = 'array[' + _(value).map(function(item) {
14+
return dialect.builder._pushValue(item);
15+
}).join(', ') + ']';
16+
} else {
17+
result = dialect.builder._pushValue('{}');
18+
}
1519
} else if (_.isObject(value)) {
1620
result = dialect.builder._pushValue(JSON.stringify(value));
1721
} else {

lib/dialects/postgresql/operators/comparison.js

+21
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,25 @@ module.exports = function(dialect) {
5555
return buildComparisonCondition(field, 'not ilike', value);
5656
}
5757
});
58+
59+
dialect.operators.comparison.add('$arrayContains', {
60+
defaultFetchingOperator: '$array',
61+
fn: function(field, value) {
62+
return buildComparisonCondition(field, '@>', value);
63+
}
64+
});
65+
66+
dialect.operators.comparison.add('$arrayIn', {
67+
defaultFetchingOperator: '$array',
68+
fn: function(field, value) {
69+
return buildComparisonCondition(field, '<@', value);
70+
}
71+
});
72+
73+
dialect.operators.comparison.add('$arrayOverlap', {
74+
defaultFetchingOperator: '$array',
75+
fn: function(field, value) {
76+
return buildComparisonCondition(field, '&&', value);
77+
}
78+
});
5879
};
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
'use strict';
22

3+
var _ = require('underscore');
4+
35
module.exports = function(dialect) {
46
dialect.operators.fetching.add('$json', {
57
fn: function(value, end) {
68
if (end) value = {value: value};
79
return dialect.buildBlock('term', {term: value, type: 'value'});
810
}
911
});
12+
13+
dialect.operators.fetching.add('$array', {
14+
fn: function(value) {
15+
if (!_.isArray(value)) {
16+
value = [value];
17+
}
18+
return dialect.buildBlock('term', {term: value, type: 'value'});
19+
}
20+
});
1021
};

tests/6_dialects/0_postgresql.js

+135
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,141 @@ describe('PostgreSQL dialect', function() {
169169
});
170170
});
171171

172+
describe('array', function() {
173+
it('should replace empty array to {}', function() {
174+
var result = jsonSql.build({
175+
table: 'test',
176+
condition: {
177+
'params': []
178+
}
179+
});
180+
181+
expect(result.query).to.be.equal(
182+
'select * from "test" where "params" = $1;'
183+
);
184+
expect(result.values).to.be.eql(['{}']);
185+
});
186+
187+
it('should be ok with empty array in modification', function() {
188+
var result = jsonSql.build({
189+
type: 'update',
190+
table: 'test',
191+
modifier: {
192+
'params': []
193+
}
194+
});
195+
196+
expect(result.query).to.be.equal('update "test" set "params" = $1;');
197+
expect(result.values).to.be.eql(['{}']);
198+
});
199+
200+
it('should be ok with empty array in values', function() {
201+
var result = jsonSql.build({
202+
type: 'insert',
203+
table: 'test',
204+
values: {
205+
'params': []
206+
}
207+
});
208+
209+
expect(result.query).to.be.equal('insert into "test" ("params") values ($1);');
210+
expect(result.values).to.be.eql(['{}']);
211+
});
212+
213+
it('should be ok with `$arrayContains` conditional operator', function() {
214+
var result = jsonSql.build({
215+
table: 'test',
216+
condition: {
217+
'params': {
218+
$arrayContains: ['a']
219+
}
220+
}
221+
});
222+
223+
expect(result.query).to.be.equal(
224+
'select * from "test" where "params" @> array[$1];'
225+
);
226+
expect(result.values).to.be.eql(['a']);
227+
});
228+
229+
it('should correctly wrap `$arrayContains` parameters to array', function() {
230+
var result = jsonSql.build({
231+
table: 'test',
232+
condition: {
233+
'params': {
234+
$arrayContains: 'a'
235+
}
236+
}
237+
});
238+
239+
expect(result.query).to.be.equal(
240+
'select * from "test" where "params" @> array[$1];'
241+
);
242+
expect(result.values).to.be.eql(['a']);
243+
});
244+
245+
it('should be ok with `$arrayIn` conditional operator', function() {
246+
var result = jsonSql.build({
247+
table: 'test',
248+
condition: {
249+
'params': {
250+
$arrayIn: ['a']
251+
}
252+
}
253+
});
254+
255+
expect(result.query).to.be.equal(
256+
'select * from "test" where "params" <@ array[$1];'
257+
);
258+
expect(result.values).to.be.eql(['a']);
259+
});
260+
261+
it('should correctly wrap `$arrayIn` parameters to array', function() {
262+
var result = jsonSql.build({
263+
table: 'test',
264+
condition: {
265+
'params': {
266+
$arrayIn: 'a'
267+
}
268+
}
269+
});
270+
271+
expect(result.query).to.be.equal(
272+
'select * from "test" where "params" <@ array[$1];'
273+
);
274+
expect(result.values).to.be.eql(['a']);
275+
});
276+
277+
it('should be ok with `$arrayOverlap` conditional operator', function() {
278+
var result = jsonSql.build({
279+
table: 'test',
280+
condition: {
281+
params: {
282+
$arrayOverlap: ['a']
283+
}
284+
}
285+
});
286+
287+
expect(result.query).to.be.equal('select * from "test" where "params" && array[$1];');
288+
expect(result.values).to.be.eql(['a']);
289+
});
290+
291+
it('should correctly wrap `$arrayOverlap` parameters to array', function() {
292+
var result = jsonSql.build({
293+
table: 'test',
294+
condition: {
295+
params: {
296+
$arrayOverlap: 'a'
297+
}
298+
}
299+
});
300+
301+
expect(result.query).to.be.equal('select * from "test" where "params" && array[$1];');
302+
expect(result.values).to.be.eql(['a']);
303+
});
304+
});
305+
306+
172307
describe('explain', function() {
173308
it('should throw error without `query`, `select` and `expression` properties',
174309
function() {

0 commit comments

Comments
 (0)