Skip to content

Commit

Permalink
Merge pull request #47 from js-data/develop
Browse files Browse the repository at this point in the history
Stable Version 0.11.7
  • Loading branch information
techniq committed Dec 7, 2015
2 parents 4830b84 + db63dd0 commit 9580c95
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 62 deletions.
181 changes: 130 additions & 51 deletions dist/js-data-sql.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ module.exports =

'use strict';

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"); } }; })();

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; }; })();

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"); } }; })();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

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; }
Expand All @@ -68,6 +68,66 @@ module.exports =
return resourceConfig.table || underscore(resourceConfig.name);
}

/**
* Lookup and apply table joins to query if field contains a `.`
* @param {string} field - Field defined in where filter
* @param {object} query - knex query to modify
* @param {object} resourceConfig - Resource of primary query/table
* @param {string[]} existingJoins - Array of fully qualitifed field names for
* any existing table joins for query
* @returns {string} - field updated to perspective of applied joins
*/
function applyTableJoins(field, query, resourceConfig, existingJoins) {
if (DSUtils.contains(field, '.')) {
(function () {
var parts = field.split('.');
var localResourceConfig = resourceConfig;

var relationPath = [];

var _loop = function _loop() {
var relationName = parts.shift();
var relationResourceConfig = resourceConfig.getResource(relationName);
relationPath.push(relationName);

if (!existingJoins.some(function (t) {
return t === relationPath.join('.');
})) {
var _localResourceConfig$ = localResourceConfig.relationList.filter(function (r) {
return r.relation === relationName;
});

var _localResourceConfig$2 = _slicedToArray(_localResourceConfig$, 1);

var relation = _localResourceConfig$2[0];

if (relation) {
var table = getTable(localResourceConfig);
var localId = table + '.' + relation.localKey;

var relationTable = getTable(relationResourceConfig);
var foreignId = relationTable + '.' + relationResourceConfig.idAttribute;

query.join(relationTable, localId, foreignId);
existingJoins.push(relationPath.join('.'));
} else {
// hopefully a qualified local column
}
}
localResourceConfig = relationResourceConfig;
};

while (parts.length >= 2) {
_loop();
}

field = getTable(localResourceConfig) + '.' + parts[0];
})();
}

return field;
}

function loadWithRelations(items, resourceConfig, options) {
var _this = this;

Expand Down Expand Up @@ -363,57 +423,30 @@ module.exports =
}

DSUtils.forOwn(criteria, function (v, op) {
if (DSUtils.contains(field, '.')) {
(function () {
var parts = field.split('.');
var localResourceConfig = resourceConfig;

var relationPath = [];

var _loop = function _loop() {
var relationName = parts.shift();
var relationResourceConfig = resourceConfig.getResource(relationName);
relationPath.push(relationName);

if (!joinedTables.some(function (t) {
return t === relationPath.join('.');
})) {
var _localResourceConfig$ = localResourceConfig.relationList.filter(function (r) {
return r.relation === relationName;
});

var _localResourceConfig$2 = _slicedToArray(_localResourceConfig$, 1);

var relation = _localResourceConfig$2[0];

if (relation) {
var _table = getTable(localResourceConfig);
var localId = _table + '.' + relation.localKey;

var relationTable = getTable(relationResourceConfig);
var foreignId = relationTable + '.' + relationResourceConfig.idAttribute;

query = query.join(relationTable, localId, foreignId);
joinedTables.push(relationPath.join('.'));
} else {
// local column
}
}
localResourceConfig = relationResourceConfig;
};

while (parts.length >= 2) {
_loop();
}

field = getTable(localResourceConfig) + '.' + parts[0];
})();
// Apply table joins (if needed)
if (DSUtils.contains(field, ',')) {
var splitFields = field.split(',').map(function (c) {
return c.trim();
});
field = splitFields.map(function (splitField) {
return applyTableJoins(splitField, query, resourceConfig, joinedTables);
}).join(',');
} else {
field = applyTableJoins(field, query, resourceConfig, joinedTables);
}

if (op === '==' || op === '===') {
query = query.where(field, v);
if (v === null) {
query = query.whereNull(field);
} else {
query = query.where(field, v);
}
} else if (op === '!=' || op === '!==') {
query = query.where(field, '!=', v);
if (v === null) {
query = query.whereNotNull(field);
} else {
query = query.where(field, '!=', v);
}
} else if (op === '>') {
query = query.where(field, '>', v);
} else if (op === '>=') {
Expand All @@ -430,12 +463,58 @@ module.exports =
query = query.where(field, 'in', v);
} else if (op === 'notIn') {
query = query.whereNotIn(field, v);
} else if (op === 'near') {
var milesRegex = /(\d+(\.\d+)?)\s*(m|M)iles$/;
var kilometersRegex = /(\d+(\.\d+)?)\s*(k|K)$/;

var radius = undefined;
var unitsPerDegree = undefined;
if (typeof v.radius === 'number' || milesRegex.test(v.radius)) {
radius = typeof v.radius === 'number' ? v.radius : v.radius.match(milesRegex)[1];
unitsPerDegree = 69.0; // miles per degree
} else if (kilometersRegex.test(v.radius)) {
radius = v.radius.match(kilometersRegex)[1];
unitsPerDegree = 111.045; // kilometers per degree;
} else {
throw new Error('Unknown radius distance units');
}

var _field$split$map = field.split(',').map(function (c) {
return c.trim();
});

var _field$split$map2 = _slicedToArray(_field$split$map, 2);

var latitudeColumn = _field$split$map2[0];
var longitudeColumn = _field$split$map2[1];

var _v$center = _slicedToArray(v.center, 2);

var latitude = _v$center[0];
var longitude = _v$center[1];

// Uses indexes on `latitudeColumn` / `longitudeColumn` if available

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)))]);

