Skip to content

Commit 9580c95

Browse files
committed
Merge pull request #47 from js-data/develop
Stable Version 0.11.7
2 parents 4830b84 + db63dd0 commit 9580c95

File tree

3 files changed

+141
-62
lines changed

3 files changed

+141
-62
lines changed

dist/js-data-sql.js

Lines changed: 130 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ module.exports =
4747

4848
'use strict';
4949

50-
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })();
51-
5250
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
5351

52+
var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; })();
53+
5454
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5555

5656
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -68,6 +68,66 @@ module.exports =
6868
return resourceConfig.table || underscore(resourceConfig.name);
6969
}
7070

71+
/**
72+
* Lookup and apply table joins to query if field contains a `.`
73+
* @param {string} field - Field defined in where filter
74+
* @param {object} query - knex query to modify
75+
* @param {object} resourceConfig - Resource of primary query/table
76+
* @param {string[]} existingJoins - Array of fully qualitifed field names for
77+
* any existing table joins for query
78+
* @returns {string} - field updated to perspective of applied joins
79+
*/
80+
function applyTableJoins(field, query, resourceConfig, existingJoins) {
81+
if (DSUtils.contains(field, '.')) {
82+
(function () {
83+
var parts = field.split('.');
84+
var localResourceConfig = resourceConfig;
85+
86+
var relationPath = [];
87+
88+
var _loop = function _loop() {
89+
var relationName = parts.shift();
90+
var relationResourceConfig = resourceConfig.getResource(relationName);
91+
relationPath.push(relationName);
92+
93+
if (!existingJoins.some(function (t) {
94+
return t === relationPath.join('.');
95+
})) {
96+
var _localResourceConfig$ = localResourceConfig.relationList.filter(function (r) {
97+
return r.relation === relationName;
98+
});
99+
100+
var _localResourceConfig$2 = _slicedToArray(_localResourceConfig$, 1);
101+
102+
var relation = _localResourceConfig$2[0];
103+
104+
if (relation) {
105+
var table = getTable(localResourceConfig);
106+
var localId = table + '.' + relation.localKey;
107+
108+
var relationTable = getTable(relationResourceConfig);
109+
var foreignId = relationTable + '.' + relationResourceConfig.idAttribute;
110+
111+
query.join(relationTable, localId, foreignId);
112+
existingJoins.push(relationPath.join('.'));
113+
} else {
114+
// hopefully a qualified local column
115+
}
116+
}
117+
localResourceConfig = relationResourceConfig;
118+
};
119+
120+
while (parts.length >= 2) {
121+
_loop();
122+
}
123+
124+
field = getTable(localResourceConfig) + '.' + parts[0];
125+
})();
126+
}
127+
128+
return field;
129+
}
130+
71131
function loadWithRelations(items, resourceConfig, options) {
72132
var _this = this;
73133

@@ -363,57 +423,30 @@ module.exports =
363423
}
364424

