1
0
Fork 0

Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel

This commit is contained in:
scottashton 2014-11-18 09:42:26 +01:00
commit 8635862224
20 changed files with 1020 additions and 187 deletions

View File

@ -297,16 +297,16 @@ install-exec-hook:
################################################################################
install-data-hook:
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/c
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/d
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/e
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/f
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/sub/b
rm -f $(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/hoek/test/modules/ignore.txt
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/setup.sh
rm -f $(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/isemail/dns-no-mx.js
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh
rm -f $(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/c
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/d
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/e
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/f
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/ncp/test/fixtures/src/sub/b
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/hoek/test/modules/ignore.txt
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/setup.sh
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/joi/node_modules/isemail/dns-no-mx.js
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh
rm -f $(DESTDIR)$(pkgdataNODEdir)/js/node/node_modules/docco/node_modules/fs-extra/node_modules/rimraf/test/run.sh
## -----------------------------------------------------------------------------

View File

@ -205,7 +205,6 @@ namespace triagens {
std::string toString () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief get a string representation of the AqlValue
/// this will fail if the value is not a string

View File

@ -376,18 +376,22 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
AqlValue result = executeSimpleExpression(member, &myCollection, trx, docColls, argv, startPos, vars, regs);
if (result.isList()) {
if (index->isNumericValue()) {
auto j = result.extractListMember(trx, myCollection, index->getIntValue(), true);
TRI_document_collection_t const* myCollection2 = nullptr;
AqlValue indexResult = executeSimpleExpression(index, &myCollection2, trx, docColls, argv, startPos, vars, regs);
if (indexResult.isNumber()) {
auto j = result.extractListMember(trx, myCollection, indexResult.toInt64(), true);
indexResult.destroy();
result.destroy();
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
}
else if (index->isStringValue()) {
char const* p = index->getStringValue();
TRI_ASSERT(p != nullptr);
else if (indexResult.isString()) {
auto&& value = indexResult.toString();
indexResult.destroy();
try {
// stoll() might throw an exception if the string is not a number
int64_t position = static_cast<int64_t>(std::stoll(p));
int64_t position = static_cast<int64_t>(std::stoll(value.c_str()));
auto j = result.extractListMember(trx, myCollection, position, true);
result.destroy();
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
@ -399,17 +403,21 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
// fall-through to returning null
}
else if (result.isArray()) {
if (index->isNumericValue()) {
std::string const indexString = std::to_string(index->getIntValue());
TRI_document_collection_t const* myCollection2 = nullptr;
AqlValue indexResult = executeSimpleExpression(index, &myCollection2, trx, docColls, argv, startPos, vars, regs);
if (indexResult.isNumber()) {
auto&& indexString = std::to_string(indexResult.toInt64());
auto j = result.extractArrayMember(trx, myCollection, indexString.c_str());
indexResult.destroy();
result.destroy();
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
}
else if (index->isStringValue()) {
char const* p = index->getStringValue();
TRI_ASSERT(p != nullptr);
else if (indexResult.isString()) {
auto&& value = indexResult.toString();
indexResult.destroy();
auto j = result.extractArrayMember(trx, myCollection, p);
auto j = result.extractArrayMember(trx, myCollection, value.c_str());
result.destroy();
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, j.steal()));
}

View File

@ -62,8 +62,9 @@ namespace triagens {
std::vector<std::string> const& readCollections,
std::vector<std::string> const& writeCollections,
double lockTimeout,
bool waitForSync)
: Transaction(new V8TransactionContext(false), vocbase, 0) {
bool waitForSync,
bool embed)
: Transaction(new V8TransactionContext(embed), vocbase, 0) {
// std::cout << TRI_CurrentThreadId() << ", EXPLICITTRANSACTION " << this << " CTOR\r\n";
this->addHint(TRI_TRANSACTION_HINT_LOCK_ENTIRELY, false);

View File

@ -277,6 +277,11 @@ static v8::Handle<v8::Value> JS_Transaction (v8::Arguments const& argv) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_INTERNAL);
}
bool embed = false;
if (object->Has(TRI_V8_SYMBOL("embed"))) {
v8::Handle<v8::Value> v = v8::Handle<v8::Object>::Cast(object->Get(TRI_V8_SYMBOL("embed")));
embed = TRI_ObjectToBoolean(v);
}
v8::Handle<v8::Object> current = v8::Context::GetCurrent()->Global();
@ -306,13 +311,13 @@ static v8::Handle<v8::Value> JS_Transaction (v8::Arguments const& argv) {
TRI_V8_EXCEPTION_PARAMETER(scope, actionError);
}
// start actual transaction
ExplicitTransaction trx(vocbase,
readCollections,
writeCollections,
lockTimeout,
waitForSync);
waitForSync,
embed);
int res = trx.begin();

View File

@ -325,7 +325,7 @@ setupIndexQueries();
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleAllSkipLimit}
/// var cn = "products";
/// db._drop(cn);
/// var collection = db._create(cn, { waitForSync: true });
/// var collection = db._create(cn);
/// collection.save({"Hello1" : "World1" });
/// collection.save({"Hello2" : "World2" });
/// collection.save({"Hello3" : "World3" });
@ -523,7 +523,7 @@ actions.defineHttp({
///
/// In order to use the *near* operator, a geo index must be defined for the
/// collection. This index also defines which attribute holds the coordinates
/// for the document. If you have more then one geo-spatial index, you can use
/// for the document. If you have more than one geo-spatial index, you can use
/// the *geo* field to select a particular index.
///
/// The call expects a JSON object as body with the following attributes:
@ -566,7 +566,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleNear}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// var loc = products.ensureGeoIndex("loc");
/// var i;
/// for (i = -0.01; i <= 0.01; i += 0.002) {
@ -594,7 +594,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleNearDistance}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// var loc = products.ensureGeoIndex("loc");
/// var i;
/// for (i = -0.01; i <= 0.01; i += 0.002) {
@ -702,7 +702,7 @@ actions.defineHttp({
///
/// In order to use the *within* operator, a geo index must be defined for
/// the collection. This index also defines which attribute holds the
/// coordinates for the document. If you have more then one geo-spatial index,
/// coordinates for the document. If you have more than one geo-spatial index,
/// you can use the *geo* field to select a particular index.
///
/// The call expects a JSON object as body with the following attributes:
@ -747,7 +747,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleWithin}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// var loc = products.ensureGeoIndex("loc");
/// var i;
/// for (i = -0.01; i <= 0.01; i += 0.002) {
@ -776,7 +776,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleWithinDistance}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// var loc = products.ensureGeoIndex("loc");
/// var i;
/// for (i = -0.01; i <= 0.01; i += 0.002) {
@ -862,6 +862,159 @@ actions.defineHttp({
}
});
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSA_put_api_simple_within_rectangle
/// @brief returns all documents of a collection within a rectangle
///
/// @RESTHEADER{PUT /_api/simple/within-rectangle, Within rectangle query}
///
/// @RESTBODYPARAM{query,string,required}
/// Contains the query.
///
/// @RESTDESCRIPTION
///
/// This will find all documents within the specified rectangle (determined by
/// the given coordinates (*latitude1*, *longitude1*, *latitude2*, *longitude2*).
///
/// In order to use the *within-rectangle* query, a geo index must be defined for
/// the collection. This index also defines which attribute holds the
/// coordinates for the document. If you have more than one geo-spatial index,
/// you can use the *geo* field to select a particular index.
///
/// The call expects a JSON object as body with the following attributes:
///
/// - *collection*: The name of the collection to query.
///
/// - *latitude1*: The latitude of the first rectangle coordinate.
///
/// - *longitude1*: The longitude of the first rectangle coordinate.
///
/// - *latitude2*: The latitude of the second rectangle coordinate.
///
/// - *longitude2*: The longitude of the second rectangle coordinate.
///
/// - *skip*: The number of documents to skip in the query. (optional)
///
/// - *limit*: The maximal amount of documents to return. The *skip* is
/// applied before the *limit* restriction. The default is 100. (optional)
///
/// - *geo*: If given, the identifier of the geo-index to use. (optional)
///
/// Returns a cursor containing the result, see [Http Cursor](../HttpAqlQueryCursor/README.md) for details.
///
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{201}
/// is returned if the query was executed successfully.
///
/// @RESTRETURNCODE{400}
/// is returned if the body does not contain a valid JSON representation of a
/// query. The response body contains an error document in this case.
///
/// @RESTRETURNCODE{404}
/// is returned if the collection specified by *collection* is unknown. The
/// response body contains an error document in this case.
///
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleWithinRectangle}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn);
/// var loc = products.ensureGeoIndex("loc");
/// var i;
/// for (i = -0.01; i <= 0.01; i += 0.002) {
/// products.save({ name : "Name/" + i + "/",loc: [ i, 0 ] });
/// }
/// var url = "/_api/simple/within-rectangle";
/// var body = {
/// collection: "products",
/// latitude1 : 0,
/// longitude1 : 0,
/// latitude2 : 0.2,
/// longitude2 : 0.2,
/// skip : 1,
/// limit : 2
/// };
///
/// var response = logCurlRequest('PUT', url, JSON.stringify(body));
///
/// assert(response.code === 201);
///
/// logJsonResponse(response);
/// db._drop(cn);
/// @END_EXAMPLE_ARANGOSH_RUN
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////
actions.defineHttp({
url: API + "within-rectangle",
callback : function (req, res) {
try {
var body = actions.getJsonBody(req, res);
if (body === undefined) {
return;
}
if (req.requestType !== actions.PUT) {
actions.resultUnsupported(req, res);
}
else {
var limit = body.limit;
var skip = body.skip;
var latitude1 = body.latitude1;
var longitude1 = body.longitude1;
var latitude2 = body.latitude2;
var longitude2 = body.longitude2;
var geo = body.geo;
var name = body.collection;
var collection = db._collection(name);
if (collection === null) {
actions.collectionNotFound(req, res, name);
}
else if (latitude1 === null || latitude1 === undefined) {
actions.badParameter(req, res, "latitude1");
}
else if (longitude1 === null || longitude1 === undefined) {
actions.badParameter(req, res, "longitude1");
}
else if (latitude2 === null || latitude2 === undefined) {
actions.badParameter(req, res, "latitude2");
}
else if (longitude2 === null || longitude2 === undefined) {
actions.badParameter(req, res, "longitude2");
}
else {
var result;
if (geo === null || geo === undefined) {
result = collection.withinRectangle(latitude1, longitude1, latitude2, longitude2);
}
else {
result = collection.geo({ id : geo }).withinRectangle(latitude1, longitude1, latitude2, longitude2);
}
if (skip !== null && skip !== undefined) {
result = result.skip(skip);
}
if (limit !== null && limit !== undefined) {
result = result.limit(limit);
}
createCursorResponse(req, res, CREATE_CURSOR(result.toArray(), true, body.batchSize, body.ttl));
}
}
}
catch (err) {
actions.resultException(req, res, err, undefined, false);
}
}
});
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSA_put_api_simple_fulltext
/// @brief returns documents of a collection as a result of a fulltext query
@ -915,7 +1068,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleFulltext}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({"text" : "this text contains word" });
/// products.save({"text" : "this text also has a word" });
/// products.save({"text" : "this is nothing" });
@ -1032,7 +1185,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleByExample}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1053,7 +1206,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleByExample2}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1074,7 +1227,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleByExample3}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1186,7 +1339,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirstExample}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1207,7 +1360,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirstExampleNotFound}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1315,7 +1468,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirst}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: false });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1336,7 +1489,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleFirstSingle}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: false });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1434,7 +1587,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleLast}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: false });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1455,7 +1608,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleLastSingle}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: false });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1557,7 +1710,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleRange}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.ensureUniqueSkiplist("i");
/// products.save({ "i": 1});
/// products.save({ "i": 2});
@ -1689,7 +1842,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleRemoveByExample}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1708,7 +1861,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleRemoveByExample_1}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1728,7 +1881,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleRemoveByExample_2}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1857,7 +2010,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleReplaceByExample}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -1881,7 +2034,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleReplaceByExampleWaitForSync}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -2020,7 +2173,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleUpdateByExample}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});
@ -2044,7 +2197,7 @@ actions.defineHttp({
/// @EXAMPLE_ARANGOSH_RUN{RestSimpleUpdateByExample_1}
/// var cn = "products";
/// db._drop(cn);
/// var products = db._create(cn, { waitForSync: true });
/// var products = db._create(cn);
/// products.save({ "a": { "k": 1, "j": 1 }, "i": 1});
/// products.save({ "a": { "j": 1 }, "i": 1});
/// products.save({ "i": 1});

View File

@ -367,25 +367,24 @@ controller.post("/query/upload/:user", function(req, res) {
queries = req.body();
userColl = db._users.byExample({"user": user}).toArray()[0];
storedQueries = userColl.extra.queries;
queriesToSave = [];
queriesToSave = userColl.userData.queries || [ ];
underscore.each(queries, function(newq) {
var toBeStored = true;
underscore.each(storedQueries, function(stored) {
if (stored.name === newq.name) {
toBeStored = false;
var found = false, i;
for (i = 0; i < queriesToSave.length; ++i) {
if (queriesToSave[i].name === newq.name) {
queriesToSave[i] = newq;
found = true;
break;
}
});
if (toBeStored === true) {
}
if (! found) {
queriesToSave.push(newq);
}
});
queriesToSave = queriesToSave.concat(storedQueries);
var toUpdate = {
extra: {
userData: {
queries: queriesToSave
}
}

View File

@ -46,6 +46,7 @@ var SimpleQueryRange = simple.SimpleQueryRange;
var SimpleQueryGeo = simple.SimpleQueryGeo;
var SimpleQueryNear = simple.SimpleQueryNear;
var SimpleQueryWithin = simple.SimpleQueryWithin;
var SimpleQueryWithinRectangle = simple.SimpleQueryWithinRectangle;
var SimpleQueryFulltext = simple.SimpleQueryFulltext;
// -----------------------------------------------------------------------------
@ -740,6 +741,10 @@ 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);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a fulltext query for a collection
/// @startDocuBlock collectionFulltext

View File

@ -1911,7 +1911,6 @@ var bindEdgeCollections = function(self, edgeCollections) {
// remove
wrap.remove = function(edgeId, options) {
var result;
//if _key make _id (only on 1st call)
if (edgeId.indexOf("/") === -1) {
edgeId = key + "/" + edgeId;
@ -1923,6 +1922,7 @@ var bindEdgeCollections = function(self, edgeCollections) {
collections: {
write: self.__collectionsToLock
},
embed: true,
action: function (params) {
var db = require("internal").db;
params.ids.forEach(
@ -1940,13 +1940,15 @@ var bindEdgeCollections = function(self, edgeCollections) {
options: options
}
});
result = true;
} catch (e) {
result = false;
self.__idsToRemove = [];
self.__collectionsToLock = [];
throw e;
}
self.__idsToRemove = [];
self.__collectionsToLock = [];
return result;
return true;
};
self[key] = wrap;
@ -1956,7 +1958,6 @@ var bindEdgeCollections = function(self, edgeCollections) {
var bindVertexCollections = function(self, vertexCollections) {
_.each(vertexCollections, function(key) {
var obj = db._collection(key);
var result;
var wrap = wrapCollection(obj);
wrap.remove = function(vertexId, options) {
//delete all edges using the vertex in all graphs
@ -1998,6 +1999,7 @@ var bindVertexCollections = function(self, vertexCollections) {
collections: {
write: self.__collectionsToLock
},
embed: true,
action: function (params) {
var db = require("internal").db;
params.ids.forEach(
@ -2021,14 +2023,15 @@ var bindVertexCollections = function(self, vertexCollections) {
vertexId: vertexId
}
});
result = true;
} catch (e) {
result = false;
self.__idsToRemove = [];
self.__collectionsToLock = [];
throw e;
}
self.__idsToRemove = [];
self.__collectionsToLock = [];
return result;
return true;
};
self[key] = wrap;
});

View File

@ -37,6 +37,7 @@ var ArangoError = arangodb.ArangoError;
var SimpleQueryArray;
var SimpleQueryNear;
var SimpleQueryWithin;
var SimpleQueryWithinRectangle;
// -----------------------------------------------------------------------------
// --SECTION-- GENERAL ARRAY CURSOR
@ -990,6 +991,14 @@ 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);
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY NEAR
// -----------------------------------------------------------------------------
@ -1214,10 +1223,6 @@ SimpleQueryWithin.prototype._PRINT = function (context) {
context.output += text;
};
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief adds the distance attribute
////////////////////////////////////////////////////////////////////////////////
@ -1237,6 +1242,112 @@ SimpleQueryWithin.prototype.distance = function (attribute) {
return clone;
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY WITHINRECTANGLE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @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;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @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._latitude1
+ ", "
+ 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;
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY FULLTEXT
// -----------------------------------------------------------------------------
@ -1342,6 +1453,7 @@ exports.SimpleQueryRange = SimpleQueryRange;
exports.SimpleQueryGeo = SimpleQueryGeo;
exports.SimpleQueryNear = SimpleQueryNear;
exports.SimpleQueryWithin = SimpleQueryWithin;
exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle;
exports.SimpleQueryFulltext = SimpleQueryFulltext;
// -----------------------------------------------------------------------------

View File

@ -45,6 +45,7 @@ var SimpleQueryGeo = sq.SimpleQueryGeo;
var SimpleQueryNear = sq.SimpleQueryNear;
var SimpleQueryRange = sq.SimpleQueryRange;
var SimpleQueryWithin = sq.SimpleQueryWithin;
var SimpleQueryWithinRectangle = sq.SimpleQueryWithinRectangle;
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY ALL
@ -382,6 +383,65 @@ SimpleQueryWithin.prototype.execute = function (batchSize) {
}
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY WITHINRECTANGLE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a withinRectangle query
////////////////////////////////////////////////////////////////////////////////
SimpleQueryWithinRectangle.prototype.execute = function (batchSize) {
if (this._execution === null) {
if (batchSize !== undefined && batchSize > 0) {
this._batchSize = batchSize;
}
var data = {
collection: this._collection.name(),
latitude1: this._latitude1,
longitude1: this._longitude1,
latitude2: this._latitude2,
longitude2: this._longitude2
};
if (this._limit !== null) {
data.limit = this._limit;
}
if (this._skip !== null) {
data.skip = this._skip;
}
if (this._index !== null) {
data.geo = this._index;
}
if (this._distance !== null) {
data.distance = this._distance;
}
if (this._batchSize !== null) {
data.batchSize = this._batchSize;
}
var requestResult = this._collection._database._connection.PUT(
"/_api/simple/within-rectangle", JSON.stringify(data));
arangosh.checkRequestResult(requestResult);
this._execution = new ArangoQueryCursor(this._collection._database, requestResult);
if (requestResult.hasOwnProperty("count")) {
this._countQuery = requestResult.count;
}
}
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY FULLTEXT
// -----------------------------------------------------------------------------
@ -449,6 +509,7 @@ exports.SimpleQueryGeo = SimpleQueryGeo;
exports.SimpleQueryNear = SimpleQueryNear;
exports.SimpleQueryRange = SimpleQueryRange;
exports.SimpleQueryWithin = SimpleQueryWithin;
exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle;
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE

View File

@ -44,6 +44,7 @@ var SimpleQueryGeo = sq.SimpleQueryGeo;
var SimpleQueryNear = sq.SimpleQueryNear;
var SimpleQueryRange = sq.SimpleQueryRange;
var SimpleQueryWithin = sq.SimpleQueryWithin;
var SimpleQueryWithinRectangle = sq.SimpleQueryWithinRectangle;
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY ALL
@ -381,6 +382,65 @@ SimpleQueryWithin.prototype.execute = function (batchSize) {
}
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY WITHINRECTANGLE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a withinRectangle query
////////////////////////////////////////////////////////////////////////////////
SimpleQueryWithinRectangle.prototype.execute = function (batchSize) {
if (this._execution === null) {
if (batchSize !== undefined && batchSize > 0) {
this._batchSize = batchSize;
}
var data = {
collection: this._collection.name(),
latitude1: this._latitude1,
longitude1: this._longitude1,
latitude2: this._latitude2,
longitude2: this._longitude2
};
if (this._limit !== null) {
data.limit = this._limit;
}
if (this._skip !== null) {
data.skip = this._skip;
}
if (this._index !== null) {
data.geo = this._index;
}
if (this._distance !== null) {
data.distance = this._distance;
}
if (this._batchSize !== null) {
data.batchSize = this._batchSize;
}
var requestResult = this._collection._database._connection.PUT(
"/_api/simple/within-rectangle", JSON.stringify(data));
arangosh.checkRequestResult(requestResult);
this._execution = new ArangoQueryCursor(this._collection._database, requestResult);
if (requestResult.hasOwnProperty("count")) {
this._countQuery = requestResult.count;
}
}
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY FULLTEXT
// -----------------------------------------------------------------------------
@ -448,6 +508,7 @@ exports.SimpleQueryGeo = SimpleQueryGeo;
exports.SimpleQueryNear = SimpleQueryNear;
exports.SimpleQueryRange = SimpleQueryRange;
exports.SimpleQueryWithin = SimpleQueryWithin;
exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle;
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE

View File

@ -45,6 +45,7 @@ var SimpleQueryRange = simple.SimpleQueryRange;
var SimpleQueryGeo = simple.SimpleQueryGeo;
var SimpleQueryNear = simple.SimpleQueryNear;
var SimpleQueryWithin = simple.SimpleQueryWithin;
var SimpleQueryWithinRectangle = simple.SimpleQueryWithinRectangle;
var SimpleQueryFulltext = simple.SimpleQueryFulltext;
// -----------------------------------------------------------------------------
@ -739,6 +740,10 @@ 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);
};
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a fulltext query for a collection
/// @startDocuBlock collectionFulltext

View File

@ -1910,7 +1910,6 @@ var bindEdgeCollections = function(self, edgeCollections) {
// remove
wrap.remove = function(edgeId, options) {
var result;
//if _key make _id (only on 1st call)
if (edgeId.indexOf("/") === -1) {
edgeId = key + "/" + edgeId;
@ -1922,6 +1921,7 @@ var bindEdgeCollections = function(self, edgeCollections) {
collections: {
write: self.__collectionsToLock
},
embed: true,
action: function (params) {
var db = require("internal").db;
params.ids.forEach(
@ -1939,13 +1939,15 @@ var bindEdgeCollections = function(self, edgeCollections) {
options: options
}
});
result = true;
} catch (e) {
result = false;
self.__idsToRemove = [];
self.__collectionsToLock = [];
throw e;
}
self.__idsToRemove = [];
self.__collectionsToLock = [];
return result;
return true;
};
self[key] = wrap;
@ -1955,7 +1957,6 @@ var bindEdgeCollections = function(self, edgeCollections) {
var bindVertexCollections = function(self, vertexCollections) {
_.each(vertexCollections, function(key) {
var obj = db._collection(key);
var result;
var wrap = wrapCollection(obj);
wrap.remove = function(vertexId, options) {
//delete all edges using the vertex in all graphs
@ -1997,6 +1998,7 @@ var bindVertexCollections = function(self, vertexCollections) {
collections: {
write: self.__collectionsToLock
},
embed: true,
action: function (params) {
var db = require("internal").db;
params.ids.forEach(
@ -2020,14 +2022,15 @@ var bindVertexCollections = function(self, vertexCollections) {
vertexId: vertexId
}
});
result = true;
} catch (e) {
result = false;
self.__idsToRemove = [];
self.__collectionsToLock = [];
throw e;
}
self.__idsToRemove = [];
self.__collectionsToLock = [];
return result;
return true;
};
self[key] = wrap;
});

View File

@ -36,6 +36,7 @@ var ArangoError = arangodb.ArangoError;
var SimpleQueryArray;
var SimpleQueryNear;
var SimpleQueryWithin;
var SimpleQueryWithinRectangle;
// -----------------------------------------------------------------------------
// --SECTION-- GENERAL ARRAY CURSOR
@ -989,6 +990,14 @@ 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);
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY NEAR
// -----------------------------------------------------------------------------
@ -1213,10 +1222,6 @@ SimpleQueryWithin.prototype._PRINT = function (context) {
context.output += text;
};
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief adds the distance attribute
////////////////////////////////////////////////////////////////////////////////
@ -1236,6 +1241,112 @@ SimpleQueryWithin.prototype.distance = function (attribute) {
return clone;
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY WITHINRECTANGLE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @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;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @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._latitude1
+ ", "
+ 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;
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY FULLTEXT
// -----------------------------------------------------------------------------
@ -1341,6 +1452,7 @@ exports.SimpleQueryRange = SimpleQueryRange;
exports.SimpleQueryGeo = SimpleQueryGeo;
exports.SimpleQueryNear = SimpleQueryNear;
exports.SimpleQueryWithin = SimpleQueryWithin;
exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle;
exports.SimpleQueryFulltext = SimpleQueryFulltext;
// -----------------------------------------------------------------------------

View File

@ -3112,17 +3112,17 @@ function AQL_NEAR (collection, latitude, longitude, limit, distanceAttribute) {
function AQL_WITHIN (collection, latitude, longitude, radius, distanceAttribute) {
"use strict";
var weight = TYPEWEIGHT(distanceAttribute);
if (weight !== TYPEWEIGHT_NULL && weight !== TYPEWEIGHT_STRING) {
WARN("WITHIN", INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
}
if (isCoordinator) {
var query = COLLECTION(collection).within(latitude, longitude, radius);
query._distance = distanceAttribute;
return query.toArray();
}
var weight = TYPEWEIGHT(distanceAttribute);
if (weight !== TYPEWEIGHT_NULL && weight !== TYPEWEIGHT_STRING) {
WARN("WITHIN", INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
}
var idx = INDEX(COLLECTION(collection), [ "geo1", "geo2" ]);
if (idx === null) {
@ -3161,91 +3161,7 @@ function AQL_WITHIN_RECTANGLE (collection, latitude1, longitude1, latitude2, lon
return null;
}
var distanceMeters = function (lat1, lon1, lat2, lon2) {
var deltaLat = (lat2 - lat1) * Math.PI / 180;
var deltaLon = (lon2 - lon1) * Math.PI / 180;
var a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return 6378.137 /* radius of earth in kilometers */
* c
* 1000; // kilometers to meters;
};
var midpoint = [
latitude1 + (latitude2 - latitude1) * 0.5,
longitude1 + (longitude2 - longitude1) * 0.5
];
var idx = INDEX(COLLECTION(collection), [ "geo1", "geo2" ]);
if (idx === null) {
THROW("WITHIN_RECTANGLE", INTERNAL.errors.ERROR_QUERY_GEO_INDEX_MISSING, collection);
}
var diameter = distanceMeters(latitude1, longitude1, latitude2, longitude2);
var latLower, latUpper, lonLower, lonUpper;
if (latitude1 < latitude2) {
latLower = latitude1;
latUpper = latitude2;
}
else {
latLower = latitude2;
latUpper = latitude1;
}
if (longitude1 < longitude2) {
lonLower = longitude1;
lonUpper = longitude2;
}
else {
lonLower = longitude2;
lonUpper = longitude1;
}
var result = COLLECTION(collection).WITHIN(idx.id, midpoint[0], midpoint[1], diameter);
var documents = [ ];
if (idx.type === 'geo1') {
// geo1, we have both coordinates in a list
var attribute = idx.fields[0];
if (idx.geoJson) {
result.documents.forEach(function(doc) {
// check if within bounding rectangle
// first list value is longitude, then latitude
if (doc[attribute][1] >= latLower && doc[attribute][1] <= latUpper &&
doc[attribute][0] >= lonLower && doc[attribute][0] <= lonUpper) {
documents.push(doc);
}
});
}
else {
result.documents.forEach(function(doc) {
// check if within bounding rectangle
// first list value is latitude, then longitude
if (doc[attribute][0] >= latLower && doc[attribute][0] <= latUpper &&
doc[attribute][1] >= lonLower && doc[attribute][1] <= lonUpper) {
documents.push(doc);
}
});
}
}
else {
// geo2, we have dedicated latitude and longitude attributes
var latAtt = idx.fields[0], lonAtt = idx.fields[1];
result.documents.forEach(function(doc) {
// check if within bounding rectangle
if (doc[latAtt] >= latLower && doc[latAtt] <= latUpper &&
doc[lonAtt] >= lonLower && doc[lonAtt] <= lonUpper) {
documents.push(doc);
}
});
}
return documents;
return COLLECTION(collection).withinRectangle(latitude1, longitude1, latitude2, longitude2).toArray();
}
////////////////////////////////////////////////////////////////////////////////
@ -3513,8 +3429,7 @@ function AQL_HAS (element, name) {
}
if (weight !== TYPEWEIGHT_DOCUMENT) {
WARN("HAS", INTERNAL.errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH);
return;
return false;
}
return element.hasOwnProperty(AQL_TO_STRING(name));

View File

@ -45,6 +45,7 @@ var SimpleQueryGeo = sq.SimpleQueryGeo;
var SimpleQueryNear = sq.SimpleQueryNear;
var SimpleQueryRange = sq.SimpleQueryRange;
var SimpleQueryWithin = sq.SimpleQueryWithin;
var SimpleQueryWithinRectangle = sq.SimpleQueryWithinRectangle;
////////////////////////////////////////////////////////////////////////////////
/// @brief rewrites an index id by stripping the collection name from it
@ -1188,6 +1189,190 @@ SimpleQueryWithin.prototype.execute = function () {
this._countTotal = documents.total;
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY WITHINRECTANGLE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// --SECTION-- private functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief executes a within-rectangle query
////////////////////////////////////////////////////////////////////////////////
SimpleQueryWithinRectangle.prototype.execute = function () {
var result;
var documents;
if (this._execution !== null) {
return;
}
if (this._skip === null) {
this._skip = 0;
}
if (this._skip < 0) {
var err = new ArangoError();
err.errorNum = internal.errors.ERROR_BAD_PARAMETER;
err.errorMessage = "skip must be non-negative";
throw err;
}
var cluster = require("org/arangodb/cluster");
if (cluster.isCoordinator()) {
var dbName = require("internal").db._name();
var shards = cluster.shardList(dbName, this._collection.name());
var coord = { coordTransactionID: ArangoClusterInfo.uniqid() };
var options = { coordTransactionID: coord.coordTransactionID, timeout: 360 };
var _limit = 0;
if (this._limit > 0) {
if (this._skip >= 0) {
_limit = this._skip + this._limit;
}
}
var self = this;
shards.forEach(function (shard) {
ArangoClusterComm.asyncRequest("put",
"shard:" + shard,
dbName,
"/_api/simple/within-rectangle",
JSON.stringify({
collection: shard,
latitude1: self._latitude1,
longitude1: self._longitude1,
latitude2: self._latitude2,
longitude2: self._longitude2,
geo: rewriteIndex(self._index),
skip: 0,
limit: _limit || undefined,
batchSize: 100000000
}),
{ },
options);
});
var _documents = [ ], total = 0;
result = cluster.wait(coord, shards);
result.forEach(function(part) {
var body = JSON.parse(part.body);
total += body.total;
_documents = _documents.concat(body.result);
});
if (this._limit > 0) {
_documents = _documents.slice(0, this._skip + this._limit);
}
documents = {
documents: _documents,
count: _documents.length,
total: total
};
}
else {
var distanceMeters = function (lat1, lon1, lat2, lon2) {
var deltaLat = (lat2 - lat1) * Math.PI / 180;
var deltaLon = (lon2 - lon1) * Math.PI / 180;
var a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return 6378.137 /* radius of earth in kilometers */
* c
* 1000; // kilometers to meters;
};
var diameter = distanceMeters(this._latitude1, this._longitude1, this._latitude2, this._longitude2);
var midpoint = [
this._latitude1 + (this._latitude2 - this._latitude1) * 0.5,
this._longitude1 + (this._longitude2 - this._longitude1) * 0.5
];
result = this._collection.WITHIN(this._index, midpoint[0], midpoint[1], diameter);
var idx = this._collection.index(this._index);
var latLower, latUpper, lonLower, lonUpper;
if (this._latitude1 < this._latitude2) {
latLower = this._latitude1;
latUpper = this._latitude2;
}
else {
latLower = this._latitude2;
latUpper = this._latitude1;
}
if (this._longitude1 < this._longitude2) {
lonLower = this._longitude1;
lonUpper = this._longitude2;
}
else {
lonLower = this._longitude2;
lonUpper = this._longitude1;
}
documents = [ ];
if (idx.type === 'geo1') {
// geo1, we have both coordinates in a list
var attribute = idx.fields[0];
if (idx.geoJson) {
result.documents.forEach(function(doc) {
// check if within bounding rectangle
// first list value is longitude, then latitude
if (doc[attribute][1] >= latLower && doc[attribute][1] <= latUpper &&
doc[attribute][0] >= lonLower && doc[attribute][0] <= lonUpper) {
documents.push(doc);
}
});
}
else {
result.documents.forEach(function(doc) {
// check if within bounding rectangle
// first list value is latitude, then longitude
if (doc[attribute][0] >= latLower && doc[attribute][0] <= latUpper &&
doc[attribute][1] >= lonLower && doc[attribute][1] <= lonUpper) {
documents.push(doc);
}
});
}
}
else {
// geo2, we have dedicated latitude and longitude attributes
var latAtt = idx.fields[0], lonAtt = idx.fields[1];
result.documents.forEach(function(doc) {
// check if within bounding rectangle
if (doc[latAtt] >= latLower && doc[latAtt] <= latUpper &&
doc[lonAtt] >= lonLower && doc[lonAtt] <= lonUpper) {
documents.push(doc);
}
});
}
documents = {
documents: documents,
count: result.documents.length,
total: result.documents.length
};
if (this._limit > 0) {
documents.documents = documents.documents.slice(0, this._skip + this._limit);
documents.count = documents.documents.length;
}
}
this._execution = new GeneralArrayCursor(documents.documents, this._skip, null);
this._countQuery = documents.total - this._skip;
this._countTotal = documents.total;
};
// -----------------------------------------------------------------------------
// --SECTION-- SIMPLE QUERY FULLTEXT
// -----------------------------------------------------------------------------
@ -1294,6 +1479,7 @@ exports.SimpleQueryGeo = SimpleQueryGeo;
exports.SimpleQueryNear = SimpleQueryNear;
exports.SimpleQueryRange = SimpleQueryRange;
exports.SimpleQueryWithin = SimpleQueryWithin;
exports.SimpleQueryWithinRectangle = SimpleQueryWithinRectangle;
exports.byExample = byExample;
// -----------------------------------------------------------------------------

View File

@ -1876,6 +1876,16 @@ function ahuacatlFunctionsTestSuite () {
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test has function
////////////////////////////////////////////////////////////////////////////////
testHas3 : function () {
var expected = [ [ "test2", [ "other" ] ] ];
var actual = getQueryResults("LET doc = { \"_id\": \"test/76689250173\", \"_rev\": \"76689250173\", \"_key\": \"76689250173\", \"test1\": \"something\", \"test2\": { \"DATA\": [ \"other\" ] } } FOR attr IN ATTRIBUTES(doc) LET prop = doc[attr] FILTER HAS(prop, 'DATA') RETURN [ attr, prop.DATA ]");
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test has function
////////////////////////////////////////////////////////////////////////////////
@ -1884,10 +1894,10 @@ function ahuacatlFunctionsTestSuite () {
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN HAS()");
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN HAS({ })");
assertQueryError(errors.ERROR_QUERY_FUNCTION_ARGUMENT_NUMBER_MISMATCH.code, "RETURN HAS({ }, \"fox\", true)");
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN HAS(false, \"fox\")");
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN HAS(3, \"fox\")");
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN HAS(\"yes\", \"fox\")");
assertQueryWarningAndNull(errors.ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH.code, "RETURN HAS([ ], \"fox\")");
assertEqual([ false ], getQueryResults("RETURN HAS(false, \"fox\")"));
assertEqual([ false ], getQueryResults("RETURN HAS(3, \"fox\")"));
assertEqual([ false ], getQueryResults("RETURN HAS(\"yes\", \"fox\")"));
assertEqual([ false ], getQueryResults("RETURN HAS([ ], \"fox\")"));
assertEqual([ false ], getQueryResults("RETURN HAS({ }, null)"));
assertEqual([ false ], getQueryResults("RETURN HAS({ }, false)"));
assertEqual([ false ], getQueryResults("RETURN HAS({ }, true)"));

View File

@ -648,6 +648,201 @@ function ahuacatlQueryCollectionTestSuite () {
var actual = getQueryResults("FOR u in " + users.name() + " SORT u.name RETURN { name : u.name, from: u._from, to: u._to }");
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test querying attributes
////////////////////////////////////////////////////////////////////////////////
testAttributesQuery1 : function () {
var expected = [
[
"Abigail",
"Abigail"
],
[
"Alexander",
"Alexander"
],
[
"Anthony",
"Anthony"
],
[
"Chloe",
"Chloe"
],
[
"Daniel",
"Daniel"
],
[
"Diego",
"Diego"
],
[
"Emma",
"Emma"
],
[
"Ethan",
"Ethan"
],
[
"Eva",
"Eva"
],
[
"Fred",
"Fred"
],
[
"Isabella",
"Isabella"
],
[
"Jacob",
"Jacob"
],
[
"Jim",
"Jim"
],
[
"John",
"John"
],
[
"Madison",
"Madison"
],
[
"Mariah",
"Mariah"
],
[
"Mary",
"Mary"
],
[
"Michael",
"Michael"
],
[
"Olivia",
"Olivia"
],
[
"Sophia",
"Sophia"
]
];
var actual = getQueryResults("FOR u in " + users.name() + " SORT u.name RETURN [ u.name, u['name'] ]");
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test querying attributes
////////////////////////////////////////////////////////////////////////////////
testAttributesQuery2 : function () {
var expected = [
[
"Abigail",
"Abigail"
],
[
"Alexander",
"Alexander"
],
[
"Anthony",
"Anthony"
],
[
"Chloe",
"Chloe"
],
[
"Daniel",
"Daniel"
],
[
"Diego",
"Diego"
],
[
"Emma",
"Emma"
],
[
"Ethan",
"Ethan"
],
[
"Eva",
"Eva"
],
[
"Fred",
"Fred"
],
[
"Isabella",
"Isabella"
],
[
"Jacob",
"Jacob"
],
[
"Jim",
"Jim"
],
[
"John",
"John"
],
[
"Madison",
"Madison"
],
[
"Mariah",
"Mariah"
],
[
"Mary",
"Mary"
],
[
"Michael",
"Michael"
],
[
"Olivia",
"Olivia"
],
[
"Sophia",
"Sophia"
]
];
var actual = getQueryResults("FOR u in " + users.name() + " LET d = 'name' SORT u.name RETURN [ u.name, u[d] ]");
assertEqual(expected, actual);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test querying attributes
////////////////////////////////////////////////////////////////////////////////
testAttributesQuery3 : function () {
users.save({ "hobbies" : [ "riding", "skating", "swimming" ] });
var expected = [ [ "riding", "skating", "swimming", null, "swimming" ] ];
var actual = getQueryResults("FOR u in " + users.name() + " FILTER HAS(u, 'hobbies') RETURN [ u.hobbies[0], u.hobbies[1], u.hobbies[2], u.hobbies[3], u.hobbies[-1] ]");
assertEqual(expected, actual);
}
};

View File

@ -84,17 +84,17 @@ function withinRectangleSuite () {
////////////////////////////////////////////////////////////////////////////////
testWithinRectangleAsResult : function () {
var actual =AQL_EXECUTE("RETURN WITHIN_RECTANGLE(geo, -1, -1, 1, 1)").json[0];
var actual = AQL_EXECUTE("RETURN WITHIN_RECTANGLE(geo, -1, -1, 1, 1)").json[0];
assertEqual(actual.length , 9);
},
testWithinRectangleAsResultForSingleDocument : function () {
var actual =AQL_EXECUTE("RETURN WITHIN_RECTANGLE(geo, -0.8, -1.2, -1.2, -0.8)").json[0];
var actual = AQL_EXECUTE("RETURN WITHIN_RECTANGLE(geo, -0.8, -1.2, -1.2, -0.8)").json[0];
assertEqual(actual.length , 1);
},
testWithinRectangleAsResultForMissingDocument : function () {
var actual =AQL_EXECUTE("RETURN WITHIN_RECTANGLE(geo, -41, -41, -41, -41)").json[0];
var actual = AQL_EXECUTE("RETURN WITHIN_RECTANGLE(geo, -41, -41, -41, -41)").json[0];
assertEqual(actual.length , 0);
},