tg-client-query-builder 2.14.1 → 2.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1,3 +1,3 @@
1
- const QueryBuilder = require('./query-builder');
1
+ const QueryBuilder = require("./query-builder");
2
2
 
3
- module.exports = QueryBuilder;
3
+ module.exports = QueryBuilder;
package/package.json CHANGED
@@ -1,25 +1,10 @@
1
1
  {
2
2
  "name": "tg-client-query-builder",
3
- "version": "2.14.1",
3
+ "version": "2.14.3",
4
4
  "description": "Teselagen Client Side (browser) SQL Query Builder",
5
- "main": "build/query-builder/index.js",
6
- "repository": "https://github.com/TeselaGen/tg-query.git",
7
5
  "author": "TeselaGen",
8
6
  "license": "ISC",
9
- "scripts": {
10
- "prepublishOnly": "yarn build",
11
- "build": "babel --presets=es2015 query-builder/ --out-dir build/query-builder/"
12
- },
13
7
  "dependencies": {
14
8
  "lodash": "^4.17.4"
15
- },
16
- "devDependencies": {
17
- "babel-cli": "^6.26.0",
18
- "babel-preset-latest": "^6.24.1",
19
- "chai": "^4.0.2",
20
- "fs-extra": "^3.0.1",
21
- "json-beautify": "^1.0.1",
22
- "json-format": "^1.0.1",
23
- "jsonfile": "^3.0.0"
24
9
  }
25
10
  }
@@ -1,22 +1,27 @@
1
+ module.exports = function combineQueries(qry1, qry2, joinOperator, opts) {
2
+ if (qry1.__objectType !== "query")
3
+ throw new Error("First query is not a query type.");
4
+ if (qry2.__objectType !== "query")
5
+ throw new Error("Second query is not a query type.");
6
+ if (qry1.entity != qry2.entity)
7
+ throw new Error(
8
+ "Queries are for different entities " +
9
+ qry1.entity +
10
+ " and " +
11
+ qry2.entity
12
+ );
1
13
 
14
+ if (joinOperator !== "or") joinOperator = "and";
2
15
 
3
- module.exports = function combineQueries(qry1, qry2, joinOperator, opts){
4
- if(qry1.__objectType !== 'query') throw new Error("First query is not a query type.");
5
- if(qry2.__objectType !== 'query') throw new Error("Second query is not a query type.");
6
- if(qry1.entity != qry2.entity) throw new Error("Queries are for different entities " + qry1.entity + " and " + qry2.entity);
16
+ var combinedFilters = {
17
+ type: "group",
18
+ operator: joinOperator,
19
+ filters: []
20
+ };
7
21
 
8
- if(joinOperator !== 'or') joinOperator = 'and';
22
+ combinedFilters.filters = qry1.filters.concat(qry2.filters);
9
23
 
10
- var combinedFilters =
11
- {
12
- type: "group",
13
- operator: joinOperator,
14
- filters: [ ]
15
- };
16
-
17
- combinedFilters.filters = qry1.filters.concat(qry2.filters);
18
-
19
- qry1.filters = [combinedFilters];
24
+ qry1.filters = [combinedFilters];
20
25
 
21
- return qry1;
22
- }
26
+ return qry1;
27
+ };
@@ -1,20 +1,17 @@
1
+ module.exports = (function() {
2
+ function FilterExpression(opName, args) {
3
+ this.name = opName;
4
+ this.args = args;
5
+ }
1
6
 
2
-
3
-
4
- module.exports = (function(){
5
- function FilterExpression(opName, args){
6
- this.name = opName;
7
- this.args = args;
8
- }
9
-
10
- FilterExpression.prototype.toFilter = function(filterBuilder, argName){
11
- var filterDef = {
12
- type: "expression",
13
- operator: this.name,
14
- field: argName,
15
- args: this.args
16
- };
17
- return filterDef;
18
- }
19
- return FilterExpression;
20
- })();
7
+ FilterExpression.prototype.toFilter = function(filterBuilder, argName) {
8
+ var filterDef = {
9
+ type: "expression",
10
+ operator: this.name,
11
+ field: argName,
12
+ args: this.args
13
+ };
14
+ return filterDef;
15
+ };
16
+ return FilterExpression;
17
+ })();
@@ -32,25 +32,33 @@ function isDateOrNumber(opName) {
32
32
  return () => {
33
33
  var args = [].slice.call(arguments);
34
34
  if (
35
- args.some((arg) => {
35
+ args.some(arg => {
36
36
  return !(_.isDate(arg) || _.isString(arg) || _.isNumber(arg));
37
37
  })
38
38
  ) {
39
- throw new Error(`QueryBuilderError: You must pass a date or number as args to ${opName}. You passed: Args ${args.join(",")}`);
39
+ throw new Error(
40
+ `QueryBuilderError: You must pass a date or number as args to ${opName}. You passed: Args ${args.join(
41
+ ","
42
+ )}`
43
+ );
40
44
  }
41
45
  };
42
46
  }
43
47
  function isArray(opName) {
44
- return (arg) => {
48
+ return arg => {
45
49
  if (!_.isArray(arg)) {
46
- throw new Error(`QueryBuilderError: You must pass an array for ${opName} filters. You passed: ${arg}`);
50
+ throw new Error(
51
+ `QueryBuilderError: You must pass an array for ${opName} filters. You passed: ${arg}`
52
+ );
47
53
  }
48
54
  };
49
55
  }
50
56
  function isString(opName) {
51
- return (arg) => {
57
+ return arg => {
52
58
  if (!_.isString(arg)) {
53
- throw new Error(`QueryBuilderError: You must pass a string for ${opName} filters. You passed: ${arg}`);
59
+ throw new Error(
60
+ `QueryBuilderError: You must pass a string for ${opName} filters. You passed: ${arg}`
61
+ );
54
62
  }
55
63
  };
56
64
  }
@@ -58,7 +66,9 @@ function isString(opName) {
58
66
  function numberOfArgs(opName, argLength) {
59
67
  return (...args) => {
60
68
  if (args.length !== argLength) {
61
- throw new Error(`QueryBuilderError: Args for ${opName} are of length ${args.length}, but they should be of length ${argLength}`);
69
+ throw new Error(
70
+ `QueryBuilderError: Args for ${opName} are of length ${args.length}, but they should be of length ${argLength}`
71
+ );
62
72
  }
63
73
  };
64
74
  }
@@ -66,124 +76,139 @@ function numberOfArgs(opName, argLength) {
66
76
  const expressionOperators = [
67
77
  {
68
78
  opName: "greaterThan",
69
- sanityChecks: [numberOfArgs("greaterThan", 1), isDateOrNumber("greaterThan")],
79
+ sanityChecks: [
80
+ numberOfArgs("greaterThan", 1),
81
+ isDateOrNumber("greaterThan")
82
+ ]
70
83
  },
71
84
  {
72
85
  opName: "inList",
73
- sanityChecks: [numberOfArgs("inList", 1), isArray("inList")],
86
+ sanityChecks: [numberOfArgs("inList", 1), isArray("inList")]
74
87
  },
75
88
  {
76
89
  opName: "lessThan",
77
- sanityChecks: [numberOfArgs("lessThan", 1), isDateOrNumber("lessThan")],
90
+ sanityChecks: [numberOfArgs("lessThan", 1), isDateOrNumber("lessThan")]
78
91
  },
79
92
  {
80
93
  opName: "lessThanOrEqual",
81
- sanityChecks: [numberOfArgs("lessThanOrEqual", 1), isDateOrNumber("lessThanOrEqual")],
94
+ sanityChecks: [
95
+ numberOfArgs("lessThanOrEqual", 1),
96
+ isDateOrNumber("lessThanOrEqual")
97
+ ]
82
98
  },
83
99
  {
84
100
  opName: "equals",
85
- sanityChecks: [numberOfArgs("equals", 1)],
101
+ sanityChecks: [numberOfArgs("equals", 1)]
86
102
  },
87
103
  {
88
104
  opName: "greaterThanOrEqual",
89
- sanityChecks: [numberOfArgs("greaterThanOrEqual", 1), isDateOrNumber("greaterThanOrEqual")],
105
+ sanityChecks: [
106
+ numberOfArgs("greaterThanOrEqual", 1),
107
+ isDateOrNumber("greaterThanOrEqual")
108
+ ]
90
109
  },
91
110
  {
92
111
  opName: "notEquals",
93
- sanityChecks: [numberOfArgs("notEquals", 1)],
112
+ sanityChecks: [numberOfArgs("notEquals", 1)]
94
113
  },
95
114
  {
96
115
  opName: "notNull",
97
- sanityChecks: [numberOfArgs("notNull", 0)],
116
+ sanityChecks: [numberOfArgs("notNull", 0)]
98
117
  },
99
118
  {
100
119
  opName: "isNull",
101
- sanityChecks: [numberOfArgs("isNull", 0)],
120
+ sanityChecks: [numberOfArgs("isNull", 0)]
102
121
  },
103
122
  {
104
123
  opName: "between",
105
- sanityChecks: [numberOfArgs("between", 2), isDateOrNumber("between")],
124
+ sanityChecks: [numberOfArgs("between", 2), isDateOrNumber("between")]
106
125
  },
107
126
  {
108
127
  opName: "notInList",
109
- sanityChecks: [numberOfArgs("notInList", 1), isArray("notInList")],
128
+ sanityChecks: [numberOfArgs("notInList", 1), isArray("notInList")]
110
129
  },
111
130
  {
112
131
  opName: "startsWithExactly",
113
- sanityChecks: [numberOfArgs("startsWith", 1), isString("startsWith")],
132
+ sanityChecks: [numberOfArgs("startsWith", 1), isString("startsWith")]
114
133
  },
115
134
  {
116
135
  opName: "endsWithExactly",
117
- sanityChecks: [numberOfArgs("endsWith", 1), isString("endsWith")],
136
+ sanityChecks: [numberOfArgs("endsWith", 1), isString("endsWith")]
118
137
  },
119
138
  {
120
139
  opName: "containsExactly",
121
- sanityChecks: [numberOfArgs("contains", 1), isString("contains")],
140
+ sanityChecks: [numberOfArgs("contains", 1), isString("contains")]
122
141
  },
123
142
  {
124
143
  opName: "startsWith",
125
- sanityChecks: [numberOfArgs("startsWith", 1), isString("startsWith")],
144
+ sanityChecks: [numberOfArgs("startsWith", 1), isString("startsWith")]
126
145
  },
127
146
  {
128
147
  opName: "notStartsWith",
129
- sanityChecks: [numberOfArgs("notStartsWith", 1), isString("notStartsWith")],
148
+ sanityChecks: [numberOfArgs("notStartsWith", 1), isString("notStartsWith")]
130
149
  },
131
150
  {
132
151
  opName: "endsWith",
133
- sanityChecks: [numberOfArgs("endsWith", 1), isString("endsWith")],
152
+ sanityChecks: [numberOfArgs("endsWith", 1), isString("endsWith")]
134
153
  },
135
154
  {
136
155
  opName: "notEndsWith",
137
- sanityChecks: [numberOfArgs("notEndsWith", 1), isString("notEndsWith")],
156
+ sanityChecks: [numberOfArgs("notEndsWith", 1), isString("notEndsWith")]
138
157
  },
139
158
  {
140
159
  opName: "contains",
141
- sanityChecks: [numberOfArgs("contains", 1), isString("contains")],
160
+ sanityChecks: [numberOfArgs("contains", 1), isString("contains")]
142
161
  },
143
162
  {
144
163
  opName: "notContains",
145
- sanityChecks: [numberOfArgs("notContains", 1), isString("notContains")],
164
+ sanityChecks: [numberOfArgs("notContains", 1), isString("notContains")]
146
165
  },
147
166
  {
148
167
  opName: "upperCase",
149
- sanityChecks: [numberOfArgs("upperCase", 1), isString("upperCase")],
168
+ sanityChecks: [numberOfArgs("upperCase", 1), isString("upperCase")]
150
169
  },
151
170
  {
152
171
  opName: "lowerCase",
153
- sanityChecks: [numberOfArgs("lowerCase", 1), isString("lowerCase")],
172
+ sanityChecks: [numberOfArgs("lowerCase", 1), isString("lowerCase")]
154
173
  },
155
174
  {
156
175
  opName: "matchesRegex",
157
- sanityChecks: [numberOfArgs("matchesRegex", 1), isString("matchesRegex")],
176
+ sanityChecks: [numberOfArgs("matchesRegex", 1), isString("matchesRegex")]
158
177
  },
159
178
  {
160
179
  opName: "matchesSimilar",
161
- sanityChecks: [numberOfArgs("matchesSimilar", 1), isString("matchesSimilar")],
180
+ sanityChecks: [
181
+ numberOfArgs("matchesSimilar", 1),
182
+ isString("matchesSimilar")
183
+ ]
162
184
  },
163
185
  {
164
186
  opName: "fuzzy",
165
187
  sanityChecks: [numberOfArgs("fuzzy", 1), isString("fuzzy")],
166
- transform: (arg) => {
188
+ transform: arg => {
167
189
  // Build Regex String
168
190
  var matchTerm = "";
169
191
  // Split all the search terms
170
- var terms = arg.replace(/\W/g, "").replace(" ", "").split("");
192
+ var terms = arg
193
+ .replace(/\W/g, "")
194
+ .replace(" ", "")
195
+ .split("");
171
196
  for (var i = 0; i < terms.length; i++) {
172
197
  matchTerm += ".*" + terms[i];
173
198
  }
174
199
  matchTerm += ".*";
175
200
  return {
176
201
  newOpName: "matchesRegex",
177
- newArgs: [matchTerm],
202
+ newArgs: [matchTerm]
178
203
  };
179
- },
180
- },
204
+ }
205
+ }
181
206
 
182
207
  // 'subString', //tnr: not yet implemented
183
208
  // 'dateOnly', //tnr: not yet implemented
184
209
  ];
185
210
 
186
- module.exports = (function () {
211
+ module.exports = (function() {
187
212
  // to be implemented
188
213
  //
189
214
  // filter - done
@@ -217,14 +242,15 @@ module.exports = (function () {
217
242
  function QueryBuilder(entity) {
218
243
  this.query = {};
219
244
 
220
- if (entity == null) throw new Error("You must pass the name of the model being filtered!");
245
+ if (entity == null)
246
+ throw new Error("You must pass the name of the model being filtered!");
221
247
 
222
248
  if (typeof entity === "string") {
223
249
  this.query = {
224
250
  __objectType: "query",
225
251
  type: "root",
226
252
  entity,
227
- filters: [],
253
+ filters: []
228
254
  };
229
255
  } else {
230
256
  let subQuery = entity;
@@ -234,11 +260,12 @@ module.exports = (function () {
234
260
  entity: subQuery.entity,
235
261
  foreignKey: subQuery.foreignKey,
236
262
  modifier: subQuery.modifier,
263
+ isArrayRelation: subQuery.isArrayRelation,
237
264
  filters: [],
238
- countExpression: undefined,
265
+ countExpression: undefined
239
266
  };
240
267
  this.parentBuilder = subQuery.parentBuilder;
241
- this.toFilter = function (filterBuilder, name) {
268
+ this.toFilter = function(filterBuilder, name) {
242
269
  this.query.foreignKey = name;
243
270
  return this.toJSON();
244
271
  };
@@ -247,14 +274,14 @@ module.exports = (function () {
247
274
 
248
275
  QueryBuilder.combineQueries = combineQueries;
249
276
 
250
- QueryBuilder.prototype.field = function (fieldName) {
277
+ QueryBuilder.prototype.field = function(fieldName) {
251
278
  return {
252
279
  __objectType: "field",
253
- field: fieldName,
280
+ field: fieldName
254
281
  };
255
282
  };
256
283
 
257
- QueryBuilder.prototype.related = function (relatedEntity, isArrayRelation) {
284
+ QueryBuilder.prototype.related = function(relatedEntity, isArrayRelation) {
258
285
  var tokens = relatedEntity.split(".");
259
286
  var entity = tokens[0];
260
287
  var key = tokens[1];
@@ -265,7 +292,7 @@ module.exports = (function () {
265
292
  return createSubQueryBuilder(this, entity, key, isArrayRelation);
266
293
  };
267
294
 
268
- QueryBuilder.prototype.notRelated = function (relatedEntity, isArrayRelation) {
295
+ QueryBuilder.prototype.notRelated = function(relatedEntity, isArrayRelation) {
269
296
  var tokens = relatedEntity.split(".");
270
297
  var entity = tokens[0];
271
298
  var key = tokens[1];
@@ -276,7 +303,7 @@ module.exports = (function () {
276
303
  return createSubQueryBuilder(this, entity, key, isArrayRelation, "not");
277
304
  };
278
305
 
279
- QueryBuilder.prototype.toJSON = function () {
306
+ QueryBuilder.prototype.toJSON = function() {
280
307
  let qry = JSON.parse(JSON.stringify(this.query));
281
308
  if (qry.filters.length > 1) {
282
309
  qry.filters = [
@@ -284,14 +311,14 @@ module.exports = (function () {
284
311
  type: "group",
285
312
  operator: "and",
286
313
  chainedWith: "and",
287
- filters: qry.filters,
288
- },
314
+ filters: qry.filters
315
+ }
289
316
  ];
290
317
  }
291
318
  return qry;
292
319
  };
293
320
 
294
- QueryBuilder.prototype.convertToFilter = function (argDef, operator) {
321
+ QueryBuilder.prototype.convertToFilter = function(argDef, operator) {
295
322
  var whereArgs = {};
296
323
  var filters = [];
297
324
 
@@ -317,7 +344,7 @@ module.exports = (function () {
317
344
  if (_.keys(whereArgs).length > 0) {
318
345
  filters.unshift({
319
346
  type: "where",
320
- args: whereArgs,
347
+ args: whereArgs
321
348
  });
322
349
  }
323
350
 
@@ -327,61 +354,63 @@ module.exports = (function () {
327
354
  var filterDef = {
328
355
  type: "group",
329
356
  operator: operator || "and",
330
- filters,
357
+ filters
331
358
  };
332
359
  return filterDef;
333
360
  };
334
361
 
335
- QueryBuilder.prototype.where = function () {
362
+ QueryBuilder.prototype.where = function() {
336
363
  var args = [].slice.call(arguments);
337
364
  return this.whereAll(args);
338
365
  };
339
366
 
340
- QueryBuilder.prototype.orWhere = function () {
367
+ QueryBuilder.prototype.orWhere = function() {
341
368
  var args = [].slice.call(arguments);
342
369
  return this.orWhereAll(args);
343
370
  };
344
371
 
345
- QueryBuilder.prototype.andWhere = function () {
372
+ QueryBuilder.prototype.andWhere = function() {
346
373
  var args = [].slice.call(arguments);
347
374
  return this.andWhereAll(args);
348
375
  };
349
376
 
350
- QueryBuilder.prototype.whereAny = function () {
377
+ QueryBuilder.prototype.whereAny = function() {
351
378
  var args = [].slice.call(arguments);
352
379
  return whereAny(this, args);
353
380
  };
354
381
 
355
- QueryBuilder.prototype.whereAll = function () {
382
+ QueryBuilder.prototype.whereAll = function() {
356
383
  var args = [].slice.call(arguments);
357
384
  return whereAll(this, args);
358
385
  };
359
386
 
360
- QueryBuilder.prototype.andWhereAny = function () {
387
+ QueryBuilder.prototype.andWhereAny = function() {
361
388
  var args = [].slice.call(arguments);
362
389
  return whereAny(this, args, "and");
363
390
  };
364
391
 
365
- QueryBuilder.prototype.orWhereAny = function () {
392
+ QueryBuilder.prototype.orWhereAny = function() {
366
393
  var args = [].slice.call(arguments);
367
394
  return whereAny(this, args, "or");
368
395
  };
369
396
 
370
- QueryBuilder.prototype.andWhereAll = function () {
397
+ QueryBuilder.prototype.andWhereAll = function() {
371
398
  var args = [].slice.call(arguments);
372
399
  return whereAll(this, args, "and");
373
400
  };
374
401
 
375
- QueryBuilder.prototype.orWhereAll = function () {
402
+ QueryBuilder.prototype.orWhereAll = function() {
376
403
  var args = [].slice.call(arguments);
377
404
  return whereAll(this, args, "or");
378
405
  };
379
406
 
380
- QueryBuilder.prototype.count = function () {
407
+ QueryBuilder.prototype.count = function() {
381
408
  var args = [].slice.call(arguments);
382
409
  if (this.query.type === "subquery") {
383
410
  if (this.query.countExpression) {
384
- throw new Error("QueryBuilder subquery can only have one count expression");
411
+ throw new Error(
412
+ "QueryBuilder subquery can only have one count expression"
413
+ );
385
414
  }
386
415
  this.query.countExpression = args[0].toFilter(this, "count");
387
416
  } else {
@@ -395,13 +424,19 @@ module.exports = (function () {
395
424
 
396
425
  return QueryBuilder;
397
426
 
398
- function createSubQueryBuilder(qb, entity, key, isArrayRelation = true, modifier) {
427
+ function createSubQueryBuilder(
428
+ qb,
429
+ entity,
430
+ key,
431
+ isArrayRelation = true,
432
+ modifier
433
+ ) {
399
434
  return new QueryBuilder({
400
435
  parentBuilder: qb,
401
436
  entity,
402
437
  key,
403
438
  modifier,
404
- isArrayRelation,
439
+ isArrayRelation
405
440
  });
406
441
  }
407
442
 
@@ -415,7 +450,7 @@ module.exports = (function () {
415
450
  argsToUse = newArgs;
416
451
  opNameToUse = newOpName;
417
452
  }
418
- sanityChecks.forEach((sanityCheck) => {
453
+ sanityChecks.forEach(sanityCheck => {
419
454
  sanityCheck(...args);
420
455
  });
421
456
  return new FilterExpression(opNameToUse, argsToUse);
@@ -440,16 +475,17 @@ module.exports = (function () {
440
475
  }
441
476
 
442
477
  function where(filterBuilder, operator, whereArgs, chainedWith) {
443
- if (!Array.isArray(whereArgs)) return where(filterBuilder, operator, [whereArgs], chainedWith);
478
+ if (!Array.isArray(whereArgs))
479
+ return where(filterBuilder, operator, [whereArgs], chainedWith);
444
480
 
445
481
  var filterDef = {
446
482
  type: "group",
447
483
  operator,
448
484
  chainedWith,
449
- filters: [],
485
+ filters: []
450
486
  };
451
487
 
452
- whereArgs.forEach((arg) => {
488
+ whereArgs.forEach(arg => {
453
489
  //add check for object type TODO
454
490
  var filter = filterBuilder.convertToFilter(arg, operator);
455
491
  filterDef.filters.push(filter);
@@ -1,21 +0,0 @@
1
- 'use strict';
2
-
3
- module.exports = function combineQueries(qry1, qry2, joinOperator, opts) {
4
- if (qry1.__objectType !== 'query') throw new Error("First query is not a query type.");
5
- if (qry2.__objectType !== 'query') throw new Error("Second query is not a query type.");
6
- if (qry1.entity != qry2.entity) throw new Error("Queries are for different entities " + qry1.entity + " and " + qry2.entity);
7
-
8
- if (joinOperator !== 'or') joinOperator = 'and';
9
-
10
- var combinedFilters = {
11
- type: "group",
12
- operator: joinOperator,
13
- filters: []
14
- };
15
-
16
- combinedFilters.filters = qry1.filters.concat(qry2.filters);
17
-
18
- qry1.filters = [combinedFilters];
19
-
20
- return qry1;
21
- };
@@ -1,19 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = function () {
4
- function FilterExpression(opName, args) {
5
- this.name = opName;
6
- this.args = args;
7
- }
8
-
9
- FilterExpression.prototype.toFilter = function (filterBuilder, argName) {
10
- var filterDef = {
11
- type: "expression",
12
- operator: this.name,
13
- field: argName,
14
- args: this.args
15
- };
16
- return filterDef;
17
- };
18
- return FilterExpression;
19
- }();
@@ -1,453 +0,0 @@
1
- "use strict";
2
-
3
- // valid filters:
4
- // greaterThan
5
- // inList
6
- // lessThan
7
- // lessThanOrEqual
8
- // equals
9
- // greaterThanOrEqual
10
- // notEquals
11
- // notNull
12
- // isNull
13
- // between
14
- // notInList
15
- // startsWithExactly
16
- // endsWithExactly
17
- // containsExactly
18
- // startsWith
19
- // notStartsWith
20
- // endsWith
21
- // notEndsWith
22
- // contains
23
- // notContains
24
- // upperCase
25
- // lowerCase
26
- // matchesRegex (note: this takes a string like "thomas.*is.*cool", don't include the outer slashes like /asdf/ and don't pass a regex object )
27
- // fuzzy
28
- var FilterExpression = require("./filter-expression");
29
- var _ = require("lodash");
30
-
31
- var combineQueries = require("./combine-queries");
32
-
33
- function isDateOrNumber(opName) {
34
- var _arguments = arguments;
35
-
36
- return function () {
37
- var args = [].slice.call(_arguments);
38
- if (args.some(function (arg) {
39
- return !(_.isDate(arg) || _.isString(arg) || _.isNumber(arg));
40
- })) {
41
- throw new Error("QueryBuilderError: You must pass a date or number as args to " + opName + ". You passed: Args " + args.join(","));
42
- }
43
- };
44
- }
45
- function isArray(opName) {
46
- return function (arg) {
47
- if (!_.isArray(arg)) {
48
- throw new Error("QueryBuilderError: You must pass an array for " + opName + " filters. You passed: " + arg);
49
- }
50
- };
51
- }
52
- function isString(opName) {
53
- return function (arg) {
54
- if (!_.isString(arg)) {
55
- throw new Error("QueryBuilderError: You must pass a string for " + opName + " filters. You passed: " + arg);
56
- }
57
- };
58
- }
59
-
60
- function numberOfArgs(opName, argLength) {
61
- return function () {
62
- if (arguments.length !== argLength) {
63
- throw new Error("QueryBuilderError: Args for " + opName + " are of length " + arguments.length + ", but they should be of length " + argLength);
64
- }
65
- };
66
- }
67
-
68
- var expressionOperators = [{
69
- opName: "greaterThan",
70
- sanityChecks: [numberOfArgs("greaterThan", 1), isDateOrNumber("greaterThan")]
71
- }, {
72
- opName: "inList",
73
- sanityChecks: [numberOfArgs("inList", 1), isArray("inList")]
74
- }, {
75
- opName: "lessThan",
76
- sanityChecks: [numberOfArgs("lessThan", 1), isDateOrNumber("lessThan")]
77
- }, {
78
- opName: "lessThanOrEqual",
79
- sanityChecks: [numberOfArgs("lessThanOrEqual", 1), isDateOrNumber("lessThanOrEqual")]
80
- }, {
81
- opName: "equals",
82
- sanityChecks: [numberOfArgs("equals", 1)]
83
- }, {
84
- opName: "greaterThanOrEqual",
85
- sanityChecks: [numberOfArgs("greaterThanOrEqual", 1), isDateOrNumber("greaterThanOrEqual")]
86
- }, {
87
- opName: "notEquals",
88
- sanityChecks: [numberOfArgs("notEquals", 1)]
89
- }, {
90
- opName: "notNull",
91
- sanityChecks: [numberOfArgs("notNull", 0)]
92
- }, {
93
- opName: "isNull",
94
- sanityChecks: [numberOfArgs("isNull", 0)]
95
- }, {
96
- opName: "between",
97
- sanityChecks: [numberOfArgs("between", 2), isDateOrNumber("between")]
98
- }, {
99
- opName: "notInList",
100
- sanityChecks: [numberOfArgs("notInList", 1), isArray("notInList")]
101
- }, {
102
- opName: "startsWithExactly",
103
- sanityChecks: [numberOfArgs("startsWith", 1), isString("startsWith")]
104
- }, {
105
- opName: "endsWithExactly",
106
- sanityChecks: [numberOfArgs("endsWith", 1), isString("endsWith")]
107
- }, {
108
- opName: "containsExactly",
109
- sanityChecks: [numberOfArgs("contains", 1), isString("contains")]
110
- }, {
111
- opName: "startsWith",
112
- sanityChecks: [numberOfArgs("startsWith", 1), isString("startsWith")]
113
- }, {
114
- opName: "notStartsWith",
115
- sanityChecks: [numberOfArgs("notStartsWith", 1), isString("notStartsWith")]
116
- }, {
117
- opName: "endsWith",
118
- sanityChecks: [numberOfArgs("endsWith", 1), isString("endsWith")]
119
- }, {
120
- opName: "notEndsWith",
121
- sanityChecks: [numberOfArgs("notEndsWith", 1), isString("notEndsWith")]
122
- }, {
123
- opName: "contains",
124
- sanityChecks: [numberOfArgs("contains", 1), isString("contains")]
125
- }, {
126
- opName: "notContains",
127
- sanityChecks: [numberOfArgs("notContains", 1), isString("notContains")]
128
- }, {
129
- opName: "upperCase",
130
- sanityChecks: [numberOfArgs("upperCase", 1), isString("upperCase")]
131
- }, {
132
- opName: "lowerCase",
133
- sanityChecks: [numberOfArgs("lowerCase", 1), isString("lowerCase")]
134
- }, {
135
- opName: "matchesRegex",
136
- sanityChecks: [numberOfArgs("matchesRegex", 1), isString("matchesRegex")]
137
- }, {
138
- opName: "matchesSimilar",
139
- sanityChecks: [numberOfArgs("matchesSimilar", 1), isString("matchesSimilar")]
140
- }, {
141
- opName: "fuzzy",
142
- sanityChecks: [numberOfArgs("fuzzy", 1), isString("fuzzy")],
143
- transform: function transform(arg) {
144
- // Build Regex String
145
- var matchTerm = "";
146
- // Split all the search terms
147
- var terms = arg.replace(/\W/g, "").replace(" ", "").split("");
148
- for (var i = 0; i < terms.length; i++) {
149
- matchTerm += ".*" + terms[i];
150
- }
151
- matchTerm += ".*";
152
- return {
153
- newOpName: "matchesRegex",
154
- newArgs: [matchTerm]
155
- };
156
- }
157
- }];
158
-
159
- module.exports = function () {
160
- // to be implemented
161
- //
162
- // filter - done
163
- // lessThan - done
164
- // lessThanOrEqual - done
165
- // greaterThan - done
166
- // greaterThanOrEqual - done
167
- // equals - done
168
- // notEquals - done
169
- // notNull
170
- // isNull
171
- // between
172
- // inList - done
173
- // notInList
174
- // related - done
175
- // notRelated - done
176
- // startsWith LIKE adsd%
177
- // endsWith
178
- // contains LIKE
179
- // notContains NOT LIKE
180
- // dateOnly
181
- // upperCase
182
- // lowerCase
183
- // subString
184
- // matchesRegex
185
- // count - Done
186
-
187
- // log("FilterBuilder in QueryBuilder");
188
- // log(FilterBuilder);
189
-
190
- function QueryBuilder(entity) {
191
- this.query = {};
192
-
193
- if (entity == null) throw new Error("You must pass the name of the model being filtered!");
194
-
195
- if (typeof entity === "string") {
196
- this.query = {
197
- __objectType: "query",
198
- type: "root",
199
- entity: entity,
200
- filters: []
201
- };
202
- } else {
203
- var subQuery = entity;
204
- this.query = {
205
- type: "subquery",
206
- key: subQuery.key,
207
- entity: subQuery.entity,
208
- foreignKey: subQuery.foreignKey,
209
- modifier: subQuery.modifier,
210
- filters: [],
211
- countExpression: undefined
212
- };
213
- this.parentBuilder = subQuery.parentBuilder;
214
- this.toFilter = function (filterBuilder, name) {
215
- this.query.foreignKey = name;
216
- return this.toJSON();
217
- };
218
- }
219
- }
220
-
221
- QueryBuilder.combineQueries = combineQueries;
222
-
223
- QueryBuilder.prototype.field = function (fieldName) {
224
- return {
225
- __objectType: "field",
226
- field: fieldName
227
- };
228
- };
229
-
230
- QueryBuilder.prototype.related = function (relatedEntity, isArrayRelation) {
231
- var tokens = relatedEntity.split(".");
232
- var entity = tokens[0];
233
- var key = tokens[1];
234
-
235
- // log("FilterBuilder in related");
236
- // log(FilterBuilder);
237
-
238
- return createSubQueryBuilder(this, entity, key, isArrayRelation);
239
- };
240
-
241
- QueryBuilder.prototype.notRelated = function (relatedEntity, isArrayRelation) {
242
- var tokens = relatedEntity.split(".");
243
- var entity = tokens[0];
244
- var key = tokens[1];
245
-
246
- // log("FilterBuilder in notRelated");
247
- // log(FilterBuilder);
248
-
249
- return createSubQueryBuilder(this, entity, key, isArrayRelation, "not");
250
- };
251
-
252
- QueryBuilder.prototype.toJSON = function () {
253
- var qry = JSON.parse(JSON.stringify(this.query));
254
- if (qry.filters.length > 1) {
255
- qry.filters = [{
256
- type: "group",
257
- operator: "and",
258
- chainedWith: "and",
259
- filters: qry.filters
260
- }];
261
- }
262
- return qry;
263
- };
264
-
265
- QueryBuilder.prototype.convertToFilter = function (argDef, operator) {
266
- var _this = this;
267
-
268
- var whereArgs = {};
269
- var filters = [];
270
-
271
- _.each(argDef, function (arg, name) {
272
- // log(name);
273
- // if(arg.constructor){
274
- // log(arg.constructor.name)
275
- // }else{
276
- // log("not a prototype")
277
- // }
278
- if (!isFilterExpresionOrSubQuery(name, arg)) {
279
- if (Array.isArray(arg)) {
280
- filters.push(_this.inList(arg).toFilter(_this, name));
281
- } else {
282
- //log("Is Where Filter: " + name);
283
- whereArgs[name] = arg;
284
- }
285
- } else {
286
- //log("Is Expression or SubQuery Filter: " + name);
287
- filters.push(arg.toFilter(_this, name));
288
- }
289
- });
290
- if (_.keys(whereArgs).length > 0) {
291
- filters.unshift({
292
- type: "where",
293
- args: whereArgs
294
- });
295
- }
296
-
297
- if (filters.length === 1) {
298
- return filters[0];
299
- }
300
- var filterDef = {
301
- type: "group",
302
- operator: operator || "and",
303
- filters: filters
304
- };
305
- return filterDef;
306
- };
307
-
308
- QueryBuilder.prototype.where = function () {
309
- var args = [].slice.call(arguments);
310
- return this.whereAll(args);
311
- };
312
-
313
- QueryBuilder.prototype.orWhere = function () {
314
- var args = [].slice.call(arguments);
315
- return this.orWhereAll(args);
316
- };
317
-
318
- QueryBuilder.prototype.andWhere = function () {
319
- var args = [].slice.call(arguments);
320
- return this.andWhereAll(args);
321
- };
322
-
323
- QueryBuilder.prototype.whereAny = function () {
324
- var args = [].slice.call(arguments);
325
- return whereAny(this, args);
326
- };
327
-
328
- QueryBuilder.prototype.whereAll = function () {
329
- var args = [].slice.call(arguments);
330
- return whereAll(this, args);
331
- };
332
-
333
- QueryBuilder.prototype.andWhereAny = function () {
334
- var args = [].slice.call(arguments);
335
- return whereAny(this, args, "and");
336
- };
337
-
338
- QueryBuilder.prototype.orWhereAny = function () {
339
- var args = [].slice.call(arguments);
340
- return whereAny(this, args, "or");
341
- };
342
-
343
- QueryBuilder.prototype.andWhereAll = function () {
344
- var args = [].slice.call(arguments);
345
- return whereAll(this, args, "and");
346
- };
347
-
348
- QueryBuilder.prototype.orWhereAll = function () {
349
- var args = [].slice.call(arguments);
350
- return whereAll(this, args, "or");
351
- };
352
-
353
- QueryBuilder.prototype.count = function () {
354
- var args = [].slice.call(arguments);
355
- if (this.query.type === "subquery") {
356
- if (this.query.countExpression) {
357
- throw new Error("QueryBuilder subquery can only have one count expression");
358
- }
359
- this.query.countExpression = args[0].toFilter(this, "count");
360
- } else {
361
- throw new Error("QueryBuilder is not subquery type on count expression");
362
- }
363
-
364
- return this;
365
- };
366
- QueryBuilder.ExpressionJson = {};
367
- attachExpressionFunctions();
368
-
369
- return QueryBuilder;
370
-
371
- function createSubQueryBuilder(qb, entity, key) {
372
- var isArrayRelation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
373
- var modifier = arguments[4];
374
-
375
- return new QueryBuilder({
376
- parentBuilder: qb,
377
- entity: entity,
378
- key: key,
379
- modifier: modifier,
380
- isArrayRelation: isArrayRelation
381
- });
382
- }
383
-
384
- function attachExpressionFunctions() {
385
- expressionOperators.forEach(function (_ref) {
386
- var opName = _ref.opName,
387
- sanityChecks = _ref.sanityChecks,
388
- transform = _ref.transform;
389
-
390
- var filter = function filter() {
391
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
392
- args[_key] = arguments[_key];
393
- }
394
-
395
- var argsToUse = args;
396
- var opNameToUse = opName;
397
- if (transform) {
398
- var _transform = transform.apply(undefined, args),
399
- newOpName = _transform.newOpName,
400
- newArgs = _transform.newArgs;
401
-
402
- argsToUse = newArgs;
403
- opNameToUse = newOpName;
404
- }
405
- sanityChecks.forEach(function (sanityCheck) {
406
- sanityCheck.apply(undefined, args);
407
- });
408
- return new FilterExpression(opNameToUse, argsToUse);
409
- };
410
- QueryBuilder.prototype[opName] = filter;
411
- QueryBuilder.ExpressionJson[opName] = filter;
412
- });
413
- }
414
-
415
- function isFilterExpresionOrSubQuery(name, arg) {
416
- if (arg instanceof FilterExpression) return true;
417
- if (arg instanceof QueryBuilder) return true;
418
- return false;
419
- }
420
-
421
- function whereAny(filterBuilder, whereArgs, chainedWith) {
422
- return where(filterBuilder, "or", whereArgs, chainedWith);
423
- }
424
-
425
- function whereAll(filterBuilder, whereArgs, chainedWith) {
426
- return where(filterBuilder, "and", whereArgs, chainedWith);
427
- }
428
-
429
- function where(filterBuilder, operator, whereArgs, chainedWith) {
430
- if (!Array.isArray(whereArgs)) return where(filterBuilder, operator, [whereArgs], chainedWith);
431
-
432
- var filterDef = {
433
- type: "group",
434
- operator: operator,
435
- chainedWith: chainedWith,
436
- filters: []
437
- };
438
-
439
- whereArgs.forEach(function (arg) {
440
- //add check for object type TODO
441
- var filter = filterBuilder.convertToFilter(arg, operator);
442
- filterDef.filters.push(filter);
443
- });
444
-
445
- // if (filterDef.filters.length === 1) {
446
- // filterBuilder.query.filters.push(filterDef.filters[0]);
447
- // } else {
448
- // filterBuilder.query.filters.push(filterDef);
449
- // }
450
- filterBuilder.query.filters.push(filterDef);
451
- return filterBuilder;
452
- }
453
- }();