mirror of https://gitee.com/bigwinds/arangodb
added constraint flag
This commit is contained in:
parent
da508e5b45
commit
eea4c94b1a
|
@ -1,5 +1,5 @@
|
|||
avocado> db.geo2.ensureGeoIndex("location.latitude", "location.longitude");
|
||||
{ "id" : "87612/1070652", "type" : "geo", "fields" : ["location.latitude", "location.longitude"], "isNewlyCreated" : true }
|
||||
{ "id" : "87612/1070652", "type" : "geo2", "fields" : ["location.latitude", "location.longitude"], "isNewlyCreated" : true }
|
||||
|
||||
avocado> for (i = -90; i <= 90; i += 10) {
|
||||
.......> for (j = -180; j <= 180; j += 10) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
avocado> db.geo.ensureGeoIndex("loc");
|
||||
{ "id" : "127629/47772301", "type" : "geo", "geoJson" : false, "fields" : ["loc"], "isNewlyCreated" : true }
|
||||
{ "id" : "127629/47772301", "type" : "geo1", "geoJson" : false, "fields" : ["loc"], "isNewlyCreated" : true }
|
||||
|
||||
avocado> for (i = -90; i <= 90; i += 10) {
|
||||
.......> for (j = -180; j <= 180; j += 10) {
|
||||
|
|
|
@ -2,7 +2,7 @@ avocado> db.examples.ensureGeoIndex("location");
|
|||
4545321
|
||||
|
||||
avocado> db.examples.getIndexes();
|
||||
[ { "iid" : 4545321, "type" : "geo", "location" : "location" } ]
|
||||
[ { "iid" : 4545321, "type" : "geo1", "location" : "location" } ]
|
||||
|
||||
avocado> db.examples.dropIndex(4545321);
|
||||
true
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
avocado> db.examples.getIndexes();
|
||||
[
|
||||
{ "iid" : 4701883, "type" : "geo", "location" : "work" },
|
||||
{ "iid" : 4545321, "type" : "geo", "location" : "home" }
|
||||
{ "iid" : 4701883, "type" : "geo1", "location" : "work" },
|
||||
{ "iid" : 4545321, "type" : "geo1", "location" : "home" }
|
||||
]
|
||||
|
|
|
@ -1021,7 +1021,8 @@ CLIENT_OPT := --startup.directory ./js --startup.modules-path ./js/client/module
|
|||
################################################################################
|
||||
SHELL_SERVER = @srcdir@/js/common/tests/shell-document.js \
|
||||
@srcdir@/js/common/tests/shell-edge.js \
|
||||
@srcdir@/js/common/tests/shell-collection.js
|
||||
@srcdir@/js/common/tests/shell-collection.js \
|
||||
@srcdir@/js/common/tests/shell-index-geo.js
|
||||
|
||||
UNITTESTS_SERVER = $(addprefix --unit-tests ,$(SHELL_SERVER))
|
||||
|
||||
|
|
|
@ -128,7 +128,8 @@ endif
|
|||
|
||||
SHELL_SERVER = @srcdir@/js/common/tests/shell-document.js \
|
||||
@srcdir@/js/common/tests/shell-edge.js \
|
||||
@srcdir@/js/common/tests/shell-collection.js
|
||||
@srcdir@/js/common/tests/shell-collection.js \
|
||||
@srcdir@/js/common/tests/shell-index-geo.js
|
||||
|
||||
.PHONY: unittests-shell-server
|
||||
|
||||
|
@ -159,7 +160,7 @@ SHELL_SERVER_AHUACATL = @srcdir@/js/server/tests/ahuacatl-operators.js \
|
|||
@srcdir@/js/server/tests/ahuacatl-functions.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-collection.js \
|
||||
@srcdir@/js/server/tests/ahuacatl-queries-noncollection.js
|
||||
|
||||
|
||||
|
||||
.PHONY: unittests-shell-server-ahuacatl
|
||||
|
||||
|
|
|
@ -55,6 +55,14 @@
|
|||
/// <a href="http://www.avocadodb.org/2012/03/31/using-hilbert-curves-and-polyhedrons-for-geo-indexing">blog</a>
|
||||
/// for details.
|
||||
///
|
||||
/// A geo-spatial index assumes that the latitude is between -90 and
|
||||
/// 90 degree and the longitude is between -180 and 180 degree. A geo
|
||||
/// index will ignore all documents which do not fulfill these
|
||||
/// requirements.
|
||||
///
|
||||
/// A geo-spatial constraint makes the same assumptions, but documents
|
||||
/// not fulfill the requirements are rejected.
|
||||
///
|
||||
/// @section IndexGeoShell Accessing Geo Indexes from the Shell
|
||||
///////////////////////////////////////////////////////////////
|
||||
///
|
||||
|
|
|
@ -1183,6 +1183,114 @@ static v8::Handle<v8::Value> CollectionVocBase (v8::Arguments const& argv, bool
|
|||
return scope.Close(edge ? TRI_WrapEdgesCollection(collection) : TRI_WrapCollection(collection));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ensures that a geo index or constraint exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> EnsureGeoIndexVocbaseCol (v8::Arguments const& argv, bool constraint) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Object> err;
|
||||
TRI_vocbase_col_t const* collection = UseCollection(argv.Holder(), &err);
|
||||
|
||||
if (collection == 0) {
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
TRI_doc_collection_t* doc = collection->_collection;
|
||||
|
||||
if (doc->base._type != TRI_COL_TYPE_SIMPLE_DOCUMENT) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_INTERNAL, "unknown collection type")));
|
||||
}
|
||||
|
||||
TRI_sim_collection_t* sim = (TRI_sim_collection_t*) doc;
|
||||
TRI_index_t* idx = 0;
|
||||
bool created;
|
||||
|
||||
// .............................................................................
|
||||
// case: <location>
|
||||
// .............................................................................
|
||||
|
||||
if (argv.Length() == 1) {
|
||||
v8::String::Utf8Value loc(argv[0]);
|
||||
|
||||
if (*loc == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<location> must be an attribute path")));
|
||||
}
|
||||
|
||||
idx = TRI_EnsureGeoIndex1SimCollection(sim, *loc, false, constraint, &created);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// case: <location>, <geoJson>
|
||||
// .............................................................................
|
||||
|
||||
else if (argv.Length() == 2 && (argv[1]->IsBoolean() || argv[1]->IsBooleanObject())) {
|
||||
v8::String::Utf8Value loc(argv[0]);
|
||||
|
||||
if (*loc == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<location> must be an attribute path")));
|
||||
}
|
||||
|
||||
idx = TRI_EnsureGeoIndex1SimCollection(sim, *loc, TRI_ObjectToBoolean(argv[1]), constraint, &created);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// case: <latitude>, <longitude>
|
||||
// .............................................................................
|
||||
|
||||
else if (argv.Length() == 2) {
|
||||
v8::String::Utf8Value lat(argv[0]);
|
||||
v8::String::Utf8Value lon(argv[1]);
|
||||
|
||||
if (*lat == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<latitude> must be an attribute path")));
|
||||
}
|
||||
|
||||
if (*lon == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<longitude> must be an attribute path")));
|
||||
}
|
||||
|
||||
idx = TRI_EnsureGeoIndex2SimCollection(sim, *lat, *lon, constraint, &created);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// error case
|
||||
// .............................................................................
|
||||
|
||||
else {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION,
|
||||
"usage: ensureGeoIndex(<latitude>, <longitude>) or ensureGeoIndex(<location>, [<geojson>])")));
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_errno(), "index could not be created")));
|
||||
}
|
||||
|
||||
TRI_json_t* json = idx->json(idx, collection->_collection);
|
||||
|
||||
if (!json) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("out of memory")));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> index = IndexRep(&collection->_collection->base, json);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
||||
if (index->IsObject()) {
|
||||
index->ToObject()->Set(v8::String::New("isNewlyCreated"), created ? v8::True() : v8::False());
|
||||
}
|
||||
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1918,7 +2026,7 @@ static v8::Handle<v8::Value> JS_NearQuery (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX) {
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX1 && idx->_type != TRI_IDX_TYPE_GEO_INDEX2) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_BAD_PARAMETER, "index must be a geo-index")));
|
||||
}
|
||||
|
@ -2024,7 +2132,7 @@ static v8::Handle<v8::Value> JS_WithinQuery (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX) {
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX1 && idx->_type != TRI_IDX_TYPE_GEO_INDEX2) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_BAD_PARAMETER, "index must be a geo-index")));
|
||||
}
|
||||
|
@ -4245,107 +4353,7 @@ static v8::Handle<v8::Value> JS_DropIndexVocbaseCol (v8::Arguments const& argv)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> JS_EnsureGeoIndexVocbaseCol (v8::Arguments const& argv) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Object> err;
|
||||
TRI_vocbase_col_t const* collection = UseCollection(argv.Holder(), &err);
|
||||
|
||||
if (collection == 0) {
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
||||
TRI_doc_collection_t* doc = collection->_collection;
|
||||
|
||||
if (doc->base._type != TRI_COL_TYPE_SIMPLE_DOCUMENT) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_INTERNAL, "unknown collection type")));
|
||||
}
|
||||
|
||||
TRI_sim_collection_t* sim = (TRI_sim_collection_t*) doc;
|
||||
TRI_index_t* idx = 0;
|
||||
bool created;
|
||||
|
||||
// .............................................................................
|
||||
// case: <location>
|
||||
// .............................................................................
|
||||
|
||||
if (argv.Length() == 1) {
|
||||
v8::String::Utf8Value loc(argv[0]);
|
||||
|
||||
if (*loc == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<location> must be an attribute path")));
|
||||
}
|
||||
|
||||
idx = TRI_EnsureGeoIndexSimCollection(sim, *loc, false, &created);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// case: <location>, <geoJson>
|
||||
// .............................................................................
|
||||
|
||||
else if (argv.Length() == 2 && (argv[1]->IsBoolean() || argv[1]->IsBooleanObject())) {
|
||||
v8::String::Utf8Value loc(argv[0]);
|
||||
|
||||
if (*loc == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<location> must be an attribute path")));
|
||||
}
|
||||
|
||||
idx = TRI_EnsureGeoIndexSimCollection(sim, *loc, TRI_ObjectToBoolean(argv[1]), &created);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// case: <latitude>, <longitude>
|
||||
// .............................................................................
|
||||
|
||||
else if (argv.Length() == 2) {
|
||||
v8::String::Utf8Value lat(argv[0]);
|
||||
v8::String::Utf8Value lon(argv[1]);
|
||||
|
||||
if (*lat == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<latitude> must be an attribute path")));
|
||||
}
|
||||
|
||||
if (*lon == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION, "<longitude> must be an attribute path")));
|
||||
}
|
||||
|
||||
idx = TRI_EnsureGeoIndex2SimCollection(sim, *lat, *lon, &created);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// error case
|
||||
// .............................................................................
|
||||
|
||||
else {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_ERROR_ILLEGAL_OPTION,
|
||||
"usage: ensureGeoIndex(<latitude>, <longitude>) or ensureGeoIndex(<location>, [<geojson>])")));
|
||||
}
|
||||
|
||||
if (idx == 0) {
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(v8::ThrowException(CreateErrorObject(TRI_errno(), "index could not be created")));
|
||||
}
|
||||
|
||||
TRI_json_t* json = idx->json(idx, collection->_collection);
|
||||
|
||||
if (!json) {
|
||||
return scope.Close(v8::ThrowException(v8::String::New("out of memory")));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> index = IndexRep(&collection->_collection->base, json);
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
||||
if (index->IsObject()) {
|
||||
index->ToObject()->Set(v8::String::New("isNewlyCreated"), created ? v8::True() : v8::False());
|
||||
}
|
||||
|
||||
ReleaseCollection(collection);
|
||||
return scope.Close(index);
|
||||
return EnsureGeoIndexVocbaseCol(argv, false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4389,7 +4397,6 @@ static v8::Handle<v8::Value> JS_EnsureUniqueConstraintVocbaseCol (v8::Arguments
|
|||
static v8::Handle<v8::Value> JS_EnsureHashIndexVocbaseCol (v8::Arguments const& argv) {
|
||||
return EnsureHashSkipListIndex("ensureHashIndex", argv, false, 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief ensures that a priority queue index exists
|
||||
|
|
102
VocBase/index.c
102
VocBase/index.c
|
@ -61,7 +61,8 @@ void TRI_FreeIndex (TRI_index_t* const idx) {
|
|||
LOG_TRACE("freeing index");
|
||||
|
||||
switch (idx->_type) {
|
||||
case TRI_IDX_TYPE_GEO_INDEX:
|
||||
case TRI_IDX_TYPE_GEO_INDEX1:
|
||||
case TRI_IDX_TYPE_GEO_INDEX2:
|
||||
TRI_FreeGeoIndex(idx);
|
||||
break;
|
||||
|
||||
|
@ -221,8 +222,11 @@ char const* TRI_TypeNameIndex (const TRI_index_t* const idx) {
|
|||
case TRI_IDX_TYPE_SKIPLIST_INDEX:
|
||||
return "skiplist";
|
||||
|
||||
case TRI_IDX_TYPE_GEO_INDEX:
|
||||
return "geo";
|
||||
case TRI_IDX_TYPE_GEO_INDEX1:
|
||||
return "geo1";
|
||||
|
||||
case TRI_IDX_TYPE_GEO_INDEX2:
|
||||
return "geo2";
|
||||
|
||||
case TRI_IDX_TYPE_PRIMARY_INDEX:
|
||||
return "primary";
|
||||
|
@ -479,7 +483,7 @@ static bool ExtractDoubleList (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief inserts a new document, location is a list
|
||||
/// @brief inserts a new document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int InsertGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
||||
|
@ -510,7 +514,12 @@ static int InsertGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
|||
}
|
||||
|
||||
if (! ok) {
|
||||
return false;
|
||||
if (geo->_constraint) {
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_GEO_INDEX_VIOLATED);
|
||||
}
|
||||
else {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// and insert into index
|
||||
|
@ -530,8 +539,13 @@ static int InsertGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
|||
return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
else if (res == -3) {
|
||||
LOG_DEBUG("illegal geo-coordinates, ignoring entry");
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_GEO_INDEX_VIOLATED);
|
||||
if (geo->_constraint) {
|
||||
LOG_DEBUG("illegal geo-coordinates, ignoring entry");
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_GEO_INDEX_VIOLATED);
|
||||
}
|
||||
else {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
else if (res < 0) {
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
|
@ -541,7 +555,7 @@ static int InsertGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief updates a document, location is a list
|
||||
/// @brief updates a document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int UpdateGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, TRI_shaped_json_t const* old) {
|
||||
|
@ -577,7 +591,7 @@ static int UpdateGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, TRI_sha
|
|||
res = GeoIndex_remove(geo->_geoIndex, &gc);
|
||||
|
||||
if (res != 0) {
|
||||
LOG_WARNING("cannot remove old index entry: %d", res);
|
||||
LOG_DEBUG("cannot remove old index entry: %d", res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,7 +605,12 @@ static int UpdateGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, TRI_sha
|
|||
}
|
||||
|
||||
if (! ok) {
|
||||
return false;
|
||||
if (geo->_constraint) {
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_GEO_INDEX_VIOLATED);
|
||||
}
|
||||
else {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
gc.latitude = latitude;
|
||||
|
@ -611,8 +630,13 @@ static int UpdateGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, TRI_sha
|
|||
return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
else if (res == -3) {
|
||||
LOG_DEBUG("illegal geo-coordinates, ignoring entry");
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_GEO_INDEX_VIOLATED);
|
||||
if (geo->_constraint) {
|
||||
LOG_DEBUG("illegal geo-coordinates, ignoring entry");
|
||||
return TRI_set_errno(TRI_ERROR_AVOCADO_GEO_INDEX_VIOLATED);
|
||||
}
|
||||
else {
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
else if (res < 0) {
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
|
@ -622,7 +646,7 @@ static int UpdateGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, TRI_sha
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief erases a document, location is a list
|
||||
/// @brief erases a document
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int RemoveGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
||||
|
@ -658,7 +682,7 @@ static int RemoveGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
|||
res = GeoIndex_remove(geo->_geoIndex, &gc);
|
||||
|
||||
if (res != 0) {
|
||||
LOG_WARNING("cannot remove old index entry: %d", res);
|
||||
LOG_DEBUG("cannot remove old index entry: %d", res);
|
||||
return TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
@ -670,7 +694,7 @@ static int RemoveGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc) {
|
|||
/// @brief JSON description of a geo index, location is a list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_json_t* JsonGeoIndex (TRI_index_t* idx, TRI_doc_collection_t const* collection) {
|
||||
static TRI_json_t* JsonGeoIndex1 (TRI_index_t* idx, TRI_doc_collection_t const* collection) {
|
||||
TRI_json_t* json;
|
||||
TRI_json_t* fields;
|
||||
TRI_shape_path_t const* path;
|
||||
|
@ -700,8 +724,9 @@ static TRI_json_t* JsonGeoIndex (TRI_index_t* idx, TRI_doc_collection_t const* c
|
|||
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, location));
|
||||
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "id", TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, idx->_iid));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "geo"));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "geo1"));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "geoJson", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, geo->_geoJson));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "constraint", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, geo->_constraint));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "fields", fields);
|
||||
|
||||
return json;
|
||||
|
@ -752,7 +777,8 @@ static TRI_json_t* JsonGeoIndex2 (TRI_index_t* idx, TRI_doc_collection_t const*
|
|||
TRI_PushBack3ListJson(TRI_UNKNOWN_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, longitude));
|
||||
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "id", TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, idx->_iid));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "geo"));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "type", TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "geo2"));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "constraint", TRI_CreateBooleanJson(TRI_UNKNOWN_MEM_ZONE, geo->_constraint));
|
||||
TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, json, "fields", fields);
|
||||
|
||||
return json;
|
||||
|
@ -775,40 +801,38 @@ static TRI_json_t* JsonGeoIndex2 (TRI_index_t* idx, TRI_doc_collection_t const*
|
|||
/// @brief creates a geo-index for lists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_CreateGeoIndex (struct TRI_doc_collection_s* collection,
|
||||
char const* locationName,
|
||||
TRI_shape_pid_t location,
|
||||
bool geoJson) {
|
||||
TRI_index_t* TRI_CreateGeoIndex1 (struct TRI_doc_collection_s* collection,
|
||||
char const* locationName,
|
||||
TRI_shape_pid_t location,
|
||||
bool geoJson,
|
||||
bool constraint) {
|
||||
TRI_geo_index_t* geo;
|
||||
char* ln;
|
||||
|
||||
geo = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_geo_index_t), false);
|
||||
|
||||
if (geo == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ln = TRI_DuplicateString(locationName);
|
||||
if (ln == NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, geo);
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRI_InitVectorString(&geo->base._fields, TRI_UNKNOWN_MEM_ZONE);
|
||||
|
||||
geo->base._iid = TRI_NewTickVocBase();
|
||||
geo->base._type = TRI_IDX_TYPE_GEO_INDEX;
|
||||
geo->base._type = TRI_IDX_TYPE_GEO_INDEX1;
|
||||
geo->base._collection = collection;
|
||||
geo->base._unique = false;
|
||||
|
||||
geo->base.insert = InsertGeoIndex;
|
||||
geo->base.remove = RemoveGeoIndex;
|
||||
geo->base.update = UpdateGeoIndex;
|
||||
geo->base.json = JsonGeoIndex;
|
||||
geo->base.json = JsonGeoIndex1;
|
||||
|
||||
TRI_PushBackVectorString(&geo->base._fields, ln);
|
||||
|
||||
geo->_constraint = constraint;
|
||||
geo->_geoIndex = GeoIndex_new();
|
||||
|
||||
geo->_variant = geoJson ? INDEX_GEO_COMBINED_LAT_LON : INDEX_GEO_COMBINED_LON_LAT;
|
||||
|
@ -828,36 +852,26 @@ TRI_index_t* TRI_CreateGeoIndex2 (struct TRI_doc_collection_s* collection,
|
|||
char const* latitudeName,
|
||||
TRI_shape_pid_t latitude,
|
||||
char const* longitudeName,
|
||||
TRI_shape_pid_t longitude) {
|
||||
TRI_shape_pid_t longitude,
|
||||
bool constraint) {
|
||||
TRI_geo_index_t* geo;
|
||||
char* lat;
|
||||
char* lon;
|
||||
|
||||
geo = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_geo_index_t), false);
|
||||
|
||||
if (geo == NULL) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lat = TRI_DuplicateString(latitudeName);
|
||||
if (lat == NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, geo);
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lon = TRI_DuplicateString(longitudeName);
|
||||
if (lon == NULL) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, geo);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, lat);
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRI_InitVectorString(&geo->base._fields, TRI_UNKNOWN_MEM_ZONE);
|
||||
|
||||
geo->base._iid = TRI_NewTickVocBase();
|
||||
geo->base._type = TRI_IDX_TYPE_GEO_INDEX;
|
||||
geo->base._type = TRI_IDX_TYPE_GEO_INDEX2;
|
||||
geo->base._collection = collection;
|
||||
geo->base._unique = false;
|
||||
|
||||
|
@ -869,6 +883,7 @@ TRI_index_t* TRI_CreateGeoIndex2 (struct TRI_doc_collection_s* collection,
|
|||
TRI_PushBackVectorString(&geo->base._fields, lat);
|
||||
TRI_PushBackVectorString(&geo->base._fields, lon);
|
||||
|
||||
geo->_constraint = constraint;
|
||||
geo->_geoIndex = GeoIndex_new();
|
||||
|
||||
geo->_variant = INDEX_GEO_INDIVIDUAL_LAT_LON;
|
||||
|
@ -1656,7 +1671,7 @@ HashIndexElements* TRI_LookupHashIndex(TRI_index_t* idx, TRI_json_t* parameterLi
|
|||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- PRIVATE FUNCTIONS
|
||||
// --SECTION-- private functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2152,7 +2167,6 @@ static int UpdatePriorityQueueIndex (TRI_index_t* idx,
|
|||
|
||||
|
||||
else if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,8 @@ typedef TRI_voc_tick_t TRI_idx_iid_t;
|
|||
|
||||
typedef enum {
|
||||
TRI_IDX_TYPE_PRIMARY_INDEX,
|
||||
TRI_IDX_TYPE_GEO_INDEX,
|
||||
TRI_IDX_TYPE_GEO_INDEX1,
|
||||
TRI_IDX_TYPE_GEO_INDEX2,
|
||||
TRI_IDX_TYPE_HASH_INDEX,
|
||||
TRI_IDX_TYPE_PRIORITY_QUEUE_INDEX,
|
||||
TRI_IDX_TYPE_SKIPLIST_INDEX
|
||||
|
@ -125,6 +126,7 @@ typedef struct TRI_geo_index_s {
|
|||
TRI_shape_pid_t _longitude;
|
||||
|
||||
bool _geoJson;
|
||||
bool _constraint;
|
||||
}
|
||||
TRI_geo_index_t;
|
||||
|
||||
|
@ -262,10 +264,11 @@ void TRI_FreePrimaryIndex (TRI_index_t*);
|
|||
/// first and latitude second.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_CreateGeoIndex (struct TRI_doc_collection_s*,
|
||||
char const* locationName,
|
||||
TRI_shape_pid_t,
|
||||
bool geoJson);
|
||||
TRI_index_t* TRI_CreateGeoIndex1 (struct TRI_doc_collection_s*,
|
||||
char const* locationName,
|
||||
TRI_shape_pid_t,
|
||||
bool geoJson,
|
||||
bool constraint);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief creates a geo-index for arrays
|
||||
|
@ -275,7 +278,8 @@ TRI_index_t* TRI_CreateGeoIndex2 (struct TRI_doc_collection_s*,
|
|||
char const* latitudeName,
|
||||
TRI_shape_pid_t,
|
||||
char const* longitudeName,
|
||||
TRI_shape_pid_t);
|
||||
TRI_shape_pid_t,
|
||||
bool constraint);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief frees the memory allocated, but does not free the pointer
|
||||
|
|
|
@ -174,7 +174,7 @@ static TRI_data_feeder_t* DetermineGeoIndexUsage (TRI_query_instance_t* const in
|
|||
|
||||
idx = (TRI_index_t*) indexes->_buffer[i];
|
||||
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX) {
|
||||
if (idx->_type != TRI_IDX_TYPE_GEO_INDEX1 && idx->_type != TRI_IDX_TYPE_GEO_INDEX2) {
|
||||
// ignore all indexes except geo indexes here
|
||||
continue;
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ static TRI_data_feeder_t* DetermineIndexUsage (TRI_query_instance_t* const insta
|
|||
QL_optimize_range_compare_type_e lastCompareType = COMPARE_TYPE_UNKNOWN;
|
||||
size_t j;
|
||||
|
||||
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX) {
|
||||
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX1 || idx->_type == TRI_IDX_TYPE_GEO_INDEX2) {
|
||||
// ignore all geo indexes here
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* collectio
|
|||
char const* latitude,
|
||||
char const* longitude,
|
||||
bool geoJson,
|
||||
bool constraint,
|
||||
TRI_idx_iid_t iid,
|
||||
bool* created);
|
||||
|
||||
|
@ -384,8 +385,9 @@ static TRI_doc_mptr_t CreateDocument (TRI_sim_collection_t* sim,
|
|||
|
||||
if (resRollback != TRI_ERROR_NO_ERROR) {
|
||||
LOG_ERROR("encountered error '%s' during rollback of create", TRI_last_error());
|
||||
TRI_set_errno(res);
|
||||
}
|
||||
|
||||
TRI_set_errno(res);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
|
@ -639,8 +641,9 @@ static TRI_doc_mptr_t UpdateDocument (TRI_sim_collection_t* collection,
|
|||
|
||||
if (resUpd._did == 0) {
|
||||
LOG_ERROR("encountered error '%s' during rollback of update", TRI_last_error());
|
||||
TRI_set_errno(res);
|
||||
}
|
||||
|
||||
TRI_set_errno(res);
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
|
@ -1414,7 +1417,7 @@ static bool OpenIndexIterator (char const* filename, void* data) {
|
|||
TRI_index_t* idx;
|
||||
TRI_json_t* fieldStr;
|
||||
TRI_json_t* fld;
|
||||
TRI_json_t* gjs;
|
||||
TRI_json_t* bv;
|
||||
TRI_json_t* iis;
|
||||
TRI_json_t* json;
|
||||
TRI_json_t* type;
|
||||
|
@ -1494,47 +1497,72 @@ static bool OpenIndexIterator (char const* filename, void* data) {
|
|||
}
|
||||
|
||||
// ...........................................................................
|
||||
// GEO INDEX
|
||||
// GEO INDEX (list or attribute)
|
||||
// ...........................................................................
|
||||
|
||||
if (TRI_EqualString(typeStr, "geo")) {
|
||||
bool geoJson;
|
||||
if (TRI_EqualString(typeStr, "geo1") || TRI_EqualString(typeStr, "geo2")) {
|
||||
bool constraint;
|
||||
|
||||
gjs = TRI_LookupArrayJson(json, "geoJson");
|
||||
geoJson = false;
|
||||
bv = TRI_LookupArrayJson(json, "contraint");
|
||||
constraint = false;
|
||||
|
||||
if (gjs != NULL && gjs->_type == TRI_JSON_BOOLEAN) {
|
||||
geoJson = gjs->_value._boolean;
|
||||
if (bv != NULL && bv->_type == TRI_JSON_BOOLEAN) {
|
||||
constraint = bv->_value._boolean;
|
||||
}
|
||||
|
||||
if (fieldCount == 1) {
|
||||
TRI_json_t* loc;
|
||||
if (TRI_EqualString(typeStr, "geo1")) {
|
||||
bool geoJson;
|
||||
|
||||
loc = TRI_AtVector(&fld->_value._objects, 0);
|
||||
bv = TRI_LookupArrayJson(json, "geoJson");
|
||||
geoJson = false;
|
||||
|
||||
if (bv != NULL && bv->_type == TRI_JSON_BOOLEAN) {
|
||||
geoJson = bv->_value._boolean;
|
||||
}
|
||||
|
||||
CreateGeoIndexSimCollection(doc, loc->_value._string.data, NULL, NULL, geoJson, iid, NULL);
|
||||
if (fieldCount == 1) {
|
||||
TRI_json_t* loc;
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return true;
|
||||
loc = TRI_AtVector(&fld->_value._objects, 0);
|
||||
|
||||
CreateGeoIndexSimCollection(doc, loc->_value._string.data, NULL, NULL, geoJson, constraint, iid, NULL);
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("ignoring %s-index %lu, 'fields' must be a list with 1 entries",
|
||||
typeStr, (unsigned long) iid);
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (fieldCount == 2) {
|
||||
TRI_json_t* lat;
|
||||
TRI_json_t* lon;
|
||||
|
||||
lat = TRI_AtVector(&fld->_value._objects, 0);
|
||||
lon = TRI_AtVector(&fld->_value._objects, 1);
|
||||
else if (TRI_EqualString(typeStr, "geo2")) {
|
||||
if (fieldCount == 2) {
|
||||
TRI_json_t* lat;
|
||||
TRI_json_t* lon;
|
||||
|
||||
CreateGeoIndexSimCollection(doc, NULL, lat->_value._string.data, lon->_value._string.data, false, iid, NULL);
|
||||
lat = TRI_AtVector(&fld->_value._objects, 0);
|
||||
lon = TRI_AtVector(&fld->_value._objects, 1);
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return true;
|
||||
CreateGeoIndexSimCollection(doc, NULL, lat->_value._string.data, lon->_value._string.data, false, constraint, iid, NULL);
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("ignoring %s-index %lu, 'fields' must be a list with 2 entries",
|
||||
typeStr, (unsigned long) iid);
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
LOG_ERROR("ignoring %s-index %lu, 'fields' must be a list with 1 or 2 entries",
|
||||
typeStr, (unsigned long) iid);
|
||||
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
return false;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1542,16 +1570,16 @@ static bool OpenIndexIterator (char const* filename, void* data) {
|
|||
// HASH INDEX OR SKIPLIST INDEX
|
||||
// ...........................................................................
|
||||
|
||||
else if (TRI_EqualString(typeStr, "hash") || TRI_EqualString(typeStr, "skiplist") ||
|
||||
TRI_EqualString(typeStr, "priorityqueue")
|
||||
) {
|
||||
else if ( TRI_EqualString(typeStr, "hash")
|
||||
|| TRI_EqualString(typeStr, "skiplist")
|
||||
|| TRI_EqualString(typeStr, "priorityqueue")) {
|
||||
|
||||
// Determine if the hash index is unique or non-unique
|
||||
gjs = TRI_LookupArrayJson(json, "unique");
|
||||
bv = TRI_LookupArrayJson(json, "unique");
|
||||
uniqueIndex = false;
|
||||
|
||||
if (gjs != NULL && gjs->_type == TRI_JSON_BOOLEAN) {
|
||||
uniqueIndex = gjs->_value._boolean;
|
||||
if (bv != NULL && bv->_type == TRI_JSON_BOOLEAN) {
|
||||
uniqueIndex = bv->_value._boolean;
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("ignoring %s-index %lu, could not determine if unique or non-unique",
|
||||
|
@ -2130,7 +2158,11 @@ static int CreateImmediateIndexes (TRI_sim_collection_t* sim,
|
|||
return TRI_set_errno(TRI_ERROR_AVOCADO_UNIQUE_CONSTRAINT_VIOLATED);
|
||||
}
|
||||
|
||||
return result;
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
return TRI_set_errno(result);
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2672,6 +2704,7 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
|||
char const* latitude,
|
||||
char const* longitude,
|
||||
bool geoJson,
|
||||
bool constraint,
|
||||
TRI_idx_iid_t iid,
|
||||
bool* created) {
|
||||
TRI_index_t* idx;
|
||||
|
@ -2717,10 +2750,10 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
|||
|
||||
// check, if we know the index
|
||||
if (location != NULL) {
|
||||
idx = TRI_LookupGeoIndexSimCollection(sim, loc, geoJson);
|
||||
idx = TRI_LookupGeoIndex1SimCollection(sim, loc, geoJson, constraint);
|
||||
}
|
||||
else if (longitude != NULL && latitude != NULL) {
|
||||
idx = TRI_LookupGeoIndex2SimCollection(sim, lat, lon);
|
||||
idx = TRI_LookupGeoIndex2SimCollection(sim, lat, lon, constraint);
|
||||
}
|
||||
else {
|
||||
TRI_set_errno(TRI_ERROR_INTERNAL);
|
||||
|
@ -2740,14 +2773,14 @@ static TRI_index_t* CreateGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
|||
|
||||
// create a new index
|
||||
if (location != NULL) {
|
||||
idx = TRI_CreateGeoIndex(&sim->base, location, loc, geoJson);
|
||||
idx = TRI_CreateGeoIndex1(&sim->base, location, loc, geoJson, constraint);
|
||||
|
||||
LOG_TRACE("created geo-index for location '%s': %d",
|
||||
location,
|
||||
(unsigned long) loc);
|
||||
}
|
||||
else if (longitude != NULL && latitude != NULL) {
|
||||
idx = TRI_CreateGeoIndex2(&sim->base, latitude, lat, longitude, lon);
|
||||
idx = TRI_CreateGeoIndex2(&sim->base, latitude, lat, longitude, lon, constraint);
|
||||
|
||||
LOG_TRACE("created geo-index for location '%s': %d, %d",
|
||||
location,
|
||||
|
@ -3255,9 +3288,10 @@ TRI_vector_t TRI_SelectByExample (TRI_sim_collection_t* sim,
|
|||
/// @brief finds a geo index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_LookupGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_index_t* TRI_LookupGeoIndex1SimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_shape_pid_t location,
|
||||
bool geoJson) {
|
||||
bool geoJson,
|
||||
bool constraint) {
|
||||
size_t n;
|
||||
size_t i;
|
||||
|
||||
|
@ -3268,10 +3302,10 @@ TRI_index_t* TRI_LookupGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
|
||||
idx = collection->_indexes._buffer[i];
|
||||
|
||||
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX) {
|
||||
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX1) {
|
||||
TRI_geo_index_t* geo = (TRI_geo_index_t*) idx;
|
||||
|
||||
if (geo->_location != 0 && geo->_location == location && geo->_geoJson == geoJson) {
|
||||
if (geo->_location != 0 && geo->_location == location && geo->_geoJson == geoJson && geo->_constraint == constraint) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
@ -3286,7 +3320,8 @@ TRI_index_t* TRI_LookupGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
|||
|
||||
TRI_index_t* TRI_LookupGeoIndex2SimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_shape_pid_t latitude,
|
||||
TRI_shape_pid_t longitude) {
|
||||
TRI_shape_pid_t longitude,
|
||||
bool constraint) {
|
||||
size_t n;
|
||||
size_t i;
|
||||
|
||||
|
@ -3297,10 +3332,10 @@ TRI_index_t* TRI_LookupGeoIndex2SimCollection (TRI_sim_collection_t* collection,
|
|||
|
||||
idx = collection->_indexes._buffer[i];
|
||||
|
||||
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX) {
|
||||
if (idx->_type == TRI_IDX_TYPE_GEO_INDEX2) {
|
||||
TRI_geo_index_t* geo = (TRI_geo_index_t*) idx;
|
||||
|
||||
if (geo->_latitude != 0 && geo->_longitude != 0 && geo->_latitude == latitude && geo->_longitude == longitude) {
|
||||
if (geo->_latitude != 0 && geo->_longitude != 0 && geo->_latitude == latitude && geo->_longitude == longitude && geo->_constraint == constraint) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
@ -3515,10 +3550,11 @@ TRI_index_t* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t* collect
|
|||
/// @brief ensures that a geo index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_index_t* TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
||||
char const* location,
|
||||
bool geoJson,
|
||||
bool* created) {
|
||||
TRI_index_t* TRI_EnsureGeoIndex1SimCollection (TRI_sim_collection_t* sim,
|
||||
char const* location,
|
||||
bool geoJson,
|
||||
bool constraint,
|
||||
bool* created) {
|
||||
TRI_index_t* idx;
|
||||
int res;
|
||||
|
||||
|
@ -3528,7 +3564,7 @@ TRI_index_t* TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
|||
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
idx = CreateGeoIndexSimCollection(sim, location, NULL, NULL, geoJson, 0, created);
|
||||
idx = CreateGeoIndexSimCollection(sim, location, NULL, NULL, geoJson, constraint, 0, created);
|
||||
|
||||
if (idx == NULL) {
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
@ -3553,6 +3589,7 @@ TRI_index_t* TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* sim,
|
|||
TRI_index_t* TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* sim,
|
||||
char const* latitude,
|
||||
char const* longitude,
|
||||
bool constraint,
|
||||
bool* created) {
|
||||
TRI_index_t* idx;
|
||||
int res;
|
||||
|
@ -3563,7 +3600,7 @@ TRI_index_t* TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* sim,
|
|||
|
||||
TRI_WRITE_LOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
||||
idx = CreateGeoIndexSimCollection(sim, NULL, latitude, longitude, false, 0, created);
|
||||
idx = CreateGeoIndexSimCollection(sim, NULL, latitude, longitude, false, constraint, 0, created);
|
||||
|
||||
if (idx == NULL) {
|
||||
TRI_WRITE_UNLOCK_DOCUMENTS_INDEXES_SIM_COLLECTION(sim);
|
||||
|
|
|
@ -408,9 +408,10 @@ TRI_vector_pointer_t TRI_LookupEdgesSimCollection (TRI_sim_collection_t* edges,
|
|||
/// Note that the caller must hold at least a read-lock.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_index_s* TRI_LookupGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_shape_pid_t location,
|
||||
bool geoJson);
|
||||
struct TRI_index_s* TRI_LookupGeoIndex1SimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_shape_pid_t location,
|
||||
bool geoJson,
|
||||
bool constraint);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a geo index
|
||||
|
@ -420,7 +421,8 @@ struct TRI_index_s* TRI_LookupGeoIndexSimCollection (TRI_sim_collection_t* colle
|
|||
|
||||
struct TRI_index_s* TRI_LookupGeoIndex2SimCollection (TRI_sim_collection_t* collection,
|
||||
TRI_shape_pid_t latitude,
|
||||
TRI_shape_pid_t longitude);
|
||||
TRI_shape_pid_t longitude,
|
||||
bool constraint);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a hash index
|
||||
|
@ -455,19 +457,21 @@ struct TRI_index_s* TRI_LookupSkiplistIndexSimCollection (TRI_sim_collection_t*,
|
|||
/// @brief ensures that a geo index exists
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_index_s* TRI_EnsureGeoIndexSimCollection (TRI_sim_collection_t* collection,
|
||||
char const* location,
|
||||
bool geoJson,
|
||||
bool* created);
|
||||
struct TRI_index_s* TRI_EnsureGeoIndex1SimCollection (TRI_sim_collection_t* collection,
|
||||
char const* location,
|
||||
bool geoJson,
|
||||
bool constraint,
|
||||
bool* created);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief adds a geo index to a collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct TRI_index_s* TRI_EnsureGeoIndex2SimCollection (TRI_sim_collection_t* collection,
|
||||
char const* latitude,
|
||||
char const* longitude,
|
||||
bool* created);
|
||||
char const* latitude,
|
||||
char const* longitude,
|
||||
bool constraint,
|
||||
bool* created);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief adds or returns an existing hash index to a collection
|
||||
|
|
|
@ -78,7 +78,7 @@ function geoIndexCreationSuite() {
|
|||
var id = idx.id;
|
||||
|
||||
assertNotEqual(0, id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(false, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
|
@ -86,7 +86,7 @@ function geoIndexCreationSuite() {
|
|||
idx = collection.ensureGeoIndex("loc");
|
||||
|
||||
assertEqual(id, idx.id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(false, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(false, idx.isNewlyCreated);
|
||||
|
@ -94,10 +94,20 @@ function geoIndexCreationSuite() {
|
|||
idx = collection.ensureGeoIndex("loc", true);
|
||||
|
||||
assertNotEqual(id, idx.id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(true, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
|
||||
collection.unload();
|
||||
|
||||
idx = collection.ensureGeoIndex("loc", true);
|
||||
|
||||
assertNotEqual(id, idx.id);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(true, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(false, idx.isNewlyCreated);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -109,7 +119,7 @@ function geoIndexCreationSuite() {
|
|||
var id = idx.id;
|
||||
|
||||
assertNotEqual(0, id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(true, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
|
@ -117,7 +127,7 @@ function geoIndexCreationSuite() {
|
|||
idx = collection.ensureGeoIndex("loc", true);
|
||||
|
||||
assertEqual(id, idx.id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(true, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(false, idx.isNewlyCreated);
|
||||
|
@ -125,10 +135,20 @@ function geoIndexCreationSuite() {
|
|||
idx = collection.ensureGeoIndex("loc", false);
|
||||
|
||||
assertNotEqual(id, idx.id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(false, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
|
||||
collection.unload();
|
||||
|
||||
idx = collection.ensureGeoIndex("loc", false);
|
||||
|
||||
assertNotEqual(id, idx.id);
|
||||
assertEqual("geo1", idx.type);
|
||||
assertEqual(false, idx.geoJson);
|
||||
assertEqual(["loc"], idx.fields);
|
||||
assertEqual(false, idx.isNewlyCreated);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -140,31 +160,88 @@ function geoIndexCreationSuite() {
|
|||
var id = idx.id;
|
||||
|
||||
assertNotEqual(0, id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo2", idx.type);
|
||||
assertEqual(["lat", "lon"], idx.fields);
|
||||
assertEqual(true, idx.isNewlyCreated);
|
||||
|
||||
idx = collection.ensureGeoIndex("lat", "lon");
|
||||
|
||||
assertEqual(id, idx.id);
|
||||
assertEqual("geo", idx.type);
|
||||
assertEqual("geo2", idx.type);
|
||||
assertEqual(["lat", "lon"], idx.fields);
|
||||
assertEqual(false, idx.isNewlyCreated);
|
||||
},
|
||||
|
||||
collection.unload();
|
||||
|
||||
idx = collection.ensureGeoIndex("lat", "lon");
|
||||
|
||||
assertEqual(id, idx.id);
|
||||
assertEqual("geo2", idx.type);
|
||||
assertEqual(["lat", "lon"], idx.fields);
|
||||
assertEqual(false, idx.isNewlyCreated);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- basic methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: error handling
|
||||
/// @brief test suite: Simple Queries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testCreationLocationError : function () {
|
||||
collection.save({ loc : [ -100, 0 ] });
|
||||
function geoIndexErrorHandlingSuite() {
|
||||
var cn = "UnitTestsCollectionGeo";
|
||||
var collection = null;
|
||||
|
||||
try {
|
||||
collection.ensureGeoIndex("loc");
|
||||
fail();
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
db._drop(cn);
|
||||
collection = db._create(cn, { waitForSync : false });
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
collection.drop();
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test: error handling index
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testErrorHandlerIndexList : function () {
|
||||
collection.ensureGeoIndex("loc");
|
||||
|
||||
var d1 = collection.save({ a : 1 });
|
||||
var d2 = collection.save({ loc : null });
|
||||
var d3 = collection.save({ loc : [0] });
|
||||
var d4 = collection.save({ loc : [ -100, -200 ] });
|
||||
var d5 = collection.save({ loc : [ -10, -20 ]});
|
||||
|
||||
assertEqual(1, collection.near(0,0).toArray().length);
|
||||
|
||||
d1 = collection.replace(d1, { loc : [ 0, 0 ] });
|
||||
d2 = collection.replace(d2, { loc : [ 0, 0 ] });
|
||||
d3 = collection.replace(d3, { loc : [ 0, 0 ] });
|
||||
d4 = collection.replace(d4, { loc : [ 0, 0 ] });
|
||||
|
||||
assertEqual(5, collection.near(0,0).toArray().length);
|
||||
|
||||
collection.replace(d1, { a : 2 });
|
||||
collection.replace(d2, { loc : null });
|
||||
collection.replace(d3, { loc : [ 0 ] });
|
||||
collection.replace(d4, { loc : [ -100, -200 ] });
|
||||
|
||||
assertEqual(1, collection.near(0,0).toArray().length);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -458,6 +535,7 @@ function geoIndexSimpleQueriesSuite() {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(geoIndexCreationSuite);
|
||||
jsunity.run(geoIndexErrorHandlingSuite);
|
||||
jsunity.run(geoIndexSimpleQueriesSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
|
|
@ -189,7 +189,7 @@ AvocadoCollection.prototype.geo = function(loc, order) {
|
|||
for (var i = 0; i < inds.length; ++i) {
|
||||
var index = inds[i];
|
||||
|
||||
if (index.type == "geo") {
|
||||
if (index.type == "geo1") {
|
||||
if (index.fields[0] == loc && index.geoJson == order) {
|
||||
return index;
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ AvocadoCollection.prototype.geo = function(loc, order) {
|
|||
for (var i = 0; i < inds.length; ++i) {
|
||||
var index = inds[i];
|
||||
|
||||
if (index.type == "geo" && 2 <= index.fields.length) {
|
||||
if (index.type == "geo2") {
|
||||
if (index.fields[0] == lat && index.fields[1] == lon) {
|
||||
return index;
|
||||
}
|
||||
|
@ -1144,7 +1144,7 @@ function SimpleQueryNear (collection, latitude, longitude, iid) {
|
|||
for (var i = 0; i < idx.length; ++i) {
|
||||
var index = idx[i];
|
||||
|
||||
if (index.type == "geo") {
|
||||
if (index.type == "geo1" || index.type == "geo2") {
|
||||
if (this._index == null) {
|
||||
this._index = index.id;
|
||||
}
|
||||
|
@ -1327,7 +1327,7 @@ function SimpleQueryWithin (collection, latitude, longitude, radius, iid) {
|
|||
for (var i = 0; i < idx.length; ++i) {
|
||||
var index = idx[i];
|
||||
|
||||
if (index.type == "geo") {
|
||||
if (index.type == "geo1" || index.type == "geo2") {
|
||||
if (this._index == null) {
|
||||
this._index = index.id;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue