mirror of https://gitee.com/bigwinds/arangodb
1128 lines
31 KiB
JavaScript
1128 lines
31 KiB
JavaScript
/*jshint strict: false */
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief Arango Simple Query Language
|
|
// /
|
|
// / @file
|
|
// /
|
|
// / DISCLAIMER
|
|
// /
|
|
// / Copyright 2012 triagens GmbH, Cologne, Germany
|
|
// /
|
|
// / Licensed under the Apache License, Version 2.0 (the "License")
|
|
// / you may not use this file except in compliance with the License.
|
|
// / You may obtain a copy of the License at
|
|
// /
|
|
// / http://www.apache.org/licenses/LICENSE-2.0
|
|
// /
|
|
// / Unless required by applicable law or agreed to in writing, software
|
|
// / distributed under the License is distributed on an "AS IS" BASIS,
|
|
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// / See the License for the specific language governing permissions and
|
|
// / limitations under the License.
|
|
// /
|
|
// / Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
// /
|
|
// / @author Dr. Frank Celler
|
|
// / @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
var arangodb = require('@arangodb');
|
|
|
|
var ArangoError = arangodb.ArangoError;
|
|
|
|
// forward declaration
|
|
var SimpleQueryArray;
|
|
var SimpleQueryNear;
|
|
var SimpleQueryWithin;
|
|
var SimpleQueryWithinRectangle;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief array query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function GeneralArrayCursor (documents, skip, limit, data) {
|
|
this._documents = documents;
|
|
this._countTotal = documents.length;
|
|
this._skip = skip;
|
|
this._limit = limit;
|
|
this._cached = false;
|
|
this._extra = { };
|
|
|
|
var self = this;
|
|
if (data !== null && data !== undefined && typeof data === 'object') {
|
|
[ 'stats', 'warnings', 'profile' ].forEach(function (d) {
|
|
if (data.hasOwnProperty(d)) {
|
|
self._extra[d] = data[d];
|
|
}
|
|
});
|
|
this._cached = data.cached || false;
|
|
}
|
|
|
|
this.execute();
|
|
}
|
|
|
|
GeneralArrayCursor.prototype.isArangoResultSet = true;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief executes an array query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.execute = function () {
|
|
if (this._skip === null) {
|
|
this._skip = 0;
|
|
}
|
|
|
|
var len = this._documents.length;
|
|
var s = 0;
|
|
var e = len;
|
|
|
|
// skip from the beginning
|
|
if (0 < this._skip) {
|
|
s = this._skip;
|
|
|
|
if (e < s) {
|
|
s = e;
|
|
}
|
|
}
|
|
|
|
// skip from the end
|
|
else if (this._skip < 0) {
|
|
var skip = -this._skip;
|
|
|
|
if (skip < e) {
|
|
s = e - skip;
|
|
}
|
|
}
|
|
|
|
// apply limit
|
|
if (this._limit !== null) {
|
|
if (s + this._limit < e) {
|
|
e = s + this._limit;
|
|
}
|
|
}
|
|
|
|
this._current = s;
|
|
this._stop = e;
|
|
|
|
this._countQuery = e - s;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief print an all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'GeneralArrayCursor([.. ' + this._documents.length + ' docs .., cached: ' + String(this._cached);
|
|
|
|
if (this.hasOwnProperty('_extra') &&
|
|
this._extra.hasOwnProperty('warnings')) {
|
|
for (var j = 0; j < this._extra.warnings.length; j++) {
|
|
text += ', WARNING: ' + this._extra.warnings[j].code +
|
|
' - ' + this._extra.warnings[j].message;
|
|
}
|
|
}
|
|
text += '])';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief returns all elements of the cursor
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.toArray =
|
|
GeneralArrayCursor.prototype.elements = function () {
|
|
return this._documents;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief return the count of the cursor
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.count = function () {
|
|
return this._countTotal;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief return an extra value of the cursor
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.getExtra = function () {
|
|
return this._extra || { };
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief checks if the cursor is exhausted
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.hasNext = function () {
|
|
return this._current < this._stop;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief returns the next result document
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.next = function () {
|
|
if (this._current < this._stop) {
|
|
return this._documents[this._current++];
|
|
}
|
|
|
|
return undefined;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief returns an iterator for the results
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype[Symbol.iterator] = function * () {
|
|
while (this._current < this._stop) {
|
|
yield this._documents[this._current++];
|
|
}
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief drops the result
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
GeneralArrayCursor.prototype.dispose = function () {
|
|
this._documents = null;
|
|
this._skip = null;
|
|
this._limit = null;
|
|
this._countTotal = null;
|
|
this._countQuery = null;
|
|
this._current = null;
|
|
this._stop = null;
|
|
this._extra = null;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief simple query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQuery () {
|
|
this._execution = null;
|
|
this._skip = 0;
|
|
this._limit = null;
|
|
this._countQuery = null;
|
|
this._countTotal = null;
|
|
this._batchSize = null;
|
|
}
|
|
|
|
SimpleQuery.prototype.isArangoResultSet = true;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief join limits
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function joinLimits (query, limit) {
|
|
// original limit is 0, keep it
|
|
if (query._limit === 0) {
|
|
query = query.clone();
|
|
}
|
|
|
|
// new limit is 0, use it
|
|
else if (limit === 0) {
|
|
query = query.clone();
|
|
query._limit = 0;
|
|
}
|
|
|
|
// no old limit, use new limit
|
|
else if (query._limit === null) {
|
|
query = query.clone();
|
|
query._limit = limit;
|
|
}
|
|
|
|
// use the smaller one
|
|
else {
|
|
query = query.clone();
|
|
|
|
if (limit < query._limit) {
|
|
query._limit = limit;
|
|
}
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.clone = function () {
|
|
throw 'cannot clone abstract query';
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock queryExecute
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.execute = function () {
|
|
throw 'cannot execute abstract query';
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock queryLimit
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.limit = function (limit) {
|
|
if (this._execution !== null) {
|
|
throw 'query is already executing';
|
|
}
|
|
|
|
if (limit < 0) {
|
|
var err = new ArangoError();
|
|
err.errorNum = arangodb.ERROR_BAD_PARAMETER;
|
|
err.errorMessage = 'limit must be non-negative';
|
|
throw err;
|
|
}
|
|
|
|
return joinLimits(this, limit);
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock querySkip
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.skip = function (skip) {
|
|
var query;
|
|
var documents;
|
|
|
|
if (skip === undefined || skip === null) {
|
|
skip = 0;
|
|
}
|
|
|
|
if (this._execution !== null) {
|
|
throw 'query is already executing';
|
|
}
|
|
|
|
// no limit set, use or add skip
|
|
if (this._limit === null) {
|
|
query = this.clone();
|
|
|
|
if (this._skip === null || this._skip === 0) {
|
|
query._skip = skip;
|
|
}else {
|
|
query._skip += skip;
|
|
}
|
|
}
|
|
|
|
// limit already set
|
|
else {
|
|
documents = this.clone().toArray();
|
|
|
|
query = new SimpleQueryArray(documents);
|
|
query._skip = skip;
|
|
query._countTotal = documents._countTotal;
|
|
}
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief converts into an array
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.toArray = function () {
|
|
var result;
|
|
|
|
this.execute();
|
|
|
|
result = [];
|
|
|
|
while (this.hasNext()) {
|
|
result.push(this.next());
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock cursorGetBatchSize
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.getBatchSize = function () {
|
|
return this._batchSize;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock cursorSetBatchSize
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.setBatchSize = function (value) {
|
|
if (value >= 1) {
|
|
this._batchSize = value;
|
|
}
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock cursorCount
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.count = function (applyPagination) {
|
|
this.execute();
|
|
|
|
if (applyPagination === undefined || ! applyPagination) {
|
|
return this._countTotal;
|
|
}
|
|
|
|
return this._countQuery;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock cursorHasNext
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.hasNext = function () {
|
|
this.execute();
|
|
|
|
return this._execution.hasNext();
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock cursorNext
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.next = function () {
|
|
this.execute();
|
|
|
|
return this._execution.next();
|
|
};
|
|
|
|
SimpleQuery.prototype[Symbol.iterator] = function * () {
|
|
this.execute();
|
|
for (const item of this._execution) {
|
|
yield item;
|
|
}
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief was docuBlock cursorDispose
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQuery.prototype.dispose = function () {
|
|
if (this._execution !== null) {
|
|
this._execution.dispose();
|
|
}
|
|
|
|
this._execution = null;
|
|
this._countQuery = null;
|
|
this._countTotal = null;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQueryAll (collection) {
|
|
this._collection = collection;
|
|
}
|
|
|
|
SimpleQueryAll.prototype = new SimpleQuery();
|
|
SimpleQueryAll.prototype.constructor = SimpleQueryAll;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones an all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryAll.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryAll(this._collection);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief print an all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryAll.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryAll(' + this._collection.name() + ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief array query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryArray = function (documents) {
|
|
this._documents = documents;
|
|
};
|
|
|
|
SimpleQueryArray.prototype = new SimpleQuery();
|
|
SimpleQueryArray.prototype.constructor = SimpleQueryArray;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones an all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryArray.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryArray(this._documents);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief executes an all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryArray.prototype.execute = function () {
|
|
if (this._execution === null) {
|
|
if (this._skip === null) {
|
|
this._skip = 0;
|
|
}
|
|
|
|
this._execution = new GeneralArrayCursor(this._documents, this._skip, this._limit);
|
|
}
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief print an all query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryArray.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryArray(documents)';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief query-by-example
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQueryByExample (collection, example) {
|
|
this._collection = collection;
|
|
this._example = example;
|
|
}
|
|
|
|
SimpleQueryByExample.prototype = new SimpleQuery();
|
|
SimpleQueryByExample.prototype.constructor = SimpleQueryByExample;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a query-by-example
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryByExample.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryByExample(this._collection, this._example);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
query._type = this._type;
|
|
query._index = this._index;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief print a query-by-example
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryByExample.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryByExample(' + this._collection.name() + ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief query-by-condition
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQueryByCondition (collection, condition) {
|
|
this._collection = collection;
|
|
this._condition = condition;
|
|
}
|
|
|
|
SimpleQueryByCondition.prototype = new SimpleQuery();
|
|
SimpleQueryByCondition.prototype.constructor = SimpleQueryByCondition;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a query-by-condition
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryByCondition.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryByCondition(this._collection, this._condition);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
query._type = this._type;
|
|
query._index = this._index;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief print a query-by-condition
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryByCondition.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryByCondition(' + this._collection.name() + ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief range query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQueryRange (collection, attribute, left, right, type) {
|
|
this._collection = collection;
|
|
this._attribute = attribute;
|
|
this._left = left;
|
|
this._right = right;
|
|
this._type = type;
|
|
}
|
|
|
|
SimpleQueryRange.prototype = new SimpleQuery();
|
|
SimpleQueryRange.prototype.constructor = SimpleQueryRange;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a range query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryRange.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryRange(this._collection,
|
|
this._attribute,
|
|
this._left,
|
|
this._right,
|
|
this._type);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief prints a range query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryRange.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryRange(' + this._collection.name() + ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief geo index
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQueryGeo (collection, index) {
|
|
this._collection = collection;
|
|
this._index = index;
|
|
}
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief prints a geo index
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryGeo.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'GeoIndex('
|
|
+ this._collection.name()
|
|
+ ', '
|
|
+ this._index
|
|
+ ')';
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief constructs a near query for an index
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryGeo.prototype.near = function (lat, lon) {
|
|
return new SimpleQueryNear(this._collection, lat, lon, this._index);
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief constructs a within query for an index
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryGeo.prototype.within = function (lat, lon, radius) {
|
|
return new SimpleQueryWithin(this._collection, lat, lon, radius, this._index);
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief constructs a within-rectangle query for an index
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryGeo.prototype.withinRectangle = function (lat1, lon1, lat2, lon2) {
|
|
return new SimpleQueryWithinRectangle(this._collection, lat1, lon1, lat2, lon2, this._index);
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief near query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryNear = function (collection, latitude, longitude, iid) {
|
|
var idx;
|
|
var i;
|
|
|
|
this._collection = collection;
|
|
this._latitude = latitude;
|
|
this._longitude = longitude;
|
|
this._index = (iid === undefined ? null : iid);
|
|
this._distance = null;
|
|
|
|
if (iid === undefined) {
|
|
idx = collection.getIndexes();
|
|
|
|
for (i = 0; i < idx.length; ++i) {
|
|
var index = idx[i];
|
|
|
|
if (index.type === 'geo1' || index.type === 'geo2') {
|
|
if (this._index === null) {
|
|
this._index = index.id;
|
|
}
|
|
else if (index.id < this._index) {
|
|
this._index = index.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this._index === null) {
|
|
var err = new ArangoError();
|
|
err.errorNum = arangodb.ERROR_QUERY_GEO_INDEX_MISSING;
|
|
err.errorMessage = require('internal').sprintf(
|
|
arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.message,
|
|
collection.name());
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
SimpleQueryNear.prototype = new SimpleQuery();
|
|
SimpleQueryNear.prototype.constructor = SimpleQueryNear;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a near query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryNear.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryNear(this._collection, this._latitude, this._longitude, this._index);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
query._distance = this._distance;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief prints a near query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryNear.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryNear('
|
|
+ this._collection.name()
|
|
+ ', '
|
|
+ this._latitude
|
|
+ ', '
|
|
+ this._longitude
|
|
+ ', '
|
|
+ this._index
|
|
+ ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief adds the distance attribute
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryNear.prototype.distance = function (attribute) {
|
|
var clone;
|
|
|
|
clone = this.clone();
|
|
|
|
if (attribute) {
|
|
clone._distance = attribute;
|
|
}else {
|
|
clone._distance = 'distance';
|
|
}
|
|
|
|
return clone;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief within query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithin = function (collection, latitude, longitude, radius, iid) {
|
|
var idx;
|
|
var i;
|
|
|
|
this._collection = collection;
|
|
this._latitude = latitude;
|
|
this._longitude = longitude;
|
|
this._index = (iid === undefined ? null : iid);
|
|
this._radius = radius;
|
|
this._distance = null;
|
|
|
|
if (iid === undefined) {
|
|
idx = collection.getIndexes();
|
|
|
|
for (i = 0; i < idx.length; ++i) {
|
|
var index = idx[i];
|
|
|
|
if (index.type === 'geo1' || index.type === 'geo2') {
|
|
if (this._index === null) {
|
|
this._index = index.id;
|
|
}
|
|
else if (index.id < this._index) {
|
|
this._index = index.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this._index === null) {
|
|
var err = new ArangoError();
|
|
err.errorNum = arangodb.ERROR_QUERY_GEO_INDEX_MISSING;
|
|
err.errorMessage = arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.message;
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
SimpleQueryWithin.prototype = new SimpleQuery();
|
|
SimpleQueryWithin.prototype.constructor = SimpleQueryWithin;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a within query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithin.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryWithin(this._collection,
|
|
this._latitude,
|
|
this._longitude,
|
|
this._radius,
|
|
this._index);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
query._distance = this._distance;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief prints a within query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithin.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryWithin('
|
|
+ this._collection.name()
|
|
+ ', '
|
|
+ this._latitude
|
|
+ ', '
|
|
+ this._longitude
|
|
+ ', '
|
|
+ this._radius
|
|
+ ', '
|
|
+ this._index
|
|
+ ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief adds the distance attribute
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithin.prototype.distance = function (attribute) {
|
|
var clone;
|
|
|
|
clone = this.clone();
|
|
|
|
if (attribute) {
|
|
clone._distance = attribute;
|
|
}else {
|
|
clone._distance = 'distance';
|
|
}
|
|
|
|
return clone;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief within-rectangle query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithinRectangle = function (collection, latitude1, longitude1, latitude2, longitude2, iid) {
|
|
var idx;
|
|
var i;
|
|
|
|
this._collection = collection;
|
|
this._latitude1 = latitude1;
|
|
this._longitude1 = longitude1;
|
|
this._latitude2 = latitude2;
|
|
this._longitude2 = longitude2;
|
|
this._index = (iid === undefined ? null : iid);
|
|
|
|
if (iid === undefined) {
|
|
idx = collection.getIndexes();
|
|
|
|
for (i = 0; i < idx.length; ++i) {
|
|
var index = idx[i];
|
|
|
|
if (index.type === 'geo1' || index.type === 'geo2') {
|
|
if (this._index === null) {
|
|
this._index = index.id;
|
|
}
|
|
else if (index.id < this._index) {
|
|
this._index = index.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this._index === null) {
|
|
var err = new ArangoError();
|
|
err.errorNum = arangodb.ERROR_QUERY_GEO_INDEX_MISSING;
|
|
err.errorMessage = arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.message;
|
|
throw err;
|
|
}
|
|
};
|
|
|
|
SimpleQueryWithinRectangle.prototype = new SimpleQuery();
|
|
SimpleQueryWithinRectangle.prototype.constructor = SimpleQueryWithinRectangle;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a within-rectangle query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithinRectangle.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryWithinRectangle(this._collection,
|
|
this._latitude1,
|
|
this._longitude1,
|
|
this._latitude2,
|
|
this._longitude2,
|
|
this._index);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief prints a within-rectangle query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryWithinRectangle.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryWithinRectangle('
|
|
+ this._collection.name()
|
|
+ ', '
|
|
+ this._latitude1
|
|
+ ', '
|
|
+ this._longitude1
|
|
+ ', '
|
|
+ this._latitude2
|
|
+ ', '
|
|
+ this._longitude2
|
|
+ ', '
|
|
+ this._index
|
|
+ ')';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief fulltext query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
function SimpleQueryFulltext (collection, attribute, query, iid) {
|
|
this._collection = collection;
|
|
this._attribute = attribute;
|
|
this._query = query;
|
|
this._index = (iid === undefined ? null : iid);
|
|
|
|
if (iid === undefined) {
|
|
var idx = collection.getIndexes();
|
|
var i;
|
|
|
|
for (i = 0; i < idx.length; ++i) {
|
|
var index = idx[i];
|
|
|
|
if (index.type === 'fulltext' && index.fields[0] === attribute) {
|
|
if (this._index === null) {
|
|
this._index = index.id;
|
|
}
|
|
else if (index.indexSubstrings && ! this._index.indexSubstrings) {
|
|
// prefer indexes that have substrings indexed
|
|
this._index = index.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this._index === null) {
|
|
var err = new ArangoError();
|
|
err.errorNum = arangodb.ERROR_QUERY_FULLTEXT_INDEX_MISSING;
|
|
err.errorMessage = require('internal').sprintf(
|
|
arangodb.errors.ERROR_QUERY_FULLTEXT_INDEX_MISSING.message,
|
|
collection.name());
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
SimpleQueryFulltext.prototype = new SimpleQuery();
|
|
SimpleQueryFulltext.prototype.constructor = SimpleQueryFulltext;
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief clones a fulltext query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryFulltext.prototype.clone = function () {
|
|
var query;
|
|
|
|
query = new SimpleQueryFulltext(this._collection, this._attribute, this._query, this._index);
|
|
query._skip = this._skip;
|
|
query._limit = this._limit;
|
|
|
|
return query;
|
|
};
|
|
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
// / @brief prints a fulltext query
|
|
// //////////////////////////////////////////////////////////////////////////////
|
|
|
|
SimpleQueryFulltext.prototype._PRINT = function (context) {
|
|
var text;
|
|
|
|
text = 'SimpleQueryFulltext('
|
|
+ this._collection.name()
|
|
+ ', '
|
|
+ this._attribute
|
|
+ ', "'
|
|
+ this._query
|
|
+ '")';
|
|
|
|
if (this._skip !== null && this._skip !== 0) {
|
|
text += '.skip(' + this._skip + ')';
|
|
}
|
|
|
|
if (this._limit !== null) {
|
|
text += '.limit(' + this._limit + ')';
|
|
}
|
|
|
|
context.output += text;
|
|
};
|
|
|
|
exports.GeneralArrayCursor = GeneralArrayCursor;
|
|
exports.SimpleQueryAll = SimpleQueryAll;
|
|
exports.SimpleQueryArray = SimpleQueryArray;
|
|
exports.SimpleQueryByExample = SimpleQueryByExample;
|
|
exports.SimpleQueryByCondition = SimpleQueryByCondition;
|
|
exports.SimpleQueryRange = SimpleQueryRange;
|
|
exports.SimpleQueryGeo = SimpleQueryGeo;
|
|
exports.SimpleQueryNear = SimpleQueryNear;
|
|
exports.SimpleQueryWithin = SimpleQueryWithin;
|
|
exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle;
|
|
exports.SimpleQueryFulltext = SimpleQueryFulltext;
|