if (v.calculateDistance) {
var distanceColumn = typeof v.calculateDistance === 'string' ? v.calculateDistance : 'distance';
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]));
}
} else if (op === 'like') {
query = query.where(field, 'like', v);
} else if (op === '|==' || op === '|===') {
query = query.orWhere(field, v);
if (v === null) {
query = query.orWhereNull(field);
} else {
query = query.orWhere(field, v);
}
} else if (op === '|!=' || op === '|!==') {
query = query.orWhere(field, '!=', v);
if (v === null) {
query = query.orWhereNotNull(field);
} else {
query = query.orWhere(field, '!=', v);
}
} else if (op === '|>') {
query = query.orWhere(field, '>', v);
} else if (op === '|>=') {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "js-data-sql",
"description": "Postgres/MySQL/MariaDB/SQLite3 adapter for js-data.",
"version": "0.11.5",
"version": "0.11.7",
"homepage": "http://www.js-data.io/docs/dssqladapter",
"repository": {
"type": "git",
Expand Down
20 changes: 10 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function applyTableJoins (field, query, resourceConfig, existingJoins) {
field = `${getTable(localResourceConfig)}.${parts[0]}`
}

return field;
return field
}

function loadWithRelations (items, resourceConfig, options) {
Expand Down Expand Up @@ -330,9 +330,9 @@ class DSSqlAdapter {
// Apply table joins (if needed)
if (DSUtils.contains(field, ',')) {
let splitFields = field.split(',').map(c => c.trim())
field = splitFields.map(splitField => applyTableJoins(splitField, query, resourceConfig, joinedTables)).join(',');
field = splitFields.map(splitField => applyTableJoins(splitField, query, resourceConfig, joinedTables)).join(',')
} else {
field = applyTableJoins(field, query, resourceConfig, joinedTables);
field = applyTableJoins(field, query, resourceConfig, joinedTables)
}

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

let radius;
let unitsPerDegree;
let radius
let unitsPerDegree
if (typeof v.radius === 'number' || milesRegex.test(v.radius)) {
radius = typeof v.radius === 'number' ? v.radius : v.radius.match(milesRegex)[1]
unitsPerDegree = 69.0; // miles per degree
unitsPerDegree = 69.0 // miles per degree
} else if (kilometersRegex.test(v.radius)) {
radius = v.radius.match(kilometersRegex)[1]
unitsPerDegree = 111.045; // kilometers per degree;
unitsPerDegree = 111.045 // kilometers per degree;
} else {
throw new Error('Unknown radius distance units')
}

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

// Uses indexes on `latitudeColumn` / `longitudeColumn` if available
query = query
Expand Down

0 comments on commit 9580c95

Please sign in to comment.