1
0
Fork 0

reallow attribute names starting with underscores

This commit is contained in:
Jan Steemann 2014-08-07 15:52:58 +02:00
parent cb2e9a8a37
commit 099ec8db60
7 changed files with 199 additions and 157 deletions

View File

@ -220,14 +220,9 @@ ArangoDB:
- *_rev*: this attribute contains the revision number of a document. However, the
revision numbers are managed by ArangoDB and cannot be specified on import. Thus
any value in this attribute is ignored on import.
- all other attributes starting with an underscore are discarded on import without
any warnings.
If you import values into *_key*, you should make sure they are valid and unique.
When importing data into an edge collection, you should make sure that all import
documents can *_from* and *_to* and that their values point to existing documents.
Finally you should make sure that all other attributes in the import file do not
start with an underscore - otherwise they might be discarded.

View File

@ -15,8 +15,8 @@ following attribute naming constraints are not violated:
attributes are used to reference other documents.
More system attributes may be added in the future without further notice so
end users should not use attribute names starting with an underscore for their
own attributes.
end users should try to avoid using their own attribute names starting with
underscores.
* Attribute names should not start with the at-mark (*@*). The at-mark
at the start of attribute names is reserved in ArangoDB for future use cases.
@ -39,16 +39,15 @@ following attribute naming constraints are not violated:
length is variable and depends on the number and data types of attributes
used.
* Attribute names are case-sensitive.
* Attributes with empty names (the empty string) and attributes with names that
start with an underscore and don't have a special meaning (system attributes)
are removed from the document when saving it.
* Attributes with empty names (the empty string) are removed from the document
when saving it.
When the document is later requested, it will be returned without these
attributes. For example, if this document is saved:
{ "a" : 1, "" : 2, "_test" : 3, "b": 4 }
{ "a" : 1, "" : 2, "b": 3 }
and later requested, it will be returned like this:
{ "a" : 1, "b": 4 }
{ "a" : 1, "b": 3 }

View File

@ -89,7 +89,8 @@ describe ArangoDB do
doc.parsed_response['_rev'].should_not eq('99')
doc.parsed_response.should_not have_key('_from')
doc.parsed_response.should_not have_key('_to')
doc.parsed_response.should_not have_key('_test')
doc.parsed_response.should have_key('_test')
doc.parsed_response['_test'].should eq('c')
doc.parsed_response.should have_key('meow')
doc.parsed_response['meow'].should eq('d')
doc.parsed_response['foo'].should eq('002')
@ -101,7 +102,7 @@ describe ArangoDB do
it "creates a document with nested attribute names" do
cmd = api + "?collection=" + @cn
body = "{ \"a\" : \"1\", \"b\" : { \"b\" : \"2\" , \"a\" : \"3\", \"\": \"4\", \"_from\": \"5\", \"c\" : 6 } }"
body = "{ \"a\" : \"1\", \"b\" : { \"b\" : \"2\" , \"a\" : \"3\", \"\": \"4\", \"_key\": \"moetoer\", \"_from\": \"5\", \"_lol\" : false, \"c\" : 6 } }"
doc = ArangoDB.log_post("#{prefix}-create-duplicate-names", cmd, :body => body)
doc.code.should eq(201)
@ -118,11 +119,13 @@ describe ArangoDB do
doc.parsed_response.should have_key('b')
doc.parsed_response['b'].should_not have_key('')
doc.parsed_response['b'].should_not have_key('_from')
doc.parsed_response['b'].should have_key('_from')
doc.parsed_response['b'].should have_key('_key')
doc.parsed_response['b'].should have_key('_lol')
doc.parsed_response['b'].should have_key('b')
doc.parsed_response['b'].should have_key('a')
doc.parsed_response['b'].should have_key('c')
doc.parsed_response['b'].should eq({ "b" => "2", "a" => "3", "c" => 6 })
doc.parsed_response['b'].should eq({ "b" => "2", "a" => "3", "_key" => "moetoer", "_from" => "5", "_lol" => false, "c" => 6 })
end
################################################################################

View File

