diff --git a/addon/query/indexeddb-adapter.js b/addon/query/indexeddb-adapter.js index e7befaeb..0ced26f3 100644 --- a/addon/query/indexeddb-adapter.js +++ b/addon/query/indexeddb-adapter.js @@ -10,8 +10,7 @@ import { StringPredicate, DetailPredicate, DatePredicate, - GeographyPredicate, - GeometryPredicate, + SpatialPredicate, TruePredicate, FalsePredicate } from './predicate'; @@ -610,13 +609,8 @@ function updateWhereClause(store, table, query) { } } - if (predicate instanceof GeographyPredicate) { - Ember.warn('GeographyPredicate is not supported in indexedDB-adapter'); - return table; - } - - if (predicate instanceof GeometryPredicate) { - Ember.warn('GeometryPredicate is not supported in indexedDB-adapter'); + if (predicate instanceof SpatialPredicate) { + Ember.warn('SpatialPredicate subtypes are not supported in indexedDB-adapter'); return table; } diff --git a/addon/query/js-adapter.js b/addon/query/js-adapter.js index 686a7e9d..b73b201a 100644 --- a/addon/query/js-adapter.js +++ b/addon/query/js-adapter.js @@ -6,8 +6,7 @@ import { StringPredicate, DetailPredicate, DatePredicate, - GeographyPredicate, - GeometryPredicate, + SpatialPredicate, TruePredicate, FalsePredicate } from './predicate'; @@ -253,24 +252,16 @@ export default class JSAdapter extends BaseAdapter { let b2 = predicate instanceof StringPredicate; let b3 = predicate instanceof DetailPredicate; let b4 = predicate instanceof DatePredicate; - let b5 = predicate instanceof GeographyPredicate; - let b6 = predicate instanceof GeometryPredicate; - let b7 = predicate instanceof TruePredicate; - let b8 = predicate instanceof FalsePredicate; - if (b1 || b2 || b3 || b4 || b7 || b8) { + let b5 = predicate instanceof SpatialPredicate; + let b6 = predicate instanceof TruePredicate; + let b7 = predicate instanceof FalsePredicate; + if (b1 || b2 || b3 || b4 || b6 || b7) { let filterFunction = this.getAttributeFilterFunction(predicate, options); return this.getFilterFunctionAnd([filterFunction]); } if (b5) { - Ember.warn('GeographyPredicate is not supported in js-adapter'); - return function (data) { - return data; - }; - } - - if (b6) { - Ember.warn('GeometryPredicate is not supported in js-adapter'); + Ember.warn('SpatialPredicate subtypes are not supported in js-adapter'); return function (data) { return data; }; diff --git a/addon/query/odata-adapter.js b/addon/query/odata-adapter.js index 43a4c663..b20235ad 100644 --- a/addon/query/odata-adapter.js +++ b/addon/query/odata-adapter.js @@ -8,8 +8,7 @@ import { StringPredicate, DetailPredicate, DatePredicate, - GeographyPredicate, - GeometryPredicate, + SpatialPredicate, NotPredicate, IsOfPredicate, TruePredicate, @@ -268,22 +267,17 @@ export default class ODataAdapter extends BaseAdapter { return `isof(${expression},'${namespace}.${className}')`; } - if (predicate instanceof GeographyPredicate) { + if (predicate instanceof SpatialPredicate) { let attribute = this._getODataAttributeName(modelName, predicate.attributePath); if (prefix) { attribute = `${prefix}/${attribute}`; } - return `geo.intersects(geography1=${attribute},geography2=geography'${predicate.intersectsValue}')`; - } - - if (predicate instanceof GeometryPredicate) { - let attribute = this._getODataAttributeName(modelName, predicate.attributePath); - if (prefix) { - attribute = `${prefix}/${attribute}`; - } - - return `geom.intersects(geometry1=${attribute},geometry2=geometry'${predicate.intersectsValue}')`; + let ns = predicate.spatialNamespace; + let tp = predicate.spatialType; + let fn = predicate.spatialFunction; + let vl = predicate.spatialValue; + return `${ns}.${fn}(${tp}1=${attribute},${tp}2=${tp}'${vl}')`; } if (predicate instanceof DetailPredicate) { diff --git a/addon/query/predicate.js b/addon/query/predicate.js index 80266e73..16093f5b 100644 --- a/addon/query/predicate.js +++ b/addon/query/predicate.js @@ -293,25 +293,26 @@ export class StringPredicate extends BasePredicate { } /** - * The predicate class for geography attributes. + * The base class of logical predicate for spatial attributes. * * @namespace Query - * @class GeographyPredicate + * @class SpatialPredicate * @extends BasePredicate * * @param {String} attributePath The path to the attribute for predicate. * @constructor */ -export class GeographyPredicate extends BasePredicate { +export class SpatialPredicate extends BasePredicate { constructor(attributePath) { super(); if (!attributePath) { - throw new Error('Attribute path is required for GeographyPredicate constructor.'); + throw new Error('Attribute path is required for SpatialPredicate constructor.'); } this._attributePath = attributePath; - this._intersectsValue = null; + this._function = null; + this._value = null; } /** @@ -326,85 +327,138 @@ export class GeographyPredicate extends BasePredicate { } /** - * The geography value that has to intersect with the attribute. + * The spatial function to call. * - * @property intersectsValue + * @property spatialFunction * @type {String} * @public */ - get intersectsValue() { - return this._intersectsValue; + get spatialFunction() { + return this._function; } /** - * Sets the value that the attribute has to contain. + * The spatial value that has to be the second argument of the spatial function, + * assuming the attribute is the first argument. + * + * @property spatialValue + * @type {String} + * @public + */ + get spatialValue() { + return this._value; + } + + /** + * The spatial type namespace. + * + * @property spatialNamespace + * @type {String} + * @public + */ + get spatialNamespace() { + return null; + } + + /** + * The spatial type. + * + * @property spatialType + * @type {String} + * @public + */ + get spatialType() { + return null; + } + + /** + * Sets the spatial type value that has to intersect with the attribute. * * @method contains - * @param {String} geography The geography value that has to intersect with the attribute. - * @return {Query.StringPredicate} Returns this instance. + * @param {String} value The spatial type value that has to intersect with the attribute. + * @return {Query.SpatialPredicate} Returns this instance. * @chainable */ - intersects(geography) { - this._intersectsValue = geography; + intersects(value) { + this._function = 'intersects'; + this._value = value; return this; } } /** - * The predicate class for geometry attributes. + * The predicate class for geography attributes. * * @namespace Query - * @class GeometryPredicate - * @extends BasePredicate + * @class GeographyPredicate + * @extends SpatialPredicate * * @param {String} attributePath The path to the attribute for predicate. * @constructor */ -export class GeometryPredicate extends BasePredicate { +export class GeographyPredicate extends SpatialPredicate { constructor(attributePath) { - super(); - - if (!attributePath) { - throw new Error('Attribute path is required for GeometryPredicate constructor.'); - } + super(... arguments); + } - this._attributePath = attributePath; - this._intersectsValue = null; + /** + * The geography type namespace. + * + * @property spatialNamespace + * @type {String} + * @public + */ + get spatialNamespace() { + return 'geo'; } /** - * The path to the attribute for predicate. + * The geography type. * - * @property attributePath + * @property spatialType * @type {String} * @public */ - get attributePath() { - return this._attributePath; + get spatialType() { + return 'geography'; + } +} + +/** + * The predicate class for geometry attributes. + * + * @namespace Query + * @class GeometryPredicate + * @extends SpatialPredicate + * + * @param {String} attributePath The path to the attribute for predicate. + * @constructor + */ +export class GeometryPredicate extends SpatialPredicate { + constructor(attributePath) { + super(... arguments); } /** - * The geometry value that has to intersect with the attribute. + * The geometry type namespace. * - * @property intersectsValue + * @property spatialNamespace * @type {String} * @public */ - get intersectsValue() { - return this._intersectsValue; + get spatialNamespace() { + return 'geom'; } /** - * Sets the value that the attribute has to contain. + * The geometry type. * - * @method contains - * @param {String} geometry The geometry value that has to intersect with the attribute. - * @return {Query.StringPredicate} Returns this instance. - * @chainable + * @property spatialType + * @type {String} + * @public */ - intersects(geometry) { - this._intersectsValue = geometry; - return this; + get spatialType() { + return 'geometry'; } }