Skip to content

Commit 87e78de

Browse files
committed
Stable Version 0.11.6
1 parent 34e12e5 commit 87e78de

File tree

2 files changed

+111
-48
lines changed

2 files changed

+111
-48
lines changed

dist/js-data-sql.js

Lines changed: 110 additions & 47 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,51 +423,16 @@ 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 === '===') {
@@ -430,6 +455,44 @@ module.exports =
430455
query = query.where(field, 'in', v);
431456
} else if (op === 'notIn') {
432457
query = query.whereNotIn(field, v);
458+
} else if (op === 'near') {
459+
var milesRegex = /(\d+(\.\d+)?)\s*(m|M)iles$/;
460+
var kilometersRegex = /(\d+(\.\d+)?)\s*(k|K)$/;
461+
462+
var radius = undefined;
463+
var unitsPerDegree = undefined;
464+
if (typeof v.radius === 'number' || milesRegex.test(v.radius)) {
465+
radius = typeof v.radius === 'number' ? v.radius : v.radius.match(milesRegex)[1];
466+
unitsPerDegree = 69.0; // miles per degree
467+
} else if (kilometersRegex.test(v.radius)) {
468+
radius = v.radius.match(kilometersRegex)[1];
469+
unitsPerDegree = 111.045; // kilometers per degree;
470+
} else {
471+
throw new Error('Unknown radius distance units');
472+
}
473+
474+
var _field$split$map = field.split(',').map(function (c) {
475+
return c.trim();
476+
});
477+
478+
var _field$split$map2 = _slicedToArray(_field$split$map, 2);
479+
480+
var latitudeColumn = _field$split$map2[0];
481+
var longitudeColumn = _field$split$map2[1];
482+
483+
var _v$center = _slicedToArray(v.center, 2);
484+
485+
var latitude = _v$center[0];
486+
var longitude = _v$center[1];
487+
488+
// Uses indexes on `latitudeColumn` / `longitudeColumn` if available
489+
490+
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)))]);
491+
492+
if (v.calculateDistance) {
493+
var distanceColumn = typeof v.calculateDistance === 'string' ? v.calculateDistance : 'distance';
494+
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]));
495+
}
433496
} else if (op === 'like') {
434497
query = query.where(field, 'like', v);
435498
} else if (op === '|==' || 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.6",
55
"homepage": "http://www.js-data.io/docs/dssqladapter",
66
"repository": {
77
"type": "git",

0 commit comments

Comments
 (0)