@ -933,7 +933,7 @@ int ProcessBitarrayIndexFields (v8::Handle<v8::Object> const obj,
// "fields" is a list of fields
v8::Handle<v8::Array> fieldList = v8::Handle<v8::Array>::Cast(obj->Get(TRI_V8_SYMBOL("fields")));
const uint32_t n = fieldList->Length();
uint32_t const n = fieldList->Length();
for (uint32_t i = 0; i < n; ++i) {
if (! fieldList->Get(i)->IsArray()) {
@ -948,7 +948,7 @@ int ProcessBitarrayIndexFields (v8::Handle<v8::Object> const obj,
break;
}
const string f = TRI_ObjectToString(fieldPair->Get(0));
string const f = TRI_ObjectToString(fieldPair->Get(0));
if (f.empty() || (create && f[0] == '_')) {
// accessing internal attributes is disallowed
@ -9903,7 +9903,17 @@ static v8::Handle<v8::Value> MapGetNamedShapedJson (v8::Local<v8::String> name,
v8::String::Utf8Value const str(name);
string const key(*str, (size_t) str.length());
if (key.empty() || key[0] == '_' || strchr(key.c_str(), '.') != 0) {
if (key.empty()) {
return scope.Close(v8::Handle<v8::Value>());
}
if (key[0] == '_' &&
(key == "_key" || key == "_rev" || key == "_id" || key == "_from" || key == "_to")) {
// strip reserved attributes
return scope.Close(v8::Handle<v8::Value>());
}
if (strchr(key.c_str(), '.') != nullptr) {
return scope.Close(v8::Handle<v8::Value>());
}
@ -9954,7 +9964,7 @@ static v8::Handle<v8::Array> KeysOfShapedJson (const v8::AccessorInfo& info) {
// get shaped json
void* marker = TRI_UnwrapClass<void*>(self, WRP_SHAPED_JSON_TYPE);
if (marker == 0) {
if (marker == nullptr) {
return scope.Close(v8::Array::New());
}
@ -10000,7 +10010,7 @@ static v8::Handle<v8::Array> KeysOfShapedJson (const v8::AccessorInfo& info) {
}
}
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
result->Set(count++, v8g->_IdKey);
result->Set(count++, v8g->_RevKey);
result->Set(count++, v8g->_KeyKey);
@ -10038,7 +10048,7 @@ static v8::Handle<v8::Integer> PropertyQueryShapedJson (v8::Local<v8::String> na
}
if (key[0] == '_') {
if (key == "_id" || key == TRI_VOC_ATTRIBUTE_REV || key == TRI_VOC_ATTRIBUTE_KEY) {
if (key == "_key" || key == "_rev" || key == "_id" || key == "_from" || key == "_to") {
return scope.Close(v8::Handle<v8::Integer>(v8::Integer::New(v8::ReadOnly)));
}
}
@ -10069,7 +10079,7 @@ static v8::Handle<v8::Integer> PropertyQueryShapedJson (v8::Local<v8::String> na
TRI_shape_access_t const* acc = TRI_FindAccessorVocShaper(shaper, sid, pid);
// key not found
if (acc == 0 || acc->_resultSid == TRI_SHAPE_ILLEGAL) {
if (acc == nullptr || acc->_resultSid == TRI_SHAPE_ILLEGAL) {
return scope.Close(v8::Handle<v8::Integer>());
}
@ -10172,7 +10182,7 @@ TRI_index_t* TRI_LookupIndexByHandle (CollectionNameResolver const* resolver,
// extract the index identifier from an object
else if (val->IsObject()) {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
v8::Handle<v8::Object> obj = val->ToObject();
v8::Handle<v8::Value> iidVal = obj->Get(v8g->IdKey);

View File

@ -151,7 +151,7 @@ function AttributesSuite () {
////////////////////////////////////////////////////////////////////////////////
testReservedAttributes : function () {
var doc = { "_id" : "foo", "_rev": "99", "_key" : "meow", "_from" : "33", "_to": "99", "_test" : false };
var doc = { "_id" : "foo", "_rev": "99", "_key" : "meow", "_from" : "33", "_to": "99", "_test" : false, "_boom" : "bang" };
var d1 = c.save(doc);
var d2 = c.document(d1._id);
@ -161,17 +161,33 @@ function AttributesSuite () {
assertEqual(cn + "/meow", d1._id);
assertEqual(cn + "/meow", d2._id);
assertEqual(d1._rev, d2._rev);
assertFalse(d2._test);
assertEqual("bang", d2._boom);
assertFalse(d2.hasOwnProperty("_from"));
assertFalse(d2.hasOwnProperty("_to"));
// user specified _rev value must have been ignored
assertTrue(d1._rev !== "99");
},
// test attributes
var i;
for (i in d2) {
if (d2.hasOwnProperty(i)) {
assertTrue(i !== "_from" && i !== "_to" && i !== "_test");
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief reserved attribute names
////////////////////////////////////////////////////////////////////////////////
testEmbeddedReservedAttributes : function () {
var doc = { "_id" : "foo", "_rev": "99", "_key" : "meow", "_from" : "33", "_to": "99", "_test" : false };
c.save({ _key: "mydoc", _embedded: doc });
var d = c.document("mydoc");
assertEqual(cn + "/mydoc", d._id);
assertEqual("mydoc", d._key);
assertEqual("foo", d._embedded._id);
assertEqual("99", d._embedded._rev);
assertEqual("meow", d._embedded._key);
assertEqual("33", d._embedded._from);
assertEqual("99", d._embedded._to);
assertFalse(d._embedded._test);
},
////////////////////////////////////////////////////////////////////////////////

View File

@ -44,7 +44,7 @@
// --SECTION-- forward declarations
// -----------------------------------------------------------------------------
static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json, bool, bool);
static bool FillShapeValueJson (TRI_shaper_t* shaper, TRI_shape_value_t* dst, TRI_json_t const* json, size_t, 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);
@ -470,6 +470,7 @@ static bool FillShapeValueString (TRI_shaper_t* shaper, TRI_shape_value_t* dst,
static bool FillShapeValueList (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
TRI_json_t const* json,
size_t level,
bool create,
bool isLocked) {
size_t i, n;
@ -506,7 +507,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
dst->_size = sizeof(TRI_shape_length_list_t);
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
if (dst->_value == NULL) {
if (dst->_value == nullptr) {
return false;
}
@ -518,7 +519,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
// convert into TRI_shape_value_t array
p = (values = static_cast<TRI_shape_value_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_value_t) * n, true)));
if (p == NULL) {
if (p == nullptr) {
return false;
}
@ -526,12 +527,12 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
e = values + n;
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, create, isLocked);
TRI_json_t const* el = static_cast<TRI_json_t const*>(TRI_AtVector(&json->_value._objects, i));
bool ok = FillShapeValueJson(shaper, p, el, level + 1, create, isLocked);
if (! ok) {
for (e = p, p = values; p < e; ++p) {
if (p->_value != NULL) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -774,6 +775,7 @@ static bool FillShapeValueList (TRI_shaper_t* shaper,
static bool FillShapeValueArray (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
TRI_json_t const* json,
size_t level,
bool create,
bool isLocked) {
size_t i, n;
@ -808,7 +810,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
// convert into TRI_shape_value_t array
p = (values = static_cast<TRI_shape_value_t*>(TRI_Allocate(shaper->_memoryZone, n * sizeof(TRI_shape_value_t), true)));
if (p == NULL) {
if (p == nullptr) {
return false;
}
@ -817,36 +819,49 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
v = 0;
for (i = 0; i < n; ++i, ++p) {
bool ok;
TRI_json_t const* key = static_cast<TRI_json_t const*>(TRI_AtVector(&json->_value._objects, 2 * i));
TRI_ASSERT(key != nullptr);
TRI_json_t* key = static_cast<TRI_json_t*>(TRI_AtVector(&json->_value._objects, 2 * i));
TRI_json_t* val = static_cast<TRI_json_t*>(TRI_AtVector(&json->_value._objects, 2 * i + 1));
char const* k = key->_value._string.data;
TRI_ASSERT(key != NULL);
TRI_ASSERT(val != NULL);
if (key->_value._string.data == NULL ||
key->_value._string.length == 1 ||
key->_value._string.data[0] == '_') {
// empty or reserved attribute name
if (k == nullptr ||
key->_value._string.length == 1) {
// empty attribute name
p--;
continue;
}
if (*k == '_' && level == 0) {
// on top level, strip reserved attributes before shaping
if (strcmp(k, "_key") == 0 ||
strcmp(k, "_rev") == 0 ||
strcmp(k, "_id") == 0 ||
strcmp(k, "_from") == 0 ||
strcmp(k, "_to") == 0) {
// found a reserved attribute - discard it
--p;
continue;
}
}
// first find an identifier for the name
p->_aid = shaper->findOrCreateAttributeByName(shaper, key->_value._string.data);
p->_aid = shaper->findOrCreateAttributeByName(shaper, k);
// convert value
bool ok;
if (p->_aid == 0) {
ok = false;
}
else {
ok = FillShapeValueJson(shaper, p, val, create, isLocked);
TRI_json_t const* val = static_cast<TRI_json_t const*>(TRI_AtVector(&json->_value._objects, 2 * i + 1));
TRI_ASSERT(val != nullptr);
ok = FillShapeValueJson(shaper, p, val, level + 1, create, isLocked);
}
if (! ok) {
for (e = p, p = values; p < e; ++p) {
if (p->_value != NULL) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -893,13 +908,13 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
+ n * sizeof(TRI_shape_aid_t)
+ (f + 1) * sizeof(TRI_shape_size_t);
a = (TRI_array_shape_t*) (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, i, true)));
a = reinterpret_cast<TRI_array_shape_t*>(ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, i, true)));
if (ptr == NULL) {
if (ptr == nullptr) {
e = values + n;
for (p = values; p < e; ++p) {
if (p->_value != NULL) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -937,11 +952,11 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
dst->_size = total;
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, true)));
if (ptr == NULL) {
if (ptr == nullptr) {
e = values + n;
for (p = values; p < e; ++p) {
if (p->_value != NULL) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -982,7 +997,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
// free TRI_shape_value_t array
for (p = values; p < e; ++p) {
if (p->_value != NULL) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -992,7 +1007,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
// lookup this shape
found = shaper->findShape(shaper, &a->base, create);
if (found == NULL) {
if (found == nullptr) {
TRI_Free(shaper->_memoryZone, a);
return false;
}
@ -1009,6 +1024,7 @@ static bool FillShapeValueArray (TRI_shaper_t* shaper,
static bool FillShapeValueJson (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
TRI_json_t const* json,
size_t level,
bool create,
bool isLocked) {
switch (json->_type) {
@ -1029,10 +1045,10 @@ static bool FillShapeValueJson (TRI_shaper_t* shaper,
return FillShapeValueString(shaper, dst, json);
case TRI_JSON_ARRAY:
return FillShapeValueArray(shaper, dst, json, create, isLocked);
return FillShapeValueArray(shaper, dst, json, level, create, isLocked);
case TRI_JSON_LIST:
return FillShapeValueList(shaper, dst, json, create, isLocked);
return FillShapeValueList(shaper, dst, json, level, create, isLocked);
}
return false;
@ -1143,8 +1159,8 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
// create an array with the appropriate size
array = TRI_CreateArray2Json(shaper->_memoryZone, (size_t) n);
if (array == NULL) {
return NULL;
if (array == nullptr) {
return nullptr;
}
qtr = (char const*) shape;
@ -1159,7 +1175,7 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
offsetsF = (TRI_shape_size_t const*) qtr;
shapeCache._sid = 0;
shapeCache._shape = NULL;
shapeCache._shape = nullptr;
for (i = 0; i < f; ++i, ++sids, ++aids, ++offsetsF) {
TRI_shape_sid_t sid = *sids;
@ -1180,21 +1196,21 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
shapeCache._sid = sid;
}
if (subshape == NULL) {
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
continue;
}
name = shaper->lookupAttributeId(shaper, aid);
if (name == NULL) {
if (name == nullptr) {
LOG_WARNING("cannot find attribute #%u", (unsigned int) aid);
continue;
}
element = JsonShapeData(shaper, subshape, data + offset, offsetsF[1] - offset);
if (element == NULL) {
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
}
@ -1224,21 +1240,21 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
shapeCache._sid = sid;
}
if (subshape == NULL) {
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
continue;
}
name = shaper->lookupAttributeId(shaper, aid);
if (name == NULL) {
if (name == nullptr) {
LOG_WARNING("cannot find attribute #%u", (unsigned int) aid);
continue;
}
element = JsonShapeData(shaper, subshape, data + offset, offsetsV[1] - offset);
if (element == NULL) {
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
}
@ -1250,7 +1266,7 @@ static TRI_json_t* JsonShapeDataArray (TRI_shaper_t* shaper,
if (shaper->_memoryZone->_failed) {
TRI_FreeJson(shaper->_memoryZone, array);
return NULL;
return nullptr;
}
return array;
@ -1265,7 +1281,6 @@ static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
char const* data,
uint64_t size) {
char const* ptr;
TRI_json_t* list;
TRI_shape_sid_t const* sids;
TRI_shape_size_t const* offsets;
TRI_shape_length_list_t l;
@ -1276,10 +1291,10 @@ static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
l = * (TRI_shape_length_list_t const*) ptr;
// create a list with the appropriate size
list = TRI_CreateList2Json(shaper->_memoryZone, (size_t) l);
TRI_json_t* list = TRI_CreateList2Json(shaper->_memoryZone, (size_t) l);
if (list == NULL) {
return NULL;
if (list == nullptr) {
return nullptr;
}
ptr += sizeof(TRI_shape_length_list_t);
@ -1289,7 +1304,7 @@ static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
offsets = (TRI_shape_size_t const*) ptr;
shapeCache._sid = 0;
shapeCache._shape = NULL;
shapeCache._shape = nullptr;
for (i = 0; i < l; ++i, ++sids, ++offsets) {
TRI_shape_sid_t sid = *sids;
@ -1308,14 +1323,14 @@ static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
shapeCache._sid = sid;
}
if (subshape == NULL) {
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
continue;
}
element = JsonShapeData(shaper, subshape, data + offset, offsets[1] - offset);
if (element == NULL) {
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
}
@ -1327,7 +1342,7 @@ static TRI_json_t* JsonShapeDataList (TRI_shaper_t* shaper,
if (shaper->_memoryZone->_failed) {
TRI_FreeJson(shaper->_memoryZone, list);
return NULL;
return nullptr;
}
return list;
@ -1342,33 +1357,31 @@ static TRI_json_t* JsonShapeDataHomogeneousList (TRI_shaper_t* shaper,
char const* data,
uint64_t size) {
TRI_homogeneous_list_shape_t const* s;
TRI_json_t* list;
TRI_shape_length_list_t i;
TRI_shape_length_list_t l;
TRI_shape_sid_t sid;
TRI_shape_size_t const* offsets;
TRI_shape_t const* subshape;
char const* ptr;
s = (TRI_homogeneous_list_shape_t const*) shape;
sid = s->_sidEntry;
subshape = shaper->lookupShapeId(shaper, sid);
TRI_shape_t const* subshape = shaper->lookupShapeId(shaper, sid);
if (subshape == NULL) {
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
return NULL;
return nullptr;
}
ptr = data;
l = * (TRI_shape_length_list_t const*) ptr;
// create a list with the appropriate size
list = TRI_CreateList2Json(shaper->_memoryZone, (size_t) l);
TRI_json_t* list = TRI_CreateList2Json(shaper->_memoryZone, (size_t) l);
if (list == NULL) {
return NULL;
if (list == nullptr) {
return nullptr;
}
ptr += sizeof(TRI_shape_length_list_t);
@ -1382,7 +1395,7 @@ static TRI_json_t* JsonShapeDataHomogeneousList (TRI_shaper_t* shaper,
element = JsonShapeData(shaper, subshape, data + offset, offsets[1] - offset);
if (element == NULL) {
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
}
@ -1394,7 +1407,7 @@ static TRI_json_t* JsonShapeDataHomogeneousList (TRI_shaper_t* shaper,
if (shaper->_memoryZone->_failed) {
TRI_FreeJson(shaper->_memoryZone, list);
return NULL;
return nullptr;
}
return list;
@ -1409,34 +1422,32 @@ static TRI_json_t* JsonShapeDataHomogeneousSizedList (TRI_shaper_t* shaper,
char const* data,
uint64_t size) {
TRI_homogeneous_sized_list_shape_t const* s;
TRI_json_t* list;
TRI_shape_length_list_t i;
TRI_shape_length_list_t l;
TRI_shape_sid_t sid;
TRI_shape_size_t length;
TRI_shape_size_t offset;
TRI_shape_t const* subshape;
char const* ptr;
s = (TRI_homogeneous_sized_list_shape_t const*) shape;
sid = s->_sidEntry;
subshape = shaper->lookupShapeId(shaper, sid);
TRI_shape_t const* subshape = shaper->lookupShapeId(shaper, sid);
if (subshape == NULL) {
if (subshape == nullptr) {
LOG_WARNING("cannot find shape #%u", (unsigned int) sid);
return NULL;
return nullptr;
}
ptr = data;
l = * (TRI_shape_length_list_t const*) ptr;
// create a list with the appropriate size
list = TRI_CreateList2Json(shaper->_memoryZone, (size_t) l);
TRI_json_t* list = TRI_CreateList2Json(shaper->_memoryZone, (size_t) l);
if (list == NULL) {
return NULL;
if (list == nullptr) {
return nullptr;
}
length = s->_sizeEntry;
@ -1447,7 +1458,7 @@ static TRI_json_t* JsonShapeDataHomogeneousSizedList (TRI_shaper_t* shaper,
element = JsonShapeData(shaper, subshape, data + offset, length);
if (element == NULL) {
if (element == nullptr) {
LOG_WARNING("cannot decode element for shape #%u", (unsigned int) sid);
continue;
}
@ -1467,8 +1478,8 @@ static TRI_json_t* JsonShapeData (TRI_shaper_t* shaper,
TRI_shape_t const* shape,
char const* data,
uint64_t size) {
if (shape == NULL) {
return NULL;
if (shape == nullptr) {
return nullptr;
}
switch (shape->_type) {
@ -2226,13 +2237,12 @@ TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
bool create,
bool isLocked) {
TRI_shape_value_t dst;
bool ok;
dst._value = 0;
ok = FillShapeValueJson(shaper, &dst, json, create, isLocked);
bool ok = FillShapeValueJson(shaper, &dst, json, 0, create, isLocked);
if (! ok) {
return NULL;
return nullptr;
}
#ifdef DEBUG_JSON_SHAPER
@ -2244,9 +2254,9 @@ TRI_shaped_json_t* TRI_ShapedJsonJson (TRI_shaper_t* shaper,
// no need to prefill shaped with 0's as all attributes are set directly afterwards
TRI_shaped_json_t* shaped = static_cast<TRI_shaped_json_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shaped_json_t), false));
if (shaped == NULL) {
if (shaped == nullptr) {
TRI_Free(shaper->_memoryZone, dst._value);
return NULL;
return nullptr;
}
shaped->_sid = dst._sid;

View File

@ -51,6 +51,7 @@ using namespace triagens::basics;
static int FillShapeValueJson (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Value> const json,
size_t level,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create);
@ -261,6 +262,7 @@ static int FillShapeValueString (TRI_shaper_t* shaper,
static int FillShapeValueList (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Array> const json,
size_t level,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create) {
@ -292,9 +294,9 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
dst->_fixedSized = false;
dst->_size = sizeof(TRI_shape_length_list_t);
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
if (dst->_value == 0) {
if (dst->_value == nullptr) {
return TRI_ERROR_OUT_OF_MEMORY;
}
@ -304,9 +306,9 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
}
// convert into TRI_shape_value_t array
p = (values = (TRI_shape_value_t*) TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_value_t) * n, true));
p = (values = static_cast<TRI_shape_value_t*>(TRI_Allocate(shaper->_memoryZone, sizeof(TRI_shape_value_t) * n, true)));
if (p == 0) {
if (p == nullptr) {
return TRI_ERROR_OUT_OF_MEMORY;
}
@ -315,11 +317,11 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
for (uint32_t i = 0; i < n; ++i, ++p) {
v8::Handle<v8::Value> el = json->Get(i);
int res = FillShapeValueJson(shaper, p, el, seenHashes, seenObjects, create);
int res = FillShapeValueJson(shaper, p, el, level + 1, seenHashes, seenObjects, create);
if (res != TRI_ERROR_NO_ERROR) {
for (e = p, p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -356,9 +358,9 @@ static int 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 == 0) {
if (shape == nullptr) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -375,9 +377,9 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
found = shaper->findShape(shaper, &shape->base, create);
if (found == 0) {
if (found == nullptr) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -394,18 +396,18 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
return TRI_ERROR_INTERNAL;
}
TRI_ASSERT(found != 0);
TRI_ASSERT(found != nullptr);
dst->_type = found->_type;
dst->_sid = found->_sid;
dst->_fixedSized = false;
dst->_size = sizeof(TRI_shape_length_list_t) + total;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, false));
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, false)));
if (dst->_value == NULL) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -431,9 +433,9 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
shape = (TRI_homogeneous_list_shape_t*) TRI_Allocate(shaper->_memoryZone, sizeof(TRI_homogeneous_list_shape_t), true);
if (shape == NULL) {
if (shape == nullptr) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -451,9 +453,9 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
// if found returns non-NULL, it will free the shape!!
found = shaper->findShape(shaper, &shape->base, create);
if (found == 0) {
if (found == nullptr) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -470,7 +472,7 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
return TRI_ERROR_INTERNAL;
}
TRI_ASSERT(found != 0);
TRI_ASSERT(found != nullptr);
dst->_type = found->_type;
dst->_sid = found->_sid;
@ -479,11 +481,11 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
dst->_fixedSized = false;
dst->_size = offset + total;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, true)));
if (dst->_value == 0) {
if (dst->_value == nullptr) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -525,9 +527,9 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
dst->_size = offset + total;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
if (dst->_value == NULL) {
if (dst->_value == nullptr) {
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -561,7 +563,7 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
// free TRI_shape_value_t array
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -577,14 +579,10 @@ static int FillShapeValueList (TRI_shaper_t* shaper,
static int FillShapeValueArray (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Object> const json,
size_t level,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create) {
size_t total;
size_t f;
size_t v;
TRI_shape_value_t* values;
TRI_shape_value_t* p;
TRI_shape_value_t* e;
@ -606,19 +604,19 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
uint32_t n = names->Length();
// convert into TRI_shape_value_t array
p = (values = (TRI_shape_value_t*) TRI_Allocate(shaper->_memoryZone, n * sizeof(TRI_shape_value_t), true));
p = (values = static_cast<TRI_shape_value_t*>(TRI_Allocate(shaper->_memoryZone, n * sizeof(TRI_shape_value_t), true)));
if (p == 0) {
if (p == nullptr) {
return TRI_ERROR_OUT_OF_MEMORY;
}
total = 0;
f = 0;
v = 0;
size_t total = 0;
size_t f = 0;
size_t v = 0;
for (uint32_t i = 0; i < n; ++i, ++p) {
v8::Handle<v8::Value> key = names->Get(i);
v8::Handle<v8::Value> val = json->Get(key);
// first find an identifier for the name
TRI_Utf8ValueNFC keyStr(TRI_UNKNOWN_MEM_ZONE, key);
@ -628,9 +626,18 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
continue;
}
if ((*keyStr)[0] == '_') {
--p;
continue;
if ((*keyStr)[0] == '_' && level == 0) {
// on top level, strip reserved attributes before shaping
char const* k = (*keyStr);
if (strcmp(k, "_key") == 0 ||
strcmp(k, "_rev") == 0 ||
strcmp(k, "_id") == 0 ||
strcmp(k, "_from") == 0 ||
strcmp(k, "_to") == 0) {
// found a reserved attribute - discard it
--p;
continue;
}
}
if (create) {
@ -652,12 +659,13 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
}
}
else {
res = FillShapeValueJson(shaper, p, val, seenHashes, seenObjects, create);
v8::Handle<v8::Value> val = json->Get(key);
res = FillShapeValueJson(shaper, p, val, level + 1, seenHashes, seenObjects, create);
}
if (res != TRI_ERROR_NO_ERROR) {
for (e = p, p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -706,11 +714,11 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
a = (TRI_array_shape_t*) (ptr = (char*) TRI_Allocate(shaper->_memoryZone, totalSize, true));
if (ptr == NULL) {
if (ptr == nullptr) {
e = values + n;
for (p = values; p < e; ++p) {
if (p->_value != NULL) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -746,13 +754,13 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
dst->_fixedSized = true;
dst->_size = total;
dst->_value = (ptr = (char*) TRI_Allocate(shaper->_memoryZone, dst->_size, true));
dst->_value = (ptr = static_cast<char*>(TRI_Allocate(shaper->_memoryZone, dst->_size, true)));
if (ptr == 0) {
if (ptr == nullptr) {
e = values + n;
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -793,7 +801,7 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
// free TRI_shape_value_t array
for (p = values; p < e; ++p) {
if (p->_value != 0) {
if (p->_value != nullptr) {
TRI_Free(shaper->_memoryZone, p->_value);
}
}
@ -803,7 +811,7 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
// lookup this shape
found = shaper->findShape(shaper, &a->base, create);
if (found == 0) {
if (found == nullptr) {
LOG_TRACE("shaper failed to find shape %d", (int) a->base._type);
TRI_Free(shaper->_memoryZone, a);
@ -826,6 +834,7 @@ static int FillShapeValueArray (TRI_shaper_t* shaper,
static int FillShapeValueJson (TRI_shaper_t* shaper,
TRI_shape_value_t* dst,
v8::Handle<v8::Value> const json,
size_t level,
set<int>& seenHashes,
vector< v8::Handle<v8::Object> >& seenObjects,
bool create) {
@ -885,11 +894,11 @@ static int FillShapeValueJson (TRI_shaper_t* shaper,
}
else if (json->IsArray()) {
return FillShapeValueList(shaper, dst, v8::Handle<v8::Array>::Cast(json), seenHashes, seenObjects, create);
return FillShapeValueList(shaper, dst, v8::Handle<v8::Array>::Cast(json), level, seenHashes, seenObjects, create);
}
else if (json->IsObject()) {
int res = FillShapeValueArray(shaper, dst, json->ToObject(), seenHashes, seenObjects, create);
int res = FillShapeValueArray(shaper, dst, json->ToObject(), level, seenHashes, seenObjects, create);
seenObjects.pop_back();
return res;
}
@ -1436,7 +1445,7 @@ TRI_shaped_json_t* TRI_ShapedJsonV8Object (v8::Handle<v8::Value> const object,
set<int> seenHashes;
vector< v8::Handle<v8::Object> > seenObjects;
int res = FillShapeValueJson(shaper, &dst, object, seenHashes, seenObjects, create);
int res = FillShapeValueJson(shaper, &dst, object, 0, seenHashes, seenObjects, create);
if (res != TRI_ERROR_NO_ERROR) {
if (res == TRI_RESULT_ELEMENT_NOT_FOUND) {
@ -1473,7 +1482,7 @@ int TRI_FillShapedJsonV8Object (v8::Handle<v8::Value> const object,
set<int> seenHashes;
vector< v8::Handle<v8::Object> > seenObjects;
int res = FillShapeValueJson(shaper, &dst, object, seenHashes, seenObjects, create);
int res = FillShapeValueJson(shaper, &dst, object, 0, seenHashes, seenObjects, create);
if (res != TRI_ERROR_NO_ERROR) {
if (res != TRI_RESULT_ELEMENT_NOT_FOUND) {