365425
DSUtils.forOwn(criteria, function (v, op) {
366-
if (DSUtils.contains(field, '.')) {
367-
(function () {
368-
var parts = field.split('.');
369-
var localResourceConfig = resourceConfig;
370-
371-
var relationPath = [];
372-
373-
var _loop = function _loop() {
374-
var relationName = parts.shift();
375-
var relationResourceConfig = resourceConfig.getResource(relationName);
376-
relationPath.push(relationName);
377-
378-
if (!joinedTables.some(function (t) {
379-
return t === relationPath.join('.');
380-
})) {
381-
var _localResourceConfig$ = localResourceConfig.relationList.filter(function (r) {
382-
return r.relation === relationName;
383-
});
384-
385-
var _localResourceConfig$2 = _slicedToArray(_localResourceConfig$, 1);
386-
387-
var relation = _localResourceConfig$2[0];
388-
389-
if (relation) {
390-
var _table = getTable(localResourceConfig);
391-
var localId = _table + '.' + relation.localKey;
392-
393-
var relationTable = getTable(relationResourceConfig);
394-
var foreignId = relationTable + '.' + relationResourceConfig.idAttribute;
395-
396-
query = query.join(relationTable, localId, foreignId);
397-
joinedTables.push(relationPath.join('.'));
398-
} else {
399-
// local column
400-
}
401-
}
402-
localResourceConfig = relationResourceConfig;
403-
};
404-
405-
while (parts.length >= 2) {
406-
_loop();
407-
}
408-
409-
field = getTable(localResourceConfig) + '.' + parts[0];
410-
})();
426+
// Apply table joins (if needed)
427+
if (DSUtils.contains(field, ',')) {
428+
var splitFields = field.split(',').map(function (c) {
429+
return c.trim();
430+
});
431+
field = splitFields.map(function (splitField) {
432+
return applyTableJoins(splitField, query, resourceConfig, joinedTables);
433+
}).join(',');
434+
} else {
435+
field = applyTableJoins(field, query, resourceConfig, joinedTables);
411436
}
412437

413438
if (op === '==' || op === '===') {
414-
query = query.where(field, v);
439+
if (v === null) {
440+
query = query.whereNull(field);
441+
} else {
442+
query = query.where(field, v);
443+
}
415444
} else if (op === '!=' || op === '!==') {
416-
query = query.where(field, '!=', v);
445+
if (v === null) {
446+
query = query.whereNotNull(field);
447+
} else {
448+
query = query.where(field, '!=', v);
449+
}
417450
} else if (op === '>') {
418451
query = query.where(field, '>', v);
419452
} else if (op === '>=') {
@@ -430,12 +463,58 @@ module.exports =
430463
query = query.where(field, 'in', v);
431464
} else if (op === 'notIn') {
432465
query = query.whereNotIn(field, v);
466+
} else if (op === 'near') {
467+
var milesRegex = /(\d+(\.\d+)?)\s*(m|M)iles$/;
468+
var kilometersRegex = /(\d+(\.\d+)?)\s*(k|K)$/;
469+
470+
var radius = undefined;
471+
var unitsPerDegree = undefined;
472+
if (typeof v.radius === 'number' || milesRegex.test(v.radius)) {
473+
radius = typeof v.radius === 'number' ? v.radius : v.radius.match(milesRegex)[1];
474+
unitsPerDegree = 69.0; // miles per degree
475+
} else if (kilometersRegex.test(v.radius)) {
476+
radius = v.radius.match(kilometersRegex)[1];
477+
unitsPerDegree = 111.045; // kilometers per degree;
478+
} else {
479+
throw new Error('Unknown radius distance units');
480+
}
481+
482+
var _field$split$map = field.split(',').map(function (c) {
483+
return c.trim();
484+
});
485+
486+
var _field$split$map2 = _slicedToArray(_field$split$map, 2);
487+
488+
var latitudeColumn = _field$split$map2[0];
489+
var longitudeColumn = _field$split$map2[1];
490+
491+
var _v$center = _slicedToArray(v.center, 2);
492+
493+
var latitude = _v$center[0];
494+
var longitude = _v$center[1];
495+
496+
// Uses indexes on `latitudeColumn` / `longitudeColumn` if available
497+
498+
query = query.whereBetween(latitudeColumn, [latitude - radius / unitsPerDegree, latitude + radius / unitsPerDegree]).whereBetween(longitudeColumn, [longitude - radius / (unitsPerDegree * Math.cos(latitude * (Math.PI / 180))), longitude + radius / (unitsPerDegree * Math.cos(latitude * (Math.PI / 180)))]);
499+
500+
if (v.calculateDistance) {
501+
var distanceColumn = typeof v.calculateDistance === 'string' ? v.calculateDistance : 'distance';
502+
query = query.select(knex.raw('\n ' + unitsPerDegree + ' * DEGREES(ACOS(\n COS(RADIANS(?)) * COS(RADIANS(' + latitudeColumn + ')) *\n COS(RADIANS(' + longitudeColumn + ') - RADIANS(?)) +\n SIN(RADIANS(?)) * SIN(RADIANS(' + latitudeColumn + '))\n )) AS ' + distanceColumn, [latitude, longitude, latitude]));
503+
}
433504
} else if (op === 'like') {
434505
query = query.where(field, 'like', v);
435506
} else if (op === '|==' || op === '|===') {
436-
query = query.orWhere(field, v);
507+
if (v === null) {
508+
query = query.orWhereNull(field);
509+
} else {
510+
query = query.orWhere(field, v);
511+
}
437512
} else if (op === '|!=' || op === '|!==') {
438-
query = query.orWhere(field, '!=', v);
513+
if (v === null) {
514+
query = query.orWhereNotNull(field);
515+
} else {
516+
query = query.orWhere(field, '!=', v);
517+
}
439518
} else if (op === '|>') {
440519
query = query.orWhere(field, '>', v);
441520
} else if (op === '|>=') {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "js-data-sql",
33
"description": "Postgres/MySQL/MariaDB/SQLite3 adapter for js-data.",
4-
"version": "0.11.5",
4+
"version": "0.11.7",
55
"homepage": "http://www.js-data.io/docs/dssqladapter",
66
"repository": {
77
"type": "git",

src/index.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function applyTableJoins (field, query, resourceConfig, existingJoins) {
5959
field = `${getTable(localResourceConfig)}.${parts[0]}`
6060
}
6161

62-
return field;
62+
return field
6363
}
6464

6565
function loadWithRelations (items, resourceConfig, options) {
@@ -330,9 +330,9 @@ class DSSqlAdapter {
330330
// Apply table joins (if needed)
331331
if (DSUtils.contains(field, ',')) {
332332
let splitFields = field.split(',').map(c => c.trim())
333-
field = splitFields.map(splitField => applyTableJoins(splitField, query, resourceConfig, joinedTables)).join(',');
333+
field = splitFields.map(splitField => applyTableJoins(splitField, query, resourceConfig, joinedTables)).join(',')
334334
} else {
335-
field = applyTableJoins(field, query, resourceConfig, joinedTables);
335+
field = applyTableJoins(field, query, resourceConfig, joinedTables)
336336
}
337337

338338
if (op === '==' || op === '===') {
@@ -364,23 +364,23 @@ class DSSqlAdapter {
364364
} else if (op === 'notIn') {
365365
query = query.whereNotIn(field, v)
366366
} else if (op === 'near') {
367-
const milesRegex = /(\d+(\.\d+)?)\s*(m|M)iles$/;
368-
const kilometersRegex = /(\d+(\.\d+)?)\s*(k|K)$/;
367+
const milesRegex = /(\d+(\.\d+)?)\s*(m|M)iles$/
368+
const kilometersRegex = /(\d+(\.\d+)?)\s*(k|K)$/
369369

370-
let radius;
371-
let unitsPerDegree;
370+
let radius
371+
let unitsPerDegree
372372
if (typeof v.radius === 'number' || milesRegex.test(v.radius)) {
373373
radius = typeof v.radius === 'number' ? v.radius : v.radius.match(milesRegex)[1]
374-
unitsPerDegree = 69.0; // miles per degree
374+
unitsPerDegree = 69.0 // miles per degree
375375
} else if (kilometersRegex.test(v.radius)) {
376376
radius = v.radius.match(kilometersRegex)[1]
377-
unitsPerDegree = 111.045; // kilometers per degree;
377+
unitsPerDegree = 111.045 // kilometers per degree;
378378
} else {
379379
throw new Error('Unknown radius distance units')
380380
}
381381

382382
let [latitudeColumn, longitudeColumn] = field.split(',').map(c => c.trim())
383-
let [latitude, longitude] = v.center;
383+
let [latitude, longitude] = v.center
384384

385385
// Uses indexes on `latitudeColumn` / `longitudeColumn` if available
386386
query = query

0 commit comments

Comments
 (0)