@@ -156,6 +156,12 @@ class DSSqlAdapter {
156
156
constructor ( options ) {
157
157
this . defaults = { }
158
158
options = options || { }
159
+
160
+ if ( options . queryOperators ) {
161
+ this . queryOperators = options . queryOperators ;
162
+ delete options . queryOperators ;
163
+ }
164
+
159
165
if ( options . __knex__ ) {
160
166
this . query = options
161
167
} else {
@@ -347,107 +353,113 @@ class DSSqlAdapter {
347
353
}
348
354
349
355
forOwn ( criteria , ( v , op ) => {
350
- if ( op === '==' || op === '===' ) {
351
- if ( v === null ) {
352
- query = query . whereNull ( field )
353
- } else {
354
- query = query . where ( field , v )
355
- }
356
- } else if ( op === '!=' || op === '!==' ) {
357
- if ( v === null ) {
358
- query = query . whereNotNull ( field )
359
- } else {
360
- query = query . where ( field , '!=' , v )
361
- }
362
- } else if ( op === '>' ) {
363
- query = query . where ( field , '>' , v )
364
- } else if ( op === '>=' ) {
365
- query = query . where ( field , '>=' , v )
366
- } else if ( op === '<' ) {
367
- query = query . where ( field , '<' , v )
368
- } else if ( op === '<=' ) {
369
- query = query . where ( field , '<=' , v )
370
- // } else if (op === 'isectEmpty') {
371
- // subQuery = subQuery ? subQuery.and(row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)
372
- // } else if (op === 'isectNotEmpty') {
373
- // subQuery = subQuery ? subQuery.and(row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)
374
- } else if ( op === 'in' ) {
375
- query = query . where ( field , 'in' , v )
376
- } else if ( op === 'notIn' ) {
377
- query = query . whereNotIn ( field , v )
378
- } else if ( op === 'near' ) {
379
- const milesRegex = / ( \d + ( \. \d + ) ? ) \s * ( m | M ) i l e s $ /
380
- const kilometersRegex = / ( \d + ( \. \d + ) ? ) \s * ( k | K ) $ /
381
-
382
- let radius
383
- let unitsPerDegree
384
- if ( typeof v . radius === 'number' || milesRegex . test ( v . radius ) ) {
385
- radius = typeof v . radius === 'number' ? v . radius : v . radius . match ( milesRegex ) [ 1 ]
386
- unitsPerDegree = 69.0 // miles per degree
387
- } else if ( kilometersRegex . test ( v . radius ) ) {
388
- radius = v . radius . match ( kilometersRegex ) [ 1 ]
389
- unitsPerDegree = 111.045 // kilometers per degree;
390
- } else {
391
- throw new Error ( 'Unknown radius distance units' )
392
- }
356
+ if ( op in ( this . queryOperators || { } ) ) {
357
+ // Custom or overridden operator
358
+ query = this . queryOperators [ op ] ( query , field , v )
359
+ } else {
360
+ // Builtin operators
361
+ if ( op === '==' || op === '===' ) {
362
+ if ( v === null ) {
363
+ query = query . whereNull ( field )
364
+ } else {
365
+ query . where ( field , v )
366
+ }
367
+ } else if ( op === '!=' || op === '!==' ) {
368
+ if ( v === null ) {
369
+ query = query . whereNotNull ( field )
370
+ } else {
371
+ query = query . where ( field , '!=' , v )
372
+ }
373
+ } else if ( op === '>' ) {
374
+ query = query . where ( field , '>' , v )
375
+ } else if ( op === '>=' ) {
376
+ query = query . where ( field , '>=' , v )
377
+ } else if ( op === '<' ) {
378
+ query = query . where ( field , '<' , v )
379
+ } else if ( op === '<=' ) {
380
+ query = query . where ( field , '<=' , v )
381
+ // } else if (op === 'isectEmpty') {
382
+ // subQuery = subQuery ? subQuery.and(row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)
383
+ // } else if (op === 'isectNotEmpty') {
384
+ // subQuery = subQuery ? subQuery.and(row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)
385
+ } else if ( op === 'in' ) {
386
+ query = query . where ( field , 'in' , v )
387
+ } else if ( op === 'notIn' ) {
388
+ query = query . whereNotIn ( field , v )
389
+ } else if ( op === 'near' ) {
390
+ const milesRegex = / ( \d + ( \. \d + ) ? ) \s * ( m | M ) i l e s $ /
391
+ const kilometersRegex = / ( \d + ( \. \d + ) ? ) \s * ( k | K ) $ /
392
+
393
+ let radius
394
+ let unitsPerDegree
395
+ if ( typeof v . radius === 'number' || milesRegex . test ( v . radius ) ) {
396
+ radius = typeof v . radius === 'number' ? v . radius : v . radius . match ( milesRegex ) [ 1 ]
397
+ unitsPerDegree = 69.0 // miles per degree
398
+ } else if ( kilometersRegex . test ( v . radius ) ) {
399
+ radius = v . radius . match ( kilometersRegex ) [ 1 ]
400
+ unitsPerDegree = 111.045 // kilometers per degree;
401
+ } else {
402
+ throw new Error ( 'Unknown radius distance units' )
403
+ }
393
404
394
- let [ latitudeColumn , longitudeColumn ] = field . split ( ',' ) . map ( c => c . trim ( ) )
395
- let [ latitude , longitude ] = v . center
396
-
397
- // Uses indexes on `latitudeColumn` / `longitudeColumn` if available
398
- query = query
399
- . whereBetween ( latitudeColumn , [
400
- latitude - ( radius / unitsPerDegree ) ,
401
- latitude + ( radius / unitsPerDegree )
402
- ] )
403
- . whereBetween ( longitudeColumn , [
404
- longitude - ( radius / ( unitsPerDegree * Math . cos ( latitude * ( Math . PI / 180 ) ) ) ) ,
405
- longitude + ( radius / ( unitsPerDegree * Math . cos ( latitude * ( Math . PI / 180 ) ) ) )
406
- ] )
407
-
408
- if ( v . calculateDistance ) {
409
- let distanceColumn = ( typeof v . calculateDistance === 'string' ) ? v . calculateDistance : 'distance'
410
- query = query . select ( knex . raw ( `
411
- ${ unitsPerDegree } * DEGREES(ACOS(
412
- COS(RADIANS(?)) * COS(RADIANS(${ latitudeColumn } )) *
413
- COS(RADIANS(${ longitudeColumn } ) - RADIANS(?)) +
414
- SIN(RADIANS(?)) * SIN(RADIANS(${ latitudeColumn } ))
415
- )) AS ${ distanceColumn } ` , [ latitude , longitude , latitude ] ) )
416
- }
417
- } else if ( op === 'like' ) {
418
- query = query . where ( field , 'like' , v )
419
- } else if ( op === '|like' ) {
420
- query = query . orWhere ( field , 'like' , v )
421
- } else if ( op === '|==' || op === '|===' ) {
422
- if ( v === null ) {
423
- query = query . orWhereNull ( field )
424
- } else {
425
- query = query . orWhere ( field , v )
426
- }
427
- } else if ( op === '|!=' || op === '|!==' ) {
428
- if ( v === null ) {
429
- query = query . orWhereNotNull ( field )
405
+ let [ latitudeColumn , longitudeColumn ] = field . split ( ',' ) . map ( c => c . trim ( ) )
406
+ let [ latitude , longitude ] = v . center
407
+
408
+ // Uses indexes on `latitudeColumn` / `longitudeColumn` if available
409
+ query = query
410
+ . whereBetween ( latitudeColumn , [
411
+ latitude - ( radius / unitsPerDegree ) ,
412
+ latitude + ( radius / unitsPerDegree )
413
+ ] )
414
+ . whereBetween ( longitudeColumn , [
415
+ longitude - ( radius / ( unitsPerDegree * Math . cos ( latitude * ( Math . PI / 180 ) ) ) ) ,
416
+ longitude + ( radius / ( unitsPerDegree * Math . cos ( latitude * ( Math . PI / 180 ) ) ) )
417
+ ] )
418
+
419
+ if ( v . calculateDistance ) {
420
+ let distanceColumn = ( typeof v . calculateDistance === 'string' ) ? v . calculateDistance : 'distance'
421
+ query = query . select ( knex . raw ( `
422
+ ${ unitsPerDegree } * DEGREES(ACOS(
423
+ COS(RADIANS(?)) * COS(RADIANS(${ latitudeColumn } )) *
424
+ COS(RADIANS(${ longitudeColumn } ) - RADIANS(?)) +
425
+ SIN(RADIANS(?)) * SIN(RADIANS(${ latitudeColumn } ))
426
+ )) AS ${ distanceColumn } ` , [ latitude , longitude , latitude ] ) )
427
+ }
428
+ } else if ( op === 'like' ) {
429
+ query = query . where ( field , 'like' , v )
430
+ } else if ( op === '|like' ) {
431
+ query = query . orWhere ( field , 'like' , v )
432
+ } else if ( op === '|==' || op === '|===' ) {
433
+ if ( v === null ) {
434
+ query = query . orWhereNull ( field )
435
+ } else {
436
+ query = query . orWhere ( field , v )
437
+ }
438
+ } else if ( op === '|!=' || op === '|!==' ) {
439
+ if ( v === null ) {
440
+ query = query . orWhereNotNull ( field )
441
+ } else {
442
+ query = query . orWhere ( field , '!=' , v )
443
+ }
444
+ } else if ( op === '|>' ) {
445
+ query = query . orWhere ( field , '>' , v )
446
+ } else if ( op === '|>=' ) {
447
+ query = query . orWhere ( field , '>=' , v )
448
+ } else if ( op === '|<' ) {
449
+ query = query . orWhere ( field , '<' , v )
450
+ } else if ( op === '|<=' ) {
451
+ query = query . orWhere ( field , '<=' , v )
452
+ // } else if (op === '|isectEmpty') {
453
+ // subQuery = subQuery ? subQuery.or(row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)
454
+ // } else if (op === '|isectNotEmpty') {
455
+ // subQuery = subQuery ? subQuery.or(row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)
456
+ } else if ( op === '|in' ) {
457
+ query = query . orWhere ( field , 'in' , v )
458
+ } else if ( op === '|notIn' ) {
459
+ query = query . orWhereNotIn ( field , v )
430
460
} else {
431
- query = query . orWhere ( field , '!=' , v )
461
+ throw new Error ( 'Operator not found' )
432
462
}
433
- } else if ( op === '|>' ) {
434
- query = query . orWhere ( field , '>' , v )
435
- } else if ( op === '|>=' ) {
436
- query = query . orWhere ( field , '>=' , v )
437
- } else if ( op === '|<' ) {
438
- query = query . orWhere ( field , '<' , v )
439
- } else if ( op === '|<=' ) {
440
- query = query . orWhere ( field , '<=' , v )
441
- // } else if (op === '|isectEmpty') {
442
- // subQuery = subQuery ? subQuery.or(row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().eq(0)
443
- // } else if (op === '|isectNotEmpty') {
444
- // subQuery = subQuery ? subQuery.or(row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)) : row(field).default([]).setIntersection(r.expr(v).default([])).count().ne(0)
445
- } else if ( op === '|in' ) {
446
- query = query . orWhere ( field , 'in' , v )
447
- } else if ( op === '|notIn' ) {
448
- query = query . orWhereNotIn ( field , v )
449
- } else {
450
- throw new Error ( 'Operator not found' )
451
463
}
452
464
} )
453
465
} )
0 commit comments