1
0
Fork 0

added constraint flag

This commit is contained in:
Frank Celler 2012-04-29 14:14:52 +02:00
parent da508e5b45
commit eea4c94b1a
15 changed files with 404 additions and 250 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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" }
]

View File

@ -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))

View File

@ -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

View File

@ -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
///////////////////////////////////////////////////////////////
///

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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;
}