/*jshint strict: false, unused: false, maxlen: 200 */ //////////////////////////////////////////////////////////////////////////////// /// @brief ArangoCollection /// /// @file /// /// DISCLAIMER /// /// Copyright 2011-2013 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 2011-2013, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// var ArangoCollection = require("@arangodb/arango-collection").ArangoCollection; var arangodb = require("@arangodb"); var ArangoError = arangodb.ArangoError; var sprintf = arangodb.sprintf; var db = arangodb.db; var simple = require("@arangodb/simple-query"); var SimpleQueryAll = simple.SimpleQueryAll; var SimpleQueryByExample = simple.SimpleQueryByExample; var SimpleQueryByCondition = simple.SimpleQueryByCondition; var SimpleQueryRange = simple.SimpleQueryRange; var SimpleQueryGeo = simple.SimpleQueryGeo; var SimpleQueryNear = simple.SimpleQueryNear; var SimpleQueryWithin = simple.SimpleQueryWithin; var SimpleQueryWithinRectangle = simple.SimpleQueryWithinRectangle; var SimpleQueryFulltext = simple.SimpleQueryFulltext; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is corrupted //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_CORRUPTED = 0; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is new born /// @deprecated //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_NEW_BORN = 1; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is unloaded //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_UNLOADED = 2; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is loaded //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_LOADED = 3; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is unloading //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_UNLOADING = 4; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is deleted //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_DELETED = 5; //////////////////////////////////////////////////////////////////////////////// /// @brief collection is currently loading //////////////////////////////////////////////////////////////////////////////// ArangoCollection.STATUS_LOADING = 6; //////////////////////////////////////////////////////////////////////////////// /// @brief document collection //////////////////////////////////////////////////////////////////////////////// ArangoCollection.TYPE_DOCUMENT = 2; //////////////////////////////////////////////////////////////////////////////// /// @brief edge collection //////////////////////////////////////////////////////////////////////////////// ArangoCollection.TYPE_EDGE = 3; //////////////////////////////////////////////////////////////////////////////// /// @brief prints a collection //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype._PRINT = function (context) { var status = "unknown"; var type = "unknown"; var name = this.name(); switch (this.status()) { case ArangoCollection.STATUS_NEW_BORN: status = "new born"; break; case ArangoCollection.STATUS_UNLOADED: status = "unloaded"; break; case ArangoCollection.STATUS_UNLOADING: status = "unloading"; break; case ArangoCollection.STATUS_LOADED: status = "loaded"; break; case ArangoCollection.STATUS_CORRUPTED: status = "corrupted"; break; case ArangoCollection.STATUS_DELETED: status = "deleted"; break; } switch (this.type()) { case ArangoCollection.TYPE_DOCUMENT: type = "document"; break; case ArangoCollection.TYPE_EDGE: type = "edge"; break; } var colors = require("internal").COLORS; var useColor = context.useColor; context.output += "[ArangoCollection "; if (useColor) { context.output += colors.COLOR_NUMBER; } context.output += this._id; if (useColor) { context.output += colors.COLOR_RESET; } context.output += ", \""; if (useColor) { context.output += colors.COLOR_STRING; } context.output += name || "unknown"; if (useColor) { context.output += colors.COLOR_RESET; } context.output += "\" (type " + type + ", status " + status + ")]"; }; //////////////////////////////////////////////////////////////////////////////// /// @brief converts into a string //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.toString = function () { return "[ArangoCollection: " + this._id + "]"; }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionAll //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.all = function () { return new SimpleQueryAll(this); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionByExample //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.byExample = function (example) { var e; var i; // example is given as only argument if (arguments.length === 1) { e = example; } // example is given as list else { e = {}; // create a REAL array, otherwise JSON.stringify will fail for (i = 0; i < arguments.length; i += 2) { e[arguments[i]] = arguments[i + 1]; } } return new SimpleQueryByExample(this, e); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionByExampleHash //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.byExampleHash = function (index, example) { var sq = this.byExample(example); sq._index = index; sq._type = "hash"; return sq; }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionByExampleSkiplist //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.byExampleSkiplist = function (index, example) { var sq = this.byExample(example); sq._index = index; sq._type = "skiplist"; return sq; }; //////////////////////////////////////////////////////////////////////////////// /// @brief constructs a query-by-condition using a skiplist index //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.byConditionSkiplist = function (index, condition) { var sq = new SimpleQueryByCondition(this, condition); sq._index = index; sq._type = "skiplist"; return sq; }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionRange //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.range = function (name, left, right) { return new SimpleQueryRange(this, name, left, right, 0); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionClosedRange //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.closedRange = function (name, left, right) { return new SimpleQueryRange(this, name, left, right, 1); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionGeo //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.geo = function(loc, order) { var idx; var locateGeoIndex1 = function(collection, loc, order) { var inds = collection.getIndexes(); var i; for (i = 0; i < inds.length; ++i) { var index = inds[i]; if (index.type === "geo1") { if (index.fields[0] === loc && index.geoJson === order) { return index; } } } return null; }; var locateGeoIndex2 = function(collection, lat, lon) { var inds = collection.getIndexes(); var i; for (i = 0; i < inds.length; ++i) { var index = inds[i]; if (index.type === "geo2") { if (index.fields[0] === lat && index.fields[1] === lon) { return index; } } } return null; }; if (order === undefined) { if (typeof loc === "object") { idx = this.index(loc); } else { idx = locateGeoIndex1(this, loc, false); } } else if (typeof order === "boolean") { idx = locateGeoIndex1(this, loc, order); } else { idx = locateGeoIndex2(this, loc, order); } if (idx === null) { var err = new ArangoError(); err.errorNum = arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.code; err.errorMessage = require("internal").sprintf(arangodb.errors.ERROR_QUERY_GEO_INDEX_MISSING.message, this.name()); throw err; } return new SimpleQueryGeo(this, idx.id); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionNear //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.near = function (lat, lon) { return new SimpleQueryNear(this, lat, lon); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionWithin //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.within = function (lat, lon, radius) { return new SimpleQueryWithin(this, lat, lon, radius); }; ArangoCollection.prototype.withinRectangle = function (lat1, lon1, lat2, lon2) { return new SimpleQueryWithinRectangle(this, lat1, lon1, lat2, lon2); }; ArangoCollection.prototype.fulltext = function (attribute, query, iid) { return new SimpleQueryFulltext(this, attribute, query, iid); }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionIterate //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.iterate = function (iterator, options) { var probability = 1.0; var limit = null; var stmt; var cursor; var pos; // TODO: this is not optimal for the client, there should be an HTTP call handling // everything on the server if (options !== undefined) { if (options.hasOwnProperty("probability")) { probability = options.probability; } if (options.hasOwnProperty("limit")) { limit = options.limit; } } if (limit === null) { if (probability >= 1.0) { cursor = this.all(); } else { stmt = sprintf("FOR d IN %s FILTER rand() >= @prob RETURN d", this.name()); stmt = db._createStatement({ query: stmt }); if (probability < 1.0) { stmt.bind("prob", probability); } cursor = stmt.execute(); } } else { if (typeof limit !== "number") { var error = new ArangoError(); error.errorNum = arangodb.errors.ERROR_ILLEGAL_NUMBER.code; error.errorMessage = "expecting a number, got " + String(limit); throw error; } if (probability >= 1.0) { cursor = this.all().limit(limit); } else { stmt = sprintf("FOR d IN %s FILTER rand() >= @prob LIMIT %d RETURN d", this.name(), limit); stmt = db._createStatement({ query: stmt }); if (probability < 1.0) { stmt.bind("prob", probability); } cursor = stmt.execute(); } } pos = 0; while (cursor.hasNext()) { var document = cursor.next(); iterator(document, pos); pos++; } }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock documentsCollectionRemoveByExample //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.removeByExample = function (example, waitForSync, limit) { throw "cannot call abstract removeByExample function"; }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock documentsCollectionReplaceByExample //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.replaceByExample = function (example, newValue, waitForSync, limit) { throw "cannot call abstract replaceByExample function"; }; //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock documentsCollectionUpdateByExample //////////////////////////////////////////////////////////////////////////////// ArangoCollection.prototype.updateByExample = function (example, newValue, keepNull, waitForSync, limit) { throw "cannot call abstract updateExample function"; };