mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'sharding' of ssh://github.com/triAGENS/ArangoDB into sharding
This commit is contained in:
commit
944f29deb0
18
CHANGELOG
18
CHANGELOG
|
@ -1,6 +1,24 @@
|
|||
v2.0.0-alpha1 (2014-02-28)
|
||||
--------------------------
|
||||
|
||||
* added sharding :-)
|
||||
|
||||
* INCOMPATIBLE CHANGE: using complex values in AQL filter conditions with operators other
|
||||
than equality (e.g. >=, >, <=, <) will disable usage of skiplist indexes for filter
|
||||
evaluation.
|
||||
|
||||
For example, the following queries will be affected by change:
|
||||
|
||||
FOR doc IN docs FILTER doc.value < { foo: "bar" } RETURN doc
|
||||
FOR doc IN docs FILTER doc.value >= [ 1, 2, 3 ] RETURN doc
|
||||
|
||||
The following queries will not be affected by the change:
|
||||
|
||||
FOR doc IN docs FILTER doc.value == 1 RETURN doc
|
||||
FOR doc IN docs FILTER doc.value == "foo" RETURN doc
|
||||
FOR doc IN docs FILTER doc.value == [ 1, 2, 3 ] RETURN doc
|
||||
FOR doc IN docs FILTER doc.value == { foo: "bar" } RETURN doc
|
||||
|
||||
* added explicit startup parameter `--server.reuse-address`
|
||||
|
||||
* removed undocumented REST API method GET `/_admin/database-name`
|
||||
|
|
|
@ -452,6 +452,31 @@ TRI_aql_index_t* TRI_DetermineIndexAql (TRI_aql_context_t* const context,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (candidate->_type == TRI_AQL_ACCESS_RANGE_SINGLE) {
|
||||
// range type. check if the compare value is a list or an object
|
||||
TRI_json_t* value = candidate->_value._singleRange._value;
|
||||
|
||||
if (TRI_IsListJson(value) || TRI_IsArrayJson(value)) {
|
||||
// list or object, we cannot use this for comparison in a skiplist
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (candidate->_type == TRI_AQL_ACCESS_RANGE_DOUBLE) {
|
||||
// range type. check if the compare value is a list or an object
|
||||
TRI_json_t* value = candidate->_value._between._lower._value;
|
||||
|
||||
if (TRI_IsListJson(value) || TRI_IsArrayJson(value)) {
|
||||
// list or object, we cannot use this for comparison in a skiplist
|
||||
continue;
|
||||
}
|
||||
|
||||
value = candidate->_value._between._upper._value;
|
||||
if (TRI_IsListJson(value) || TRI_IsArrayJson(value)) {
|
||||
// list or object, we cannot use this for comparison in a skiplist
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
lastTypeWasExact = candidateIsExact;
|
||||
|
||||
TRI_PushBackVectorPointer(&matches, candidate);
|
||||
|
|
|
@ -161,8 +161,7 @@ void TRI_ClearIndexOperator(TRI_index_operator_t* indexOperator) {
|
|||
case TRI_GT_INDEX_OPERATOR:
|
||||
case TRI_NE_INDEX_OPERATOR:
|
||||
case TRI_LE_INDEX_OPERATOR:
|
||||
case TRI_LT_INDEX_OPERATOR:
|
||||
case TRI_IN_INDEX_OPERATOR: {
|
||||
case TRI_LT_INDEX_OPERATOR: {
|
||||
relationOperator = (TRI_relation_index_operator_t*)(indexOperator);
|
||||
if (relationOperator->_parameters != NULL) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, relationOperator->_parameters);
|
||||
|
@ -233,9 +232,7 @@ TRI_index_operator_t* TRI_CopyIndexOperator(TRI_index_operator_t* indexOperator)
|
|||
case TRI_GT_INDEX_OPERATOR:
|
||||
case TRI_NE_INDEX_OPERATOR:
|
||||
case TRI_LE_INDEX_OPERATOR:
|
||||
case TRI_LT_INDEX_OPERATOR:
|
||||
case TRI_IN_INDEX_OPERATOR: {
|
||||
|
||||
case TRI_LT_INDEX_OPERATOR: {
|
||||
oldRelationOperator = (TRI_relation_index_operator_t*)(indexOperator);
|
||||
newRelationOperator = (TRI_relation_index_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_relation_index_operator_t), false));
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ typedef enum {
|
|||
TRI_LT_INDEX_OPERATOR,
|
||||
TRI_GE_INDEX_OPERATOR,
|
||||
TRI_GT_INDEX_OPERATOR,
|
||||
TRI_IN_INDEX_OPERATOR,
|
||||
|
||||
TRI_AND_INDEX_OPERATOR,
|
||||
TRI_NOT_INDEX_OPERATOR,
|
||||
|
|
|
@ -268,7 +268,7 @@ int Syncer::applyCollectionDumpMarker (TRI_transaction_collection_t* trxCollecti
|
|||
|
||||
TRI_primary_collection_t* primary = trxCollection->_collection->_collection;
|
||||
TRI_memory_zone_t* zone = primary->_shaper->_memoryZone;
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json);
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json, true, true);
|
||||
|
||||
if (shaped != 0) {
|
||||
TRI_doc_mptr_t mptr;
|
||||
|
|
|
@ -1895,7 +1895,7 @@ int RestReplicationHandler::applyCollectionDumpMarker (CollectionNameResolver co
|
|||
|
||||
TRI_primary_collection_t* primary = trxCollection->_collection->_collection;
|
||||
TRI_memory_zone_t* zone = primary->_shaper->_memoryZone;
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json);
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(primary->_shaper, json, true, true);
|
||||
|
||||
if (shaped != 0) {
|
||||
TRI_doc_mptr_t mptr;
|
||||
|
|
|
@ -207,7 +207,7 @@ static int CmpElmElm(void* sli, void* left, void* right,
|
|||
/// @brief compares a key with an element in a skip list, generic callback
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CmpKeyElm(void* sli, void* left, void* right) {
|
||||
static int CmpKeyElm (void* sli, void* left, void* right) {
|
||||
|
||||
SkiplistIndex* skiplistindex = sli;
|
||||
TRI_skiplist_index_key_t* leftKey = left;
|
||||
|
|
|
@ -844,7 +844,7 @@ namespace triagens {
|
|||
|
||||
TRI_shaper_t* shaper = this->shaper(trxCollection);
|
||||
TRI_memory_zone_t* zone = shaper->_memoryZone;
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(shaper, json);
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(shaper, json, true, isLocked(trxCollection, TRI_TRANSACTION_WRITE));
|
||||
|
||||
if (shaped == 0) {
|
||||
return TRI_ERROR_ARANGO_SHAPER_FAILED;
|
||||
|
@ -909,7 +909,7 @@ namespace triagens {
|
|||
|
||||
TRI_shaper_t* shaper = this->shaper(trxCollection);
|
||||
TRI_memory_zone_t* zone = shaper->_memoryZone;
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(shaper, json);
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(shaper, json, true, isLocked(trxCollection, TRI_TRANSACTION_WRITE));
|
||||
|
||||
if (shaped == 0) {
|
||||
return TRI_ERROR_ARANGO_SHAPER_FAILED;
|
||||
|
|
|
@ -122,6 +122,21 @@ query_t;
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return an empty result set
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static v8::Handle<v8::Value> EmptyResult () {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
result->Set(v8::String::New("documents"), v8::Array::New());
|
||||
result->Set(v8::String::New("total"), v8::Number::New(0));
|
||||
result->Set(v8::String::New("count"), v8::Number::New(0));
|
||||
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief extracts skip and limit
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -212,7 +227,7 @@ static void CleanupExampleObject (TRI_memory_zone_t* zone,
|
|||
/// @brief sets up the example object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int SetupExampleObject (v8::Handle<v8::Object> example,
|
||||
static int SetupExampleObject (v8::Handle<v8::Object> const& example,
|
||||
TRI_shaper_t* shaper,
|
||||
size_t& n,
|
||||
TRI_shape_pid_t*& pids,
|
||||
|
@ -250,8 +265,15 @@ static int SetupExampleObject (v8::Handle<v8::Object> example,
|
|||
TRI_Utf8ValueNFC keyStr(TRI_UNKNOWN_MEM_ZONE, key);
|
||||
|
||||
if (*keyStr != 0) {
|
||||
pids[i] = shaper->findAttributePathByName(shaper, *keyStr);
|
||||
values[i] = TRI_ShapedJsonV8Object(val, shaper);
|
||||
pids[i] = shaper->lookupAttributePathByName(shaper, *keyStr);
|
||||
|
||||
if (pids[i] == 0) {
|
||||
// no attribute path found. this means the result will be empty
|
||||
CleanupExampleObject(shaper->_memoryZone, i, pids, values);
|
||||
return TRI_RESULT_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
values[i] = TRI_ShapedJsonV8Object(val, shaper, false, false);
|
||||
}
|
||||
|
||||
if (*keyStr == 0 || pids[i] == 0 || values[i] == 0) {
|
||||
|
@ -951,6 +973,8 @@ static int SetupSearchValue (TRI_vector_t const* paths,
|
|||
// convert
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
TRI_shape_pid_t pid = * (TRI_shape_pid_t*) TRI_AtVector(paths, i);
|
||||
|
||||
assert(pid != 0);
|
||||
char const* name = TRI_AttributeNameShapePid(shaper, pid);
|
||||
|
||||
if (name == NULL) {
|
||||
|
@ -965,15 +989,18 @@ static int SetupSearchValue (TRI_vector_t const* paths,
|
|||
if (example->HasOwnProperty(key)) {
|
||||
v8::Handle<v8::Value> val = example->Get(key);
|
||||
|
||||
res = TRI_FillShapedJsonV8Object(val, &result._values[i], shaper);
|
||||
res = TRI_FillShapedJsonV8Object(val, &result._values[i], shaper, false, false);
|
||||
}
|
||||
else {
|
||||
res = TRI_FillShapedJsonV8Object(v8::Null(), &result._values[i], shaper);
|
||||
res = TRI_FillShapedJsonV8Object(v8::Null(), &result._values[i], shaper, false, false);
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
DestroySearchValue(shaper->_memoryZone, result);
|
||||
*err = TRI_CreateErrorObject(res, "cannot convert value to JSON");
|
||||
|
||||
if (res != TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
*err = TRI_CreateErrorObject(res, "cannot convert value to JSON");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -1078,6 +1105,11 @@ static v8::Handle<v8::Value> ExecuteSkiplistQuery (v8::Arguments const& argv,
|
|||
TRI_skiplist_iterator_t* skiplistIterator = TRI_LookupSkiplistIndex(idx, skiplistOperator);
|
||||
|
||||
if (skiplistIterator == 0) {
|
||||
int res = TRI_errno();
|
||||
if (res == TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
return scope.Close(EmptyResult());
|
||||
}
|
||||
|
||||
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_NO_INDEX);
|
||||
}
|
||||
|
||||
|
@ -1953,6 +1985,11 @@ static v8::Handle<v8::Value> JS_ByExampleQuery (v8::Arguments const& argv) {
|
|||
v8::Handle<v8::Object> err;
|
||||
res = SetupExampleObject(example, shaper, n, pids, values, &err);
|
||||
|
||||
if (res == TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
// empty result
|
||||
return scope.Close(EmptyResult());
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return scope.Close(v8::ThrowException(err));
|
||||
}
|
||||
|
@ -2085,6 +2122,10 @@ static v8::Handle<v8::Value> ByExampleHashIndexQuery (ReadTransactionType& trx,
|
|||
int res = SetupSearchValue(&hashIndex->_paths, example, shaper, searchValue, err);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
if (res == TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
return scope.Close(EmptyResult());
|
||||
}
|
||||
|
||||
return scope.Close(v8::ThrowException(*err));
|
||||
}
|
||||
|
||||
|
|
|
@ -2465,6 +2465,11 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
|
|||
TRI_memory_zone_t* zone = primary->_shaper->_memoryZone;
|
||||
|
||||
TRI_doc_mptr_t document;
|
||||
|
||||
// we must lock here, because below we are
|
||||
// - reading the old document in coordinator case
|
||||
// - creating a shape, which might trigger a write into the collection
|
||||
trx.lockWrite();
|
||||
|
||||
#ifdef TRI_ENABLE_CLUSTER
|
||||
if (ServerState::instance()->isDBserver()) {
|
||||
|
@ -2478,7 +2483,6 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
|
|||
TRI_V8_EXCEPTION_MEMORY(scope);
|
||||
}
|
||||
|
||||
trx.lockWrite();
|
||||
res = trx.read(&document, key);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR || document._key == 0 || document._data == 0) {
|
||||
|
@ -2509,8 +2513,7 @@ static v8::Handle<v8::Value> ReplaceVocbaseCol (bool useCollection,
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(argv[1], primary->_shaper);
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(argv[1], primary->_shaper, true, true);
|
||||
|
||||
if (shaped == 0) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, key);
|
||||
|
@ -2575,12 +2578,13 @@ static v8::Handle<v8::Value> SaveVocbaseCol (
|
|||
|
||||
TRI_primary_collection_t* primary = trx->primaryCollection();
|
||||
TRI_memory_zone_t* zone = primary->_shaper->_memoryZone;
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(argv[0], primary->_shaper);
|
||||
|
||||
trx->lockWrite();
|
||||
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(argv[0], primary->_shaper, true, true);
|
||||
|
||||
if (shaped == 0) {
|
||||
if (key != 0) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, key);
|
||||
}
|
||||
FREE_STRING(TRI_CORE_MEM_ZONE, key);
|
||||
TRI_V8_EXCEPTION_MESSAGE(scope, TRI_errno(), "<data> cannot be converted into JSON shape");
|
||||
}
|
||||
|
||||
|
@ -2593,9 +2597,7 @@ static v8::Handle<v8::Value> SaveVocbaseCol (
|
|||
|
||||
TRI_FreeShapedJson(zone, shaped);
|
||||
|
||||
if (key != 0) {
|
||||
TRI_FreeString(TRI_CORE_MEM_ZONE, key);
|
||||
}
|
||||
FREE_STRING(TRI_CORE_MEM_ZONE, key);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_V8_EXCEPTION(scope, res);
|
||||
|
@ -2695,8 +2697,9 @@ static v8::Handle<v8::Value> SaveEdgeCol (
|
|||
TRI_primary_collection_t* primary = trx->primaryCollection();
|
||||
TRI_memory_zone_t* zone = primary->_shaper->_memoryZone;
|
||||
|
||||
trx->lockWrite();
|
||||
// extract shaped data
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(argv[2], primary->_shaper);
|
||||
TRI_shaped_json_t* shaped = TRI_ShapedJsonV8Object(argv[2], primary->_shaper, true, true);
|
||||
|
||||
if (shaped == 0) {
|
||||
FREE_STRING(TRI_CORE_MEM_ZONE, edge._fromKey);
|
||||
|
@ -10065,7 +10068,11 @@ static v8::Handle<v8::Integer> PropertyQueryShapedJson (v8::Local<v8::String> na
|
|||
|
||||
// get shape accessor
|
||||
TRI_shaper_t* shaper = collection->_shaper;
|
||||
TRI_shape_pid_t pid = shaper->findAttributePathByName(shaper, key.c_str());
|
||||
TRI_shape_pid_t pid = shaper->lookupAttributePathByName(shaper, key.c_str());
|
||||
|
||||
if (pid == 0) {
|
||||
return scope.Close(v8::Handle<v8::Integer>());
|
||||
}
|
||||
|
||||
TRI_shape_sid_t sid;
|
||||
TRI_EXTRACT_SHAPE_IDENTIFIER_MARKER(sid, marker);
|
||||
|
|
|
@ -118,7 +118,11 @@ static char* ExtractStringShapedJson (TRI_shaper_t* shaper,
|
|||
bool ok;
|
||||
char* result;
|
||||
|
||||
pid = shaper->findAttributePathByName(shaper, path);
|
||||
pid = shaper->lookupAttributePathByName(shaper, path);
|
||||
|
||||
if (pid == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ok = TRI_ExtractShapedJsonVocShaper(shaper, document, 0, pid, &shaped, &shape);
|
||||
|
||||
|
@ -165,7 +169,12 @@ static bool ExtractBooleanShapedJson (TRI_shaper_t* shaper,
|
|||
*found = false;
|
||||
}
|
||||
|
||||
pid = shaper->findAttributePathByName(shaper, path);
|
||||
pid = shaper->lookupAttributePathByName(shaper, path);
|
||||
|
||||
if (pid == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ok = TRI_ExtractShapedJsonVocShaper(shaper, document, 0, pid, &shaped, &shape);
|
||||
|
||||
if (! ok || shape == NULL) {
|
||||
|
|
|
@ -1214,21 +1214,23 @@ int TRI_WriteElementDatafile (TRI_datafile_t* datafile,
|
|||
#ifdef TRI_ENABLE_MAINTAINER_MODE
|
||||
// check _tick value of marker and set min/max tick values for datafile
|
||||
if (tick <= datafile->_tickMin || tick <= (TRI_voc_tick_t) datafile->_fid) {
|
||||
LOG_WARNING("logic error. invalid tick value %llu encountered when writing marker of type %d into datafile '%s'. "
|
||||
LOG_FATAL_AND_EXIT("logic error. invalid tick value %llu encountered when writing marker of type %d into datafile '%s'. "
|
||||
"expected tick value > tickMin %llu",
|
||||
(unsigned long long) tick,
|
||||
(int) marker->_type,
|
||||
datafile->getName(datafile),
|
||||
(unsigned long long) datafile->_tickMin);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (tick <= datafile->_tickMax) {
|
||||
LOG_WARNING("logic error. invalid tick value %llu encountered when writing marker of type %d into datafile '%s'. "
|
||||
LOG_FATAL_AND_EXIT("logic error. invalid tick value %llu encountered when writing marker of type %d into datafile '%s'. "
|
||||
"expected tick value > tickMax %llu",
|
||||
(unsigned long long) tick,
|
||||
(int) marker->_type,
|
||||
datafile->getName(datafile),
|
||||
(unsigned long long) datafile->_tickMax);
|
||||
assert(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4210,11 +4210,12 @@ bool TRI_DropIndex2DocumentCollection (TRI_document_collection_t* document,
|
|||
/// freed.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
||||
TRI_shaper_t* shaper,
|
||||
TRI_vector_t* pids,
|
||||
TRI_vector_pointer_t* names,
|
||||
bool sorted) {
|
||||
static int PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
||||
TRI_shaper_t* shaper,
|
||||
TRI_vector_t* pids,
|
||||
TRI_vector_pointer_t* names,
|
||||
bool sorted,
|
||||
bool create) {
|
||||
pid_name_t* pidnames;
|
||||
size_t j;
|
||||
|
||||
|
@ -4223,17 +4224,23 @@ int TRI_PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
// .............................................................................
|
||||
|
||||
if (sorted) {
|
||||
|
||||
// combine name and pid
|
||||
pidnames = TRI_Allocate(TRI_CORE_MEM_ZONE, sizeof(pid_name_t) * attributes->_length, false);
|
||||
|
||||
if (pidnames == NULL) {
|
||||
LOG_ERROR("out of memory in TRI_PidNamesByAttributeNames");
|
||||
LOG_ERROR("out of memory in PidNamesByAttributeNames");
|
||||
return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
for (j = 0; j < attributes->_length; ++j) {
|
||||
pidnames[j]._name = attributes->_buffer[j];
|
||||
pidnames[j]._pid = shaper->findAttributePathByName(shaper, pidnames[j]._name);
|
||||
|
||||
if (create) {
|
||||
pidnames[j]._pid = shaper->findOrCreateAttributePathByName(shaper, pidnames[j]._name, true);
|
||||
}
|
||||
else {
|
||||
pidnames[j]._pid = shaper->lookupAttributePathByName(shaper, pidnames[j]._name);
|
||||
}
|
||||
|
||||
if (pidnames[j]._pid == 0) {
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, pidnames);
|
||||
|
@ -4270,7 +4277,13 @@ int TRI_PidNamesByAttributeNames (TRI_vector_pointer_t const* attributes,
|
|||
TRI_shape_pid_t pid;
|
||||
|
||||
name = attributes->_buffer[j];
|
||||
pid = shaper->findAttributePathByName(shaper, name);
|
||||
|
||||
if (create) {
|
||||
pid = shaper->findOrCreateAttributePathByName(shaper, name, true);
|
||||
}
|
||||
else {
|
||||
pid = shaper->lookupAttributePathByName(shaper, name);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
TRI_DestroyVector(pids);
|
||||
|
@ -4550,7 +4563,7 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t*
|
|||
shaper = primary->_shaper;
|
||||
|
||||
if (location != NULL) {
|
||||
loc = shaper->findAttributePathByName(shaper, location);
|
||||
loc = shaper->findOrCreateAttributePathByName(shaper, location, true);
|
||||
|
||||
if (loc == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -4559,7 +4572,7 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t*
|
|||
}
|
||||
|
||||
if (latitude != NULL) {
|
||||
lat = shaper->findAttributePathByName(shaper, latitude);
|
||||
lat = shaper->findOrCreateAttributePathByName(shaper, latitude, true);
|
||||
|
||||
if (lat == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -4568,7 +4581,7 @@ static TRI_index_t* CreateGeoIndexDocumentCollection (TRI_document_collection_t*
|
|||
}
|
||||
|
||||
if (longitude != NULL) {
|
||||
lon = shaper->findAttributePathByName(shaper, longitude);
|
||||
lon = shaper->findOrCreateAttributePathByName(shaper, longitude, true);
|
||||
|
||||
if (lon == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -4817,10 +4830,9 @@ TRI_index_t* TRI_LookupGeoIndex1DocumentCollection (TRI_document_collection_t* d
|
|||
|
||||
shaper = document->base._shaper;
|
||||
|
||||
loc = shaper->findAttributePathByName(shaper, location);
|
||||
loc = shaper->lookupAttributePathByName(shaper, location);
|
||||
|
||||
if (loc == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -4863,11 +4875,10 @@ TRI_index_t* TRI_LookupGeoIndex2DocumentCollection (TRI_document_collection_t* d
|
|||
|
||||
shaper = document->base._shaper;
|
||||
|
||||
lat = shaper->findAttributePathByName(shaper, latitude);
|
||||
lon = shaper->findAttributePathByName(shaper, longitude);
|
||||
lat = shaper->lookupAttributePathByName(shaper, latitude);
|
||||
lon = shaper->lookupAttributePathByName(shaper, longitude);
|
||||
|
||||
if (lat == 0 || lon == 0) {
|
||||
TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -5030,11 +5041,12 @@ static TRI_index_t* CreateHashIndexDocumentCollection (TRI_document_collection_t
|
|||
idx = NULL;
|
||||
|
||||
// determine the sorted shape ids for the attributes
|
||||
res = TRI_PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
true);
|
||||
res = PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
true,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
if (created != NULL) {
|
||||
|
@ -5142,19 +5154,17 @@ TRI_index_t* TRI_LookupHashIndexDocumentCollection (TRI_document_collection_t* d
|
|||
TRI_vector_pointer_t const* attributes,
|
||||
bool unique) {
|
||||
TRI_index_t* idx;
|
||||
TRI_primary_collection_t* primary;
|
||||
TRI_vector_pointer_t fields;
|
||||
TRI_vector_t paths;
|
||||
int res;
|
||||
|
||||
primary = &document->base;
|
||||
|
||||
// determine the sorted shape ids for the attributes
|
||||
res = TRI_PidNamesByAttributeNames(attributes,
|
||||
primary->_shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
true);
|
||||
res = PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
true,
|
||||
false);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return NULL;
|
||||
|
@ -5249,11 +5259,12 @@ static TRI_index_t* CreateSkiplistIndexDocumentCollection (TRI_document_collecti
|
|||
TRI_vector_t paths;
|
||||
int res;
|
||||
|
||||
res = TRI_PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false);
|
||||
res = PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
if (created != NULL) {
|
||||
|
@ -5354,19 +5365,17 @@ TRI_index_t* TRI_LookupSkiplistIndexDocumentCollection (TRI_document_collection_
|
|||
TRI_vector_pointer_t const* attributes,
|
||||
bool unique) {
|
||||
TRI_index_t* idx;
|
||||
TRI_primary_collection_t* primary;
|
||||
TRI_vector_pointer_t fields;
|
||||
TRI_vector_t paths;
|
||||
int res;
|
||||
|
||||
primary = &document->base;
|
||||
|
||||
// determine the unsorted shape ids for the attributes
|
||||
res = TRI_PidNamesByAttributeNames(attributes,
|
||||
primary->_shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false);
|
||||
res = PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
false);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return NULL;
|
||||
|
@ -5738,11 +5747,12 @@ static TRI_index_t* CreateBitarrayIndexDocumentCollection (TRI_document_collecti
|
|||
TRI_vector_t paths;
|
||||
int res;
|
||||
|
||||
res = TRI_PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false);
|
||||
res = PidNamesByAttributeNames(attributes,
|
||||
document->base._shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
true);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
if (created != NULL) {
|
||||
|
@ -5883,7 +5893,12 @@ TRI_index_t* TRI_LookupBitarrayIndexDocumentCollection (TRI_document_collection_
|
|||
// determine the unsorted shape ids for the attributes
|
||||
// ...........................................................................
|
||||
|
||||
result = TRI_PidNamesByAttributeNames(attributes, primary->_shaper, &paths, &fields, false);
|
||||
result = PidNamesByAttributeNames(attributes,
|
||||
primary->_shaper,
|
||||
&paths,
|
||||
&fields,
|
||||
false,
|
||||
false);
|
||||
|
||||
if (result != TRI_ERROR_NO_ERROR) {
|
||||
return NULL;
|
||||
|
|
|
@ -558,16 +558,6 @@ struct TRI_index_s* TRI_EnsureGeoIndex2DocumentCollection (TRI_document_collecti
|
|||
/// @{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts attribute names to sorted lists of pids and names
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_PidNamesByAttributeNames (TRI_vector_pointer_t const*,
|
||||
TRI_shaper_t*,
|
||||
TRI_vector_t*,
|
||||
TRI_vector_pointer_t*,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds a hash index
|
||||
///
|
||||
|
|
|
@ -1031,8 +1031,7 @@ static int FillLookupSLOperator (TRI_index_operator_t* slOperator,
|
|||
case TRI_AND_INDEX_OPERATOR:
|
||||
case TRI_NOT_INDEX_OPERATOR:
|
||||
case TRI_OR_INDEX_OPERATOR: {
|
||||
|
||||
logicalOperator = (TRI_logical_index_operator_t*)(slOperator);
|
||||
logicalOperator = (TRI_logical_index_operator_t*) slOperator;
|
||||
result = FillLookupSLOperator(logicalOperator->_left, primary);
|
||||
if (result == TRI_ERROR_NO_ERROR) {
|
||||
result = FillLookupSLOperator(logicalOperator->_right, primary);
|
||||
|
@ -1049,19 +1048,29 @@ static int FillLookupSLOperator (TRI_index_operator_t* slOperator,
|
|||
case TRI_NE_INDEX_OPERATOR:
|
||||
case TRI_LE_INDEX_OPERATOR:
|
||||
case TRI_LT_INDEX_OPERATOR: {
|
||||
|
||||
relationOperator = (TRI_relation_index_operator_t*)(slOperator);
|
||||
relationOperator = (TRI_relation_index_operator_t*) slOperator;
|
||||
relationOperator->_numFields = relationOperator->_parameters->_value._objects._length;
|
||||
|
||||
relationOperator->_fields = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * relationOperator->_numFields, false);
|
||||
|
||||
if (relationOperator->_fields != NULL) {
|
||||
for (j = 0; j < relationOperator->_numFields; ++j) {
|
||||
jsonObject = (TRI_json_t*) (TRI_AtVector(&(relationOperator->_parameters->_value._objects),j));
|
||||
shapedObject = TRI_ShapedJsonJson(primary->_shaper, jsonObject);
|
||||
if (shapedObject) {
|
||||
jsonObject = (TRI_json_t*) (TRI_AtVector(&(relationOperator->_parameters->_value._objects), j));
|
||||
|
||||
if ((TRI_IsListJson(jsonObject) || TRI_IsArrayJson(jsonObject)) &&
|
||||
slOperator->_type != TRI_EQ_INDEX_OPERATOR) {
|
||||
// non-equality operator used on complex data type, this is disallowed
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
shapedObject = TRI_ShapedJsonJson(primary->_shaper, jsonObject, false, false);
|
||||
|
||||
if (shapedObject != NULL) {
|
||||
relationOperator->_fields[j] = *shapedObject; // shallow copy here is ok
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shapedObject); // don't require storage anymore
|
||||
}
|
||||
else {
|
||||
return TRI_RESULT_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1069,103 +1078,6 @@ static int FillLookupSLOperator (TRI_index_operator_t* slOperator,
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// .........................................................................
|
||||
// This index operator is special
|
||||
// The parameters are given to us as a list of json objects for EQ(...),
|
||||
// however for the IN(...) operator each parameter in the parameters list
|
||||
// is itself a list. For skiplists, the number of parameters is a
|
||||
// decreasing sequence. That is, for a skiplist with 3 attributes,
|
||||
// the parameters [ ["a","b","c","d"],["x","y"],[0] ] are allowed, whereas
|
||||
// the parameters [ ["a","b","c"], ["x","y"], [0,1,2] ] are not allowed.
|
||||
// .........................................................................
|
||||
|
||||
case TRI_IN_INDEX_OPERATOR: {
|
||||
int maxEntries;
|
||||
|
||||
relationOperator = (TRI_relation_index_operator_t*)(slOperator);
|
||||
relationOperator->_numFields = 0;
|
||||
relationOperator->_fields = NULL;
|
||||
|
||||
// .......................................................................
|
||||
// check that the parameters field is not null
|
||||
// .......................................................................
|
||||
|
||||
if (relationOperator->_parameters == NULL) {
|
||||
LOG_WARNING("No parameters given when using Skiplist lookup index");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// check that the parameters json object is of the type list
|
||||
// .......................................................................
|
||||
|
||||
if (relationOperator->_parameters->_type != TRI_JSON_LIST) {
|
||||
LOG_WARNING("Format of parameters given when using Skiplist lookup index are invalid (a)");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// .......................................................................
|
||||
// Each entry in the list is itself a list
|
||||
// .......................................................................
|
||||
|
||||
relationOperator->_numFields = relationOperator->_parameters->_value._objects._length;
|
||||
relationOperator->_fields = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * relationOperator->_numFields, false);
|
||||
|
||||
if (relationOperator->_fields == NULL) {
|
||||
relationOperator->_numFields = 0; // out of memory?
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
maxEntries = -1;
|
||||
|
||||
for (j = 0; j < relationOperator->_numFields; ++j) {
|
||||
jsonObject = (TRI_json_t*) (TRI_AtVector(&(relationOperator->_parameters->_value._objects),j));
|
||||
|
||||
if (jsonObject == NULL) {
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (jsonObject->_type != TRI_JSON_LIST) {
|
||||
result = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
// check and see that entries are non-increasing
|
||||
if ((int) jsonObject->_value._objects._length > maxEntries) {
|
||||
if (maxEntries > 0) {
|
||||
result = -3;
|
||||
break;
|
||||
}
|
||||
maxEntries = (int) jsonObject->_value._objects._length;
|
||||
}
|
||||
|
||||
// convert json to shaped json
|
||||
shapedObject = TRI_ShapedJsonJson(primary->_shaper, jsonObject);
|
||||
if (shapedObject == NULL) {
|
||||
result = -4;
|
||||
break;
|
||||
}
|
||||
|
||||
// store shaped json list
|
||||
relationOperator->_fields[j] = *shapedObject; // shallow copy here is ok
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shapedObject); // don't require storage anymore
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE,relationOperator->_fields);
|
||||
relationOperator->_fields = NULL;
|
||||
relationOperator->_numFields = 0;
|
||||
LOG_WARNING("Format of parameters given when using Skiplist lookup index are invalid (b)");
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
@ -1199,11 +1111,14 @@ TRI_skiplist_iterator_t* TRI_LookupSkiplistIndex (TRI_index_t* idx,
|
|||
errorResult = FillLookupSLOperator(slOperator, skiplistIndex->base._collection);
|
||||
|
||||
if (errorResult != TRI_ERROR_NO_ERROR) {
|
||||
TRI_set_errno(errorResult);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iteratorResult = SkiplistIndex_find(skiplistIndex->_skiplistIndex,
|
||||
&skiplistIndex->_paths, slOperator);
|
||||
&skiplistIndex->_paths,
|
||||
slOperator);
|
||||
|
||||
// .........................................................................
|
||||
// we must deallocate any memory we allocated in FillLookupSLOperator
|
||||
|
@ -1837,7 +1752,7 @@ TRI_index_t* TRI_CreateFulltextIndex (struct TRI_primary_collection_s* primary,
|
|||
|
||||
// look up the attribute
|
||||
shaper = primary->_shaper;
|
||||
attribute = shaper->findAttributePathByName(shaper, attributeName);
|
||||
attribute = shaper->findOrCreateAttributePathByName(shaper, attributeName, true);
|
||||
|
||||
if (attribute == 0) {
|
||||
return NULL;
|
||||
|
@ -1991,14 +1906,6 @@ static int FillLookupBitarrayOperator(TRI_index_operator_t* indexOperator, TRI_p
|
|||
|
||||
}
|
||||
|
||||
|
||||
// .........................................................................
|
||||
// This index operator is special
|
||||
// .........................................................................
|
||||
|
||||
case TRI_IN_INDEX_OPERATOR: {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
|
|
@ -440,6 +440,7 @@ static int LogEvent (TRI_replication_logger_t* logger,
|
|||
int res;
|
||||
bool forceSync;
|
||||
bool withTid;
|
||||
bool lock;
|
||||
|
||||
assert(logger != NULL);
|
||||
assert(buffer != NULL);
|
||||
|
@ -506,10 +507,12 @@ static int LogEvent (TRI_replication_logger_t* logger,
|
|||
(unsigned long long) tid,
|
||||
(int) forceSync,
|
||||
TRI_BeginStringBuffer(buffer));
|
||||
|
||||
lock = isStandaloneOperation;
|
||||
|
||||
primary = logger->_trxCollection->_collection->_collection;
|
||||
zone = primary->_shaper->_memoryZone;
|
||||
shaped = TRI_ShapedJsonJson(primary->_shaper, &json);
|
||||
shaped = TRI_ShapedJsonJson(primary->_shaper, &json, true, ! lock);
|
||||
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &json);
|
||||
|
||||
ReturnBuffer(logger, buffer);
|
||||
|
@ -525,7 +528,7 @@ static int LogEvent (TRI_replication_logger_t* logger,
|
|||
TRI_DOC_MARKER_KEY_DOCUMENT,
|
||||
shaped,
|
||||
NULL,
|
||||
isStandaloneOperation,
|
||||
lock,
|
||||
forceSync,
|
||||
false);
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ static int InsertTrxCallback (TRI_transaction_collection_t* trxCollection,
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
shaped = TRI_ShapedJsonJson(primary->_shaper, coordinator->_json);
|
||||
shaped = TRI_ShapedJsonJson(primary->_shaper, coordinator->_json, true, true);
|
||||
|
||||
if (shaped == NULL) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
|
|
|
@ -343,9 +343,30 @@ static void FullSetAttributeWeight (voc_shaper_t* shaper) {
|
|||
/// @brief finds an attribute identifier by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_aid_t FindAttributeByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool create) {
|
||||
static TRI_shape_aid_t LookupAttributeByName (TRI_shaper_t* shaper,
|
||||
char const* name) {
|
||||
voc_shaper_t* s;
|
||||
void const* p;
|
||||
|
||||
assert(name != NULL);
|
||||
|
||||
s = (voc_shaper_t*) shaper;
|
||||
p = TRI_LookupByKeyAssociativeSynced(&s->_attributeNames, name);
|
||||
|
||||
if (p != NULL) {
|
||||
return ((TRI_df_attribute_marker_t const*) p)->_aid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief finds an attribute identifier by name
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_aid_t FindOrCreateAttributeByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool isLocked) {
|
||||
char* mem;
|
||||
TRI_df_attribute_marker_t* marker;
|
||||
TRI_df_marker_t* result;
|
||||
|
@ -372,10 +393,6 @@ static TRI_shape_aid_t FindAttributeByName (TRI_shaper_t* shaper,
|
|||
return ((TRI_df_attribute_marker_t const*) p)->_aid;
|
||||
}
|
||||
|
||||
if (! create) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// create a new attribute name
|
||||
n = strlen(name) + 1;
|
||||
|
||||
|
@ -415,9 +432,18 @@ static TRI_shape_aid_t FindAttributeByName (TRI_shaper_t* shaper,
|
|||
// get next attribute id and write into marker
|
||||
aid = s->_nextAid++;
|
||||
marker->_aid = aid;
|
||||
|
||||
|
||||
if (! isLocked) {
|
||||
// write-lock
|
||||
s->_collection->base.beginWrite(&s->_collection->base);
|
||||
}
|
||||
|
||||
// write attribute into the collection
|
||||
res = TRI_WriteMarkerDocumentCollection(s->_collection, &marker->base, totalSize, &fid, &result, false);
|
||||
|
||||
if (! isLocked) {
|
||||
s->_collection->base.endWrite(&s->_collection->base);
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, mem);
|
||||
|
||||
|
@ -548,7 +574,6 @@ static char const* LookupAttributeId (TRI_shaper_t* shaper, TRI_shape_aid_t aid)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief looks up an attribute weight by identifier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -617,7 +642,9 @@ static bool EqualElementShape (TRI_associative_synced_t* array, void const* left
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
|
||||
TRI_shape_t* shape) {
|
||||
TRI_shape_t* shape,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
char* mem;
|
||||
TRI_df_marker_t* result;
|
||||
TRI_df_shape_marker_t* marker;
|
||||
|
@ -645,6 +672,11 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
|
|||
return found;
|
||||
}
|
||||
|
||||
// not found
|
||||
if (! create) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// initialise a new shape marker
|
||||
totalSize = sizeof(TRI_df_shape_marker_t) + shape->_size;
|
||||
mem = (char*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, totalSize, false);
|
||||
|
@ -681,9 +713,19 @@ static TRI_shape_t const* FindShape (TRI_shaper_t* shaper,
|
|||
// get next shape number and write into marker
|
||||
((TRI_shape_t*) (mem + sizeof(TRI_df_shape_marker_t)))->_sid = s->_nextSid++;
|
||||
|
||||
if (! isLocked) {
|
||||
// write-lock
|
||||
s->_collection->base.beginWrite(&s->_collection->base);
|
||||
}
|
||||
|
||||
// write shape into the collection
|
||||
res = TRI_WriteMarkerDocumentCollection(s->_collection, &marker->base, totalSize, &fid, &result, false);
|
||||
|
||||
if (! isLocked) {
|
||||
// write-unlock
|
||||
s->_collection->base.endWrite(&s->_collection->base);
|
||||
}
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
TRI_UnlockMutex(&s->_shapeLock);
|
||||
|
||||
|
@ -953,10 +995,11 @@ static uint64_t HashElementWeightedAttribute (TRI_associative_pointer_t* array,
|
|||
static int InitStep1VocShaper (voc_shaper_t* shaper) {
|
||||
int res;
|
||||
|
||||
shaper->base.findAttributeByName = FindAttributeByName;
|
||||
shaper->base.lookupAttributeId = LookupAttributeId;
|
||||
shaper->base.findShape = FindShape;
|
||||
shaper->base.lookupShapeId = LookupShapeId;
|
||||
shaper->base.findOrCreateAttributeByName = FindOrCreateAttributeByName;
|
||||
shaper->base.lookupAttributeByName = LookupAttributeByName;
|
||||
shaper->base.lookupAttributeId = LookupAttributeId;
|
||||
shaper->base.findShape = FindShape;
|
||||
shaper->base.lookupShapeId = LookupShapeId;
|
||||
|
||||
res = TRI_InitAssociativeSynced(&shaper->_attributeNames,
|
||||
TRI_UNKNOWN_MEM_ZONE,
|
||||
|
|
|
@ -60,8 +60,8 @@ severity = human
|
|||
file = @LOCALSTATEDIR@/log/arangodb/arangod.log
|
||||
|
||||
[cluster]
|
||||
disable-dispatcher-kickstarter = false
|
||||
disable-dispatcher-frontend = false
|
||||
disable-dispatcher-kickstarter = yes
|
||||
disable-dispatcher-frontend = yes
|
||||
data-path = @LOCALSTATEDIR@/lib/arangodb/cluster
|
||||
log-path = @LOCALSTATEDIR@/log/arangodb/cluster
|
||||
agent-path = @LIBEXECDIR@/arangodb/etcd-arango@PROGRAM_SUFFIX@
|
||||
|
|
|
@ -19,19 +19,21 @@
|
|||
var i,j,r;
|
||||
r = this.get("runInfo");
|
||||
j = r.length-1;
|
||||
while (j > 0 && r[j].isStartServers === undefined) {
|
||||
j--;
|
||||
}
|
||||
var l = r[j];
|
||||
if (l.endpoints) {
|
||||
for (i = 0; i < l.endpoints.length;i++) {
|
||||
if (l.roles[i] === "Coordinator") {
|
||||
this._coord = l.endpoints[i]
|
||||
.replace("tcp://","http://")
|
||||
.replace("ssl://", "https://");
|
||||
return this._coord;
|
||||
while (j > 0) {
|
||||
if(r[j].isStartServers) {
|
||||
var l = r[j];
|
||||
if (l.endpoints) {
|
||||
for (i = 0; i < l.endpoints.length;i++) {
|
||||
if (l.roles[i] === "Coordinator") {
|
||||
this._coord = l.endpoints[i]
|
||||
.replace("tcp://","http://")
|
||||
.replace("ssl://", "https://");
|
||||
return this._coord;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
j--;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
<% if (!isSymmetric) { %>
|
||||
<div class="controls">
|
||||
<label class="checkbox inline">
|
||||
<input type="checkbox" value="isCoordinator" class="isCoordinator" checked> Coordinator
|
||||
<input type="checkbox" value="isCoordinator" class="isCoordinator" checked="checked"> Coordinator
|
||||
</label>
|
||||
<label class="checkbox inline">
|
||||
<input type="checkbox" value="isDBServer" class="isDBServer" checked> DBServer
|
||||
<input type="checkbox" value="isDBServer" class="isDBServer" checked="checked"> DBServer
|
||||
</label>
|
||||
</div>
|
||||
<% } %>
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
},
|
||||
|
||||
startPlan: function() {
|
||||
$('#waitModalLayer').modal('show');
|
||||
$('#waitModalMessage').html('Please be patient while your cluster will be launched');
|
||||
var isDBServer;
|
||||
var isCoordinator;
|
||||
var self = this;
|
||||
|
@ -33,8 +31,8 @@
|
|||
}
|
||||
var hostObject = {host : host + ":" + port};
|
||||
if (!self.isSymmetric) {
|
||||
hostObject.isDBServer = !!$(".isDBServer", dispatcher).attr('checked');
|
||||
hostObject.isCoordinator = !!$(".isCoordinator", dispatcher).attr('checked');
|
||||
hostObject.isDBServer = !!$(".isDBServer", dispatcher).prop('checked');
|
||||
hostObject.isCoordinator = !!$(".isCoordinator", dispatcher).prop('checked');
|
||||
} else {
|
||||
hostObject.isDBServer = true;
|
||||
hostObject.isCoordinator = true;
|
||||
|
@ -63,6 +61,8 @@
|
|||
}
|
||||
|
||||
data.type = this.isSymmetric ? "symmetricalSetup" : "asymmetricalSetup";
|
||||
$('#waitModalLayer').modal('show');
|
||||
$('#waitModalMessage').html('Please be patient while your cluster will be launched');
|
||||
this.model.save(
|
||||
data,
|
||||
{
|
||||
|
|
|
@ -226,13 +226,12 @@
|
|||
if (endDate) {
|
||||
filterString += " filter u.time < " + endDate;
|
||||
}
|
||||
var returnValue = " return u"
|
||||
var returnValue = " return u";
|
||||
if (figures) {
|
||||
var returnValue = " return {time : u.time, server : {uptime : u.server.uptime} ,"
|
||||
returnValue = " return {time : u.time, server : {uptime : u.server.uptime} ,";
|
||||
var groups = {};
|
||||
figures.forEach(function(f) {
|
||||
var g = f.split(".")[0];
|
||||
console.log("ggg", g);
|
||||
if (!groups[g]) {
|
||||
groups[g] = [];
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
var jsunity = require("jsunity");
|
||||
var internal = require("internal");
|
||||
var errors = internal.errors;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- basic methods
|
||||
|
@ -253,10 +254,22 @@ function SkipListSuite() {
|
|||
var val = values[i].a;
|
||||
var expect = documents.slice(i);
|
||||
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [[">=", val]] }, 0, null ).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
var isValid = ! ((val !== null && typeof val === 'object'));
|
||||
if (isValid) {
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [[">=", val]] }).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
|
||||
assertEqual([i, ">=", expect], [i, ">=", result]);
|
||||
assertEqual([i, ">=", expect], [i, ">=", result]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
collection.byConditionSkiplist(idx.id, { a: [[">=", val]] }).toArray();
|
||||
fail();
|
||||
}
|
||||
catch (err1) {
|
||||
assertEqual(errors.ERROR_ARANGO_NO_INDEX.code, err1.errorNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GREATER THAN
|
||||
|
@ -264,10 +277,22 @@ function SkipListSuite() {
|
|||
var val = values[i].a;
|
||||
var expect = documents.slice(i + 1);
|
||||
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [[">", val]] }, 0, null ).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
var isValid = ! ((val !== null && typeof val === 'object'));
|
||||
if (isValid) {
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [[">", val]] }).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
|
||||
assertEqual([i, ">", expect], [i, ">", result]);
|
||||
assertEqual([i, ">", expect], [i, ">", result]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
collection.byConditionSkiplist(idx.id, { a: [[">", val]] }).toArray();
|
||||
fail();
|
||||
}
|
||||
catch (err2) {
|
||||
assertEqual(errors.ERROR_ARANGO_NO_INDEX.code, err2.errorNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LESS THAN OR EQUAL
|
||||
|
@ -275,10 +300,22 @@ function SkipListSuite() {
|
|||
var val = values[i].a;
|
||||
var expect = documents.slice(1, i + 1);
|
||||
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [["<=", val]] }, 0, null ).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
var isValid = ! ((val !== null && typeof val === 'object'));
|
||||
if (isValid) {
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [["<=", val]] }).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
|
||||
assertEqual([i, "<=", expect], [i, "<=", result]);
|
||||
assertEqual([i, "<=", expect], [i, "<=", result]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
collection.byConditionSkiplist(idx.id, { a: [["<=", val]] }).toArray();
|
||||
fail();
|
||||
}
|
||||
catch (err3) {
|
||||
assertEqual(errors.ERROR_ARANGO_NO_INDEX.code, err3.errorNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -287,10 +324,22 @@ function SkipListSuite() {
|
|||
var val = values[i].a;
|
||||
var expect = documents.slice(1, i);
|
||||
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [["<", val]] }, 0, null ).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
var isValid = ! ((val !== null && typeof val === 'object'));
|
||||
if (isValid) {
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [["<", val]] }).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
|
||||
assertEqual([i, "<", expect], [i, "<", result]);
|
||||
assertEqual([i, "<", expect], [i, "<", result]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
collection.byConditionSkiplist(idx.id, { a: [["<", val]] }).toArray();
|
||||
fail();
|
||||
}
|
||||
catch (err4) {
|
||||
assertEqual(errors.ERROR_ARANGO_NO_INDEX.code, err4.errorNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BETWEEN
|
||||
|
@ -300,11 +349,27 @@ function SkipListSuite() {
|
|||
for (j = 1; j < documents.length; ++j) {
|
||||
var valj = values[j].a;
|
||||
var expect = documents.slice(i, j + 1);
|
||||
|
||||
var isValid = ! ((vali !== null && typeof vali === 'object'));
|
||||
if (isValid) {
|
||||
isValid &= ! ((valj !== null && typeof valj === 'object'));
|
||||
}
|
||||
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [[">=", vali], ["<=", valj]] }, 0, null ).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
if (isValid) {
|
||||
var res = collection.byConditionSkiplist(idx.id, { a: [[">=", vali], ["<=", valj]] }).toArray();
|
||||
var result = res.map(function(a) { return a._key; });
|
||||
|
||||
assertEqual([i, ">= <=", expect], [i, ">= <=", result]);
|
||||
assertEqual([i, ">= <=", expect], [i, ">= <=", result]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
collection.byConditionSkiplist(idx.id, { a: [[">=", vali], ["<=", valj]] }).toArray();
|
||||
fail();
|
||||
}
|
||||
catch (err5) {
|
||||
assertEqual(errors.ERROR_ARANGO_NO_INDEX.code, err5.errorNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,7 +179,8 @@ static bool EqualNameKeyAttributePath (TRI_associative_synced_t* array, void con
|
|||
|
||||
static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool create) {
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
TRI_shape_aid_t* aids;
|
||||
TRI_shape_path_t* result;
|
||||
size_t count;
|
||||
|
@ -242,10 +243,10 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
|
|||
|
||||
if (ptr != prev) {
|
||||
if (create) {
|
||||
aids[count++] = shaper->findAttributeByName(shaper, prev, true);
|
||||
aids[count++] = shaper->findOrCreateAttributeByName(shaper, prev, isLocked);
|
||||
}
|
||||
else {
|
||||
aids[count] = shaper->findAttributeByName(shaper, prev, false);
|
||||
aids[count] = shaper->lookupAttributeByName(shaper, prev);
|
||||
|
||||
if (aids[count] == 0) {
|
||||
TRI_FreeString(shaper->_memoryZone, buffer);
|
||||
|
@ -299,8 +300,10 @@ static TRI_shape_path_t const* FindShapePathByName (TRI_shaper_t* shaper,
|
|||
/// @brief finds an attribute path by identifier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_pid_t FindAttributePathByName (TRI_shaper_t* shaper, char const* name) {
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, true);
|
||||
static TRI_shape_pid_t FindOrCreateAttributePathByName (TRI_shaper_t* shaper,
|
||||
char const* name,
|
||||
bool isLocked) {
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, true, isLocked);
|
||||
|
||||
return path == NULL ? 0 : path->_pid;
|
||||
}
|
||||
|
@ -309,8 +312,9 @@ static TRI_shape_pid_t FindAttributePathByName (TRI_shaper_t* shaper, char const
|
|||
/// @brief looks up an attribute path by identifier
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_shape_pid_t LookupAttributePathByName (TRI_shaper_t* shaper, char const* name) {
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, false);
|
||||
static TRI_shape_pid_t LookupAttributePathByName (TRI_shaper_t* shaper,
|
||||
char const* name) {
|
||||
TRI_shape_path_t const* path = FindShapePathByName(shaper, name, false, true);
|
||||
|
||||
return path == NULL ? 0 : path->_pid;
|
||||
}
|
||||
|
@ -327,7 +331,8 @@ static TRI_shape_pid_t LookupAttributePathByName (TRI_shaper_t* shaper, char con
|
|||
/// @brief creates the attribute path
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* TRI_AttributeNameShapePid (TRI_shaper_t* shaper, TRI_shape_pid_t pid) {
|
||||
char const* TRI_AttributeNameShapePid (TRI_shaper_t* shaper,
|
||||
TRI_shape_pid_t pid) {
|
||||
TRI_shape_path_t const* path;
|
||||
char const* e;
|
||||
|
||||
|
@ -379,7 +384,7 @@ int TRI_InitShaper (TRI_shaper_t* shaper, TRI_memory_zone_t* zone) {
|
|||
shaper->_nextPid = 1;
|
||||
|
||||
shaper->lookupAttributePathByPid = LookupPidAttributePath;
|
||||
shaper->findAttributePathByName = FindAttributePathByName;
|
||||
shaper->findOrCreateAttributePathByName = FindOrCreateAttributePathByName;
|
||||
shaper->lookupAttributePathByName = LookupAttributePathByName;
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
|
|
|
@ -91,13 +91,14 @@ TRI_basic_shapes_t;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct TRI_shaper_s {
|
||||
TRI_shape_aid_t (*findAttributeByName) (struct TRI_shaper_s*, char const*, bool);
|
||||
TRI_shape_aid_t (*findOrCreateAttributeByName) (struct TRI_shaper_s*, char const*, bool);
|
||||
TRI_shape_aid_t (*lookupAttributeByName) (struct TRI_shaper_s*, char const*);
|
||||
char const* (*lookupAttributeId) (struct TRI_shaper_s*, TRI_shape_aid_t);
|
||||
TRI_shape_t const* (*findShape) (struct TRI_shaper_s*, TRI_shape_t*);
|
||||
TRI_shape_t const* (*findShape) (struct TRI_shaper_s*, TRI_shape_t*, bool, bool);
|
||||
TRI_shape_t const* (*lookupShapeId) (struct TRI_shaper_s*, TRI_shape_sid_t);
|
||||
int64_t (*lookupAttributeWeight) (struct TRI_shaper_s*, TRI_shape_aid_t);
|
||||
TRI_shape_path_t const* (*lookupAttributePathByPid) (struct TRI_shaper_s*, TRI_shape_pid_t);
|
||||
TRI_shape_pid_t (*findAttributePathByName) (struct TRI_shaper_s*, char const*);
|
||||
TRI_shape_pid_t (*findOrCreateAttributePathByName) (struct TRI_shaper_s*, char const*, bool);
|
||||
TRI_shape_pid_t (*lookupAttributePathByName) (struct TRI_shaper_s*, char const*);
|
||||
|
||||
TRI_associative_synced_t _attributePathsByName;
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
// --SECTION-- forward declarations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json);
|
||||
static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json, bool, bool);
|
||||
static TRI_json_t* JsonShapeData (TRI_shaper_t* shaper, TRI_shape_t const* shape, char const* data, uint64_t size);
|
||||
static bool StringifyJsonShapeData (TRI_shaper_t* shaper, TRI_string_buffer_t* buffer, TRI_shape_t const* shape, char const* data, uint64_t size);
|
||||
|
||||
|
@ -463,7 +463,11 @@ static bool FillShapeValueString (TRI_shaper_t* shaper, TRI_shape_value_t* dst,
|
|||
/// @brief converts a json list into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueList (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json) {
|
||||
static bool FillShapeValueList (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
TRI_json_t const* json,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
size_t i, n;
|
||||
uint64_t total;
|
||||
|
||||
|
@ -520,7 +524,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TR
|
|||
|
||||
for (i = 0; i < n; ++i, ++p) {
|
||||
TRI_json_t const* el = (TRI_json_t const*) TRI_AtVector(&json->_value._objects, i);
|
||||
bool ok = FillShapeValueJson(shaper, p, el);
|
||||
bool ok = FillShapeValueJson(shaper, p, el, create, isLocked);
|
||||
|
||||
if (! ok) {
|
||||
for (e = p, p = values; p < e; ++p) {
|
||||
|
@ -580,7 +584,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TR
|
|||
shape->_sidEntry = s;
|
||||
shape->_sizeEntry = l;
|
||||
|
||||
found = shaper->findShape(shaper, &shape->base);
|
||||
found = shaper->findShape(shaper, &shape->base, create, isLocked);
|
||||
|
||||
if (found == NULL) {
|
||||
for (p = values; p < e; ++p) {
|
||||
|
@ -649,7 +653,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TR
|
|||
shape->base._dataSize = TRI_SHAPE_SIZE_VARIABLE;
|
||||
shape->_sidEntry = s;
|
||||
|
||||
found = shaper->findShape(shaper, &shape->base);
|
||||
found = shaper->findShape(shaper, &shape->base, create, isLocked);
|
||||
|
||||
if (found == NULL) {
|
||||
for (p = values; p < e; ++p) {
|
||||
|
@ -770,7 +774,9 @@ static bool FillShapeValueList (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TR
|
|||
|
||||
static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
TRI_json_t const* json) {
|
||||
TRI_json_t const* json,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
size_t i, n;
|
||||
uint64_t total;
|
||||
|
||||
|
@ -831,14 +837,14 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
// first find an identifier for the name
|
||||
p->_aid = shaper->findAttributeByName(shaper, key->_value._string.data, true);
|
||||
p->_aid = shaper->findOrCreateAttributeByName(shaper, key->_value._string.data, isLocked);
|
||||
|
||||
// convert value
|
||||
if (p->_aid == 0) {
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
ok = FillShapeValueJson(shaper, p, val);
|
||||
ok = FillShapeValueJson(shaper, p, val, create, isLocked);
|
||||
}
|
||||
|
||||
if (! ok) {
|
||||
|
@ -987,7 +993,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
// lookup this shape
|
||||
found = shaper->findShape(shaper, &a->base);
|
||||
found = shaper->findShape(shaper, &a->base, create, isLocked);
|
||||
|
||||
if (found == NULL) {
|
||||
TRI_Free(shaper->_memoryZone, a);
|
||||
|
@ -1003,7 +1009,11 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
/// @brief converts a json object into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json) {
|
||||
static bool FillShapeValueJson (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
TRI_json_t const* json,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
switch (json->_type) {
|
||||
case TRI_JSON_UNUSED:
|
||||
return false;
|
||||
|
@ -1022,10 +1032,10 @@ static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TR
|
|||
return FillShapeValueString(shaper, dst, json);
|
||||
|
||||
case TRI_JSON_ARRAY:
|
||||
return FillShapeValueArray(shaper, dst, json);
|
||||
return FillShapeValueArray(shaper, dst, json, create, isLocked);
|
||||
|
||||
case TRI_JSON_LIST:
|
||||
return FillShapeValueList(shaper, dst, json);
|
||||
return FillShapeValueList(shaper, dst, json, create, isLocked);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2259,13 +2269,15 @@ void TRI_SortShapeValues (TRI_shape_value_t* values,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
|
||||
TRI_json_t const* json) {
|
||||
TRI_json_t const* json,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
TRI_shaped_json_t* shaped;
|
||||
TRI_shape_value_t dst;
|
||||
bool ok;
|
||||
|
||||
dst._value = 0;
|
||||
ok = FillShapeValueJson(shaper, &dst, json);
|
||||
ok = FillShapeValueJson(shaper, &dst, json, create, isLocked);
|
||||
|
||||
if (! ok) {
|
||||
return NULL;
|
||||
|
@ -2296,7 +2308,8 @@ TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
|
|||
/// @brief converts a shaped json object into a json object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_json_t* TRI_JsonShapedJson (TRI_shaper_t* shaper, TRI_shaped_json_t const* shaped) {
|
||||
TRI_json_t* TRI_JsonShapedJson (TRI_shaper_t* shaper,
|
||||
TRI_shaped_json_t const* shaped) {
|
||||
TRI_shape_t const* shape;
|
||||
|
||||
shape = shaper->lookupShapeId(shaper, shaped->_sid);
|
||||
|
|
|
@ -954,7 +954,8 @@ void TRI_DestroyShapedJson (struct TRI_memory_zone_s*, TRI_shaped_json_t*);
|
|||
/// @brief destroys a json object and frees the pointer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FreeShapedJson (struct TRI_memory_zone_s*, TRI_shaped_json_t*);
|
||||
void TRI_FreeShapedJson (struct TRI_memory_zone_s*,
|
||||
TRI_shaped_json_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @}
|
||||
|
@ -973,19 +974,24 @@ void TRI_FreeShapedJson (struct TRI_memory_zone_s*, TRI_shaped_json_t*);
|
|||
/// @brief sorts a list of TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_SortShapeValues (TRI_shape_value_t* values, size_t n);
|
||||
void TRI_SortShapeValues (TRI_shape_value_t* values,
|
||||
size_t n);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a json object into a shaped json object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_shaped_json_t* TRI_ShapedJsonJson (struct TRI_shaper_s*, TRI_json_t const*);
|
||||
TRI_shaped_json_t* TRI_ShapedJsonJson (struct TRI_shaper_s*,
|
||||
TRI_json_t const*,
|
||||
bool,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a shaped json object into a json object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_json_t* TRI_JsonShapedJson (struct TRI_shaper_s*, TRI_shaped_json_t const*);
|
||||
TRI_json_t* TRI_JsonShapedJson (struct TRI_shaper_s*,
|
||||
TRI_shaped_json_t const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief prints a shaped json to a string buffer, without the outer braces
|
||||
|
|
|
@ -46,11 +46,13 @@ using namespace triagens::basics;
|
|||
// --SECTION-- forward declarations
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static bool FillShapeValueJson (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Value> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects);
|
||||
static int FillShapeValueJson (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Value> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects,
|
||||
bool create,
|
||||
bool isLocked);
|
||||
|
||||
static v8::Handle<v8::Value> JsonShapeData (TRI_shaper_t* shaper,
|
||||
TRI_shape_t const* shape,
|
||||
|
@ -83,7 +85,7 @@ shape_cache_t;
|
|||
/// @brief converts a null into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueNull (TRI_shaper_t* shaper,
|
||||
static int FillShapeValueNull (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst) {
|
||||
dst->_type = TRI_SHAPE_NULL;
|
||||
dst->_sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NULL);
|
||||
|
@ -91,16 +93,16 @@ static bool FillShapeValueNull (TRI_shaper_t* shaper,
|
|||
dst->_size = 0;
|
||||
dst->_value = 0;
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a boolean into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueBoolean (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Boolean> const& json) {
|
||||
static int FillShapeValueBoolean (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Boolean> const& json) {
|
||||
TRI_shape_boolean_t* ptr;
|
||||
|
||||
dst->_type = TRI_SHAPE_BOOLEAN;
|
||||
|
@ -109,22 +111,22 @@ static bool FillShapeValueBoolean (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_boolean_t);
|
||||
dst->_value = (char*) (ptr = (TRI_shape_boolean_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*ptr = json->Value() ? 1 : 0;
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a boolean into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueBoolean (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::BooleanObject> const& json) {
|
||||
static int FillShapeValueBoolean (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::BooleanObject> const& json) {
|
||||
TRI_shape_boolean_t* ptr;
|
||||
|
||||
dst->_type = TRI_SHAPE_BOOLEAN;
|
||||
|
@ -133,22 +135,22 @@ static bool FillShapeValueBoolean (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_boolean_t);
|
||||
dst->_value = (char*) (ptr = (TRI_shape_boolean_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*ptr = json->BooleanValue() ? 1 : 0;
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a number into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueNumber (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Number> const& json) {
|
||||
static int FillShapeValueNumber (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Number> const& json) {
|
||||
TRI_shape_number_t* ptr;
|
||||
|
||||
dst->_type = TRI_SHAPE_NUMBER;
|
||||
|
@ -157,22 +159,22 @@ static bool FillShapeValueNumber (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_number_t);
|
||||
dst->_value = (char*) (ptr = (TRI_shape_number_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*ptr = json->Value();
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a number into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueNumber (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::NumberObject> const& json) {
|
||||
static int FillShapeValueNumber (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::NumberObject> const& json) {
|
||||
TRI_shape_number_t* ptr;
|
||||
|
||||
dst->_type = TRI_SHAPE_NUMBER;
|
||||
|
@ -181,22 +183,22 @@ static bool FillShapeValueNumber (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_number_t);
|
||||
dst->_value = (char*) (ptr = (TRI_shape_number_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
*ptr = json->NumberValue();
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a string into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueString (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::String> const& json) {
|
||||
static int FillShapeValueString (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::String> const& json) {
|
||||
char* ptr;
|
||||
|
||||
TRI_Utf8ValueNFC str(TRI_UNKNOWN_MEM_ZONE, json);
|
||||
|
@ -208,8 +210,8 @@ static bool FillShapeValueString (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
|
||||
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
* ((TRI_shape_length_short_string_t*) ptr) = 1;
|
||||
|
@ -225,8 +227,8 @@ static bool FillShapeValueString (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_length_short_string_t) + TRI_SHAPE_SHORT_STRING_CUT;
|
||||
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
* ((TRI_shape_length_short_string_t*) ptr) = size + 1;
|
||||
|
@ -239,8 +241,8 @@ static bool FillShapeValueString (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_length_long_string_t) + size + 1;
|
||||
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
* ((TRI_shape_length_long_string_t*) ptr) = size + 1;
|
||||
|
@ -248,18 +250,20 @@ static bool FillShapeValueString (TRI_shaper_t* shaper,
|
|||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a json list into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueList (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Array> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects) {
|
||||
static int FillShapeValueList (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Array> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
size_t i, n;
|
||||
size_t total;
|
||||
|
||||
|
@ -292,20 +296,20 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
dst->_size = sizeof(TRI_shape_length_list_t);
|
||||
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
|
||||
|
||||
if (dst->_value == NULL) {
|
||||
return false;
|
||||
if (dst->_value == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
* (TRI_shape_length_list_t*) ptr = 0;
|
||||
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
// convert into TRI_shape_value_t array
|
||||
p = (values = (TRI_shape_value_t*) TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_value_t) * n, true));
|
||||
|
||||
if (p == NULL) {
|
||||
return false;
|
||||
if (p == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
|
@ -313,13 +317,9 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
|
||||
for (i = 0; i < n; ++i, ++p) {
|
||||
v8::Handle<v8::Value> el = json->Get(i);
|
||||
bool ok = FillShapeValueJson(shaper, p, el, seenHashes, seenObjects);
|
||||
|
||||
if (! ok) {
|
||||
if (! ok) {
|
||||
LOG_TRACE("failed to convert position '%d'", (int) i);
|
||||
}
|
||||
int res = FillShapeValueJson(shaper, p, el, seenHashes, seenObjects, create, isLocked);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (e = p, p = values; p < e; ++p) {
|
||||
if (p->_value != 0) {
|
||||
TRI_Free(shaper->_memoryZone, p->_value);
|
||||
|
@ -327,7 +327,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
total += p->_size;
|
||||
|
@ -358,7 +358,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
|
||||
shape = (TRI_homogeneous_sized_list_shape_t*) TRI_Allocate(shaper->_memoryZone, sizeof(TRI_homogeneous_sized_list_shape_t), true);
|
||||
|
||||
if (shape == NULL) {
|
||||
if (shape == 0) {
|
||||
for (p = values; p < e; ++p) {
|
||||
if (p->_value != 0) {
|
||||
TRI_Free(shaper->_memoryZone, p->_value);
|
||||
|
@ -366,8 +366,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
shape->base._size = sizeof(TRI_homogeneous_sized_list_shape_t);
|
||||
|
@ -376,7 +375,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
shape->_sidEntry = s;
|
||||
shape->_sizeEntry = l;
|
||||
|
||||
found = shaper->findShape(shaper, &shape->base);
|
||||
found = shaper->findShape(shaper, &shape->base, create, isLocked);
|
||||
|
||||
if (found == 0) {
|
||||
for (p = values; p < e; ++p) {
|
||||
|
@ -389,7 +388,12 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
TRI_Free(shaper->_memoryZone, shape);
|
||||
|
||||
LOG_TRACE("shaper failed to find shape of type %d", (int) shape->base._type);
|
||||
return false;
|
||||
|
||||
if (! create) {
|
||||
return TRI_RESULT_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
assert(found != 0);
|
||||
|
@ -410,7 +414,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// copy sub-objects into data space
|
||||
|
@ -438,7 +442,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
shape->base._size = sizeof(TRI_homogeneous_list_shape_t);
|
||||
|
@ -447,7 +451,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
shape->_sidEntry = s;
|
||||
|
||||
// if found returns non-NULL, it will free the shape!!
|
||||
found = shaper->findShape(shaper, &shape->base);
|
||||
found = shaper->findShape(shaper, &shape->base, create, isLocked);
|
||||
|
||||
if (found == 0) {
|
||||
for (p = values; p < e; ++p) {
|
||||
|
@ -460,7 +464,12 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
TRI_Free(shaper->_memoryZone, shape);
|
||||
return false;
|
||||
|
||||
if (! create) {
|
||||
return TRI_RESULT_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
assert(found != 0);
|
||||
|
@ -483,7 +492,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// copy sub-objects into data space
|
||||
|
@ -526,7 +535,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// copy sub-objects into data space
|
||||
|
@ -560,18 +569,20 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a json array into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Object> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects) {
|
||||
static int FillShapeValueArray (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Object> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
size_t i, n;
|
||||
size_t total;
|
||||
|
||||
|
@ -601,8 +612,8 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
// convert into TRI_shape_value_t array
|
||||
p = (values = (TRI_shape_value_t*) TRI_Allocate(shaper->_memoryZone, n * sizeof(TRI_shape_value_t), true));
|
||||
|
||||
if (p == NULL) {
|
||||
return false;
|
||||
if (p == 0) {
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
|
@ -612,7 +623,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
for (i = 0; i < n; ++i, ++p) {
|
||||
v8::Handle<v8::Value> key = names->Get(i);
|
||||
v8::Handle<v8::Value> val = json->Get(key);
|
||||
bool ok;
|
||||
int res;
|
||||
|
||||
// first find an identifier for the name
|
||||
TRI_Utf8ValueNFC keyStr(TRI_UNKNOWN_MEM_ZONE, key);
|
||||
|
@ -627,21 +638,27 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
continue;
|
||||
}
|
||||
|
||||
p->_aid = shaper->findAttributeByName(shaper, *keyStr, true);
|
||||
if (create) {
|
||||
p->_aid = shaper->findOrCreateAttributeByName(shaper, *keyStr, isLocked);
|
||||
}
|
||||
else {
|
||||
p->_aid = shaper->lookupAttributeByName(shaper, *keyStr);
|
||||
}
|
||||
|
||||
// convert value
|
||||
if (p->_aid == 0) {
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
ok = FillShapeValueJson(shaper, p, val, seenHashes, seenObjects);
|
||||
|
||||
if (! ok) {
|
||||
LOG_TRACE("failed to convert attribute '%s'", *keyStr);
|
||||
if (create) {
|
||||
res = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
else {
|
||||
res = TRI_RESULT_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
res = FillShapeValueJson(shaper, p, val, seenHashes, seenObjects, create, isLocked);
|
||||
}
|
||||
|
||||
if (! ok) {
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
for (e = p, p = values; p < e; ++p) {
|
||||
if (p->_value != 0) {
|
||||
TRI_Free(shaper->_memoryZone, p->_value);
|
||||
|
@ -649,7 +666,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
total += p->_size;
|
||||
|
@ -703,7 +720,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
|
||||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
a->base._type = TRI_SHAPE_ARRAY;
|
||||
|
@ -734,11 +751,11 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
dst->_size = total;
|
||||
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
|
||||
|
||||
if (ptr == NULL) {
|
||||
if (ptr == 0) {
|
||||
e = values + n;
|
||||
|
||||
for (p = values; p < e; ++p) {
|
||||
if (p->_value != NULL) {
|
||||
if (p->_value != 0) {
|
||||
TRI_Free(shaper->_memoryZone, p->_value);
|
||||
}
|
||||
}
|
||||
|
@ -746,7 +763,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
TRI_Free(shaper->_memoryZone, values);
|
||||
TRI_Free(shaper->_memoryZone, a);
|
||||
|
||||
return false;
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// array of offsets for variable part (within the value)
|
||||
|
@ -787,30 +804,35 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
|
|||
TRI_Free(shaper->_memoryZone, values);
|
||||
|
||||
// lookup this shape
|
||||
found = shaper->findShape(shaper, &a->base);
|
||||
found = shaper->findShape(shaper, &a->base, create, isLocked);
|
||||
|
||||
if (found == 0) {
|
||||
LOG_TRACE("shaper failed to find shape %d", (int) a->base._type);
|
||||
TRI_Free(shaper->_memoryZone, a);
|
||||
return false;
|
||||
|
||||
if (! create) {
|
||||
return TRI_RESULT_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// and finally add the sid
|
||||
dst->_sid = found->_sid;
|
||||
return true;
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a json object into TRI_shape_value_t
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool FillShapeValueJson (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Value> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects) {
|
||||
bool result = false;
|
||||
|
||||
static int FillShapeValueJson (TRI_shaper_t* shaper,
|
||||
TRI_shape_value_t* dst,
|
||||
v8::Handle<v8::Value> const& json,
|
||||
set<int>& seenHashes,
|
||||
vector< v8::Handle<v8::Object> >& seenObjects,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
// check for cycles
|
||||
if (json->IsObject()) {
|
||||
v8::Handle<v8::Object> o = json->ToObject();
|
||||
|
@ -822,7 +844,7 @@ static bool FillShapeValueJson (TRI_shaper_t* shaper,
|
|||
for (vector< v8::Handle<v8::Object> >::iterator i = seenObjects.begin(); i != seenObjects.end(); ++i) {
|
||||
if (json->StrictEquals(*i)) {
|
||||
LOG_TRACE("found duplicate for hash %d", hash);
|
||||
return false;
|
||||
return TRI_ERROR_ARANGO_SHAPER_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -834,68 +856,70 @@ static bool FillShapeValueJson (TRI_shaper_t* shaper,
|
|||
}
|
||||
|
||||
if (json->IsNull()) {
|
||||
result = FillShapeValueNull(shaper, dst);
|
||||
return FillShapeValueNull(shaper, dst);
|
||||
}
|
||||
|
||||
else if (json->IsBoolean()) {
|
||||
result = FillShapeValueBoolean(shaper, dst, json->ToBoolean());
|
||||
return FillShapeValueBoolean(shaper, dst, json->ToBoolean());
|
||||
}
|
||||
|
||||
else if (json->IsBooleanObject()) {
|
||||
result = FillShapeValueBoolean(shaper, dst, v8::Handle<v8::BooleanObject>::Cast(json));
|
||||
return FillShapeValueBoolean(shaper, dst, v8::Handle<v8::BooleanObject>::Cast(json));
|
||||
}
|
||||
|
||||
else if (json->IsNumber()) {
|
||||
result = FillShapeValueNumber(shaper, dst, json->ToNumber());
|
||||
return FillShapeValueNumber(shaper, dst, json->ToNumber());
|
||||
}
|
||||
|
||||
else if (json->IsNumberObject()) {
|
||||
result = FillShapeValueNumber(shaper, dst, v8::Handle<v8::NumberObject>::Cast(json));
|
||||
return FillShapeValueNumber(shaper, dst, v8::Handle<v8::NumberObject>::Cast(json));
|
||||
}
|
||||
|
||||
else if (json->IsString()) {
|
||||
result = FillShapeValueString(shaper, dst, json->ToString());
|
||||
return FillShapeValueString(shaper, dst, json->ToString());
|
||||
}
|
||||
|
||||
else if (json->IsStringObject()) {
|
||||
result = FillShapeValueString(shaper, dst, v8::Handle<v8::StringObject>::Cast(json)->StringValue());
|
||||
return FillShapeValueString(shaper, dst, v8::Handle<v8::StringObject>::Cast(json)->StringValue());
|
||||
}
|
||||
|
||||
else if (json->IsArray()) {
|
||||
result = FillShapeValueList(shaper, dst, v8::Handle<v8::Array>::Cast(json), seenHashes, seenObjects);
|
||||
return FillShapeValueList(shaper, dst, v8::Handle<v8::Array>::Cast(json), seenHashes, seenObjects, create, isLocked);
|
||||
}
|
||||
|
||||
else if (json->IsObject()) {
|
||||
result = FillShapeValueArray(shaper, dst, json->ToObject(), seenHashes, seenObjects);
|
||||
|
||||
else if (json->IsObject()) {
|
||||
int res = FillShapeValueArray(shaper, dst, json->ToObject(), seenHashes, seenObjects, create, isLocked);
|
||||
seenObjects.pop_back();
|
||||
return res;
|
||||
}
|
||||
|
||||
else if (json->IsRegExp()) {
|
||||
LOG_TRACE("shaper failed because a regexp cannot be converted");
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
else if (json->IsFunction()) {
|
||||
LOG_TRACE("shaper failed because a function cannot be converted");
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
else if (json->IsExternal()) {
|
||||
LOG_TRACE("shaper failed because an external cannot be converted");
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
else if (json->IsDate()) {
|
||||
LOG_TRACE("shaper failed because a date cannot be converted");
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
// treat undefined as null value
|
||||
else if (json->IsUndefined()) {
|
||||
result = FillShapeValueNull(shaper, dst);
|
||||
return FillShapeValueNull(shaper, dst);
|
||||
}
|
||||
|
||||
else {
|
||||
LOG_TRACE("shaper failed to convert object");
|
||||
}
|
||||
|
||||
return result;
|
||||
LOG_TRACE("shaper failed to convert object");
|
||||
return TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1430,14 +1454,22 @@ v8::Handle<v8::Value> TRI_JsonShapeData (TRI_shaper_t* shaper,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const& object,
|
||||
TRI_shaper_t* shaper) {
|
||||
TRI_shaper_t* shaper,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
TRI_shape_value_t dst;
|
||||
set<int> seenHashes;
|
||||
vector< v8::Handle<v8::Object> > seenObjects;
|
||||
bool ok = FillShapeValueJson(shaper, &dst, object, seenHashes, seenObjects);
|
||||
|
||||
if (! ok) {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
|
||||
int res = FillShapeValueJson(shaper, &dst, object, seenHashes, seenObjects, create, isLocked);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
if (res == TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
TRI_set_errno(res);
|
||||
}
|
||||
else {
|
||||
TRI_set_errno(TRI_ERROR_ARANGO_SHAPER_FAILED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1460,14 +1492,20 @@ TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const& object,
|
|||
|
||||
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const& object,
|
||||
TRI_shaped_json_t* result,
|
||||
TRI_shaper_t* shaper) {
|
||||
TRI_shaper_t* shaper,
|
||||
bool create,
|
||||
bool isLocked) {
|
||||
TRI_shape_value_t dst;
|
||||
set<int> seenHashes;
|
||||
vector< v8::Handle<v8::Object> > seenObjects;
|
||||
bool ok = FillShapeValueJson(shaper, &dst, object, seenHashes, seenObjects);
|
||||
|
||||
if (! ok) {
|
||||
return TRI_set_errno(TRI_ERROR_BAD_PARAMETER);
|
||||
int res = FillShapeValueJson(shaper, &dst, object, seenHashes, seenObjects, create, isLocked);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
if (res != TRI_RESULT_ELEMENT_NOT_FOUND) {
|
||||
res = TRI_ERROR_BAD_PARAMETER;
|
||||
}
|
||||
return TRI_set_errno(res);
|
||||
}
|
||||
|
||||
result->_sid = dst._sid;
|
||||
|
|
|
@ -67,15 +67,19 @@ v8::Handle<v8::Value> TRI_JsonShapeData (TRI_shaper_t*,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const&,
|
||||
TRI_shaper_t*);
|
||||
TRI_shaper_t*,
|
||||
bool,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief converts a V8 object to a TRI_shaped_json_t in place
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const& object,
|
||||
TRI_shaped_json_t* result,
|
||||
TRI_shaper_t*);
|
||||
int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const&,
|
||||
TRI_shaped_json_t*,
|
||||
TRI_shaper_t*,
|
||||
bool,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief convert a V8 value to a json_t value
|
||||
|
|
Loading…
Reference in New Issue