static char* ExtractStringShapedJson (TRI_shaper_t* shaper, TRI_shaped_json_t const* document, char const* path) { TRI_json_t* json; TRI_shape_pid_t pid; TRI_shape_t const* shape; TRI_shaped_json_t shaped; bool ok; char* result; pid = shaper->findAttributePathByName(shaper, path); ok = TRI_ExtractShapedJsonVocShaper(shaper, document, 0, pid, &shaped, &shape); if (! ok || shape == NULL) { return NULL; } json = TRI_JsonShapedJson(shaper, &shaped); if (json == NULL) { return NULL; } if (json->_type != TRI_JSON_STRING) { return NULL; } result = TRI_DuplicateString2(json->_value._string.data, json->_value._string.length); TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); return result; }
triagens::basics::Json DocumentAccessor::toJson () { if (_current == nullptr) { // we're still pointing to the original document auto shaper = _document->getShaper(); // fetch document from mptr TRI_shaped_json_t shaped; TRI_EXTRACT_SHAPED_JSON_MARKER(shaped, _mptr->getDataPtr()); triagens::basics::Json json(shaper->memoryZone(), TRI_JsonShapedJson(shaper, &shaped)); // add internal attributes // _id, _key, _rev char const* key = TRI_EXTRACT_MARKER_KEY(_mptr); std::string id(_resolver->getCollectionName(_document->_info._cid)); id.push_back('/'); id.append(key); json(TRI_VOC_ATTRIBUTE_ID, triagens::basics::Json(id)); json(TRI_VOC_ATTRIBUTE_REV, triagens::basics::Json(std::to_string(TRI_EXTRACT_MARKER_RID(_mptr)))); json(TRI_VOC_ATTRIBUTE_KEY, triagens::basics::Json(key)); if (TRI_IS_EDGE_MARKER(_mptr)) { // _from std::string from(_resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_FROM_CID(_mptr))); from.push_back('/'); from.append(TRI_EXTRACT_MARKER_FROM_KEY(_mptr)); json(TRI_VOC_ATTRIBUTE_FROM, triagens::basics::Json(from)); // _to std::string to(_resolver->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(_mptr))); to.push_back('/'); to.append(TRI_EXTRACT_MARKER_TO_KEY(_mptr)); json(TRI_VOC_ATTRIBUTE_TO, triagens::basics::Json(to)); } return json; } if (_current == _json.get()) { // _current points at the JSON that we own // steal the JSON TRI_json_t* value = _json.release(); setToNull(); return triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, value); } TRI_json_t* copy = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, _current); if (copy != nullptr) { _json.release(); return triagens::basics::Json(TRI_UNKNOWN_MEM_ZONE, copy); } // fall-through intentional return triagens::basics::Json(triagens::basics::Json::Null); }
static bool ExtractBooleanShapedJson (TRI_shaper_t* shaper, TRI_shaped_json_t const* document, char const* path, bool* found) { TRI_json_t* json; TRI_shape_pid_t pid; TRI_shape_t const* shape; TRI_shaped_json_t shaped; bool result; bool ok; if (found != NULL) { *found = false; } pid = shaper->findAttributePathByName(shaper, path); ok = TRI_ExtractShapedJsonVocShaper(shaper, document, 0, pid, &shaped, &shape); if (! ok || shape == NULL) { return false; } json = TRI_JsonShapedJson(shaper, &shaped); if (json == NULL) { return false; } if (json->_type != TRI_JSON_BOOLEAN) { return false; } if (found != NULL) { *found = true; } result = json->_value._boolean; TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); return result; }
void DocumentAccessor::lookupDocumentAttribute (char const* name, size_t nameLength) { if (*name == '_' && name[1] != '\0') { if (name[1] == 'k' && nameLength == 4 && memcmp(name, TRI_VOC_ATTRIBUTE_KEY, nameLength) == 0) { // _key value is copied into JSON char const* key = TRI_EXTRACT_MARKER_KEY(_mptr); if (key == nullptr) { setToNull(); return; } _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, key, strlen(key))); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (name[1] == 'i' && nameLength == 3 && memcmp(name, TRI_VOC_ATTRIBUTE_ID, nameLength) == 0) { // _id char buffer[512]; // big enough for max key length + max collection name length size_t pos = _resolver->getCollectionName(&buffer[0], _document->_info._cid); buffer[pos++] = '/'; char const* key = TRI_EXTRACT_MARKER_KEY(_mptr); if (key == nullptr) { setToNull(); return; } size_t len = strlen(key); memcpy(&buffer[pos], key, len); buffer[pos + len] = '\0'; _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (name[1] == 'r' && nameLength == 4 && memcmp(name, TRI_VOC_ATTRIBUTE_REV, nameLength) == 0) { // _rev char buffer[21]; TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(_mptr); size_t len = TRI_StringUInt64InPlace(rid, &buffer[0]); _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (TRI_IS_EDGE_MARKER(_mptr)) { if (name[1] == 'f' && nameLength == 5 && memcmp(name, TRI_VOC_ATTRIBUTE_FROM, nameLength) == 0) { // _from char buffer[512]; // big enough for max key length + max collection name length size_t pos = _resolver->getCollectionNameCluster(&buffer[0], TRI_EXTRACT_MARKER_FROM_CID(_mptr)); buffer[pos++] = '/'; char const* key = TRI_EXTRACT_MARKER_FROM_KEY(_mptr); if (key == nullptr) { setToNull(); return; } size_t len = strlen(key); memcpy(&buffer[pos], key, len); buffer[pos + len] = '\0'; _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } if (name[1] == 't' && nameLength == 3 && memcmp(name, TRI_VOC_ATTRIBUTE_TO, nameLength) == 0) { // to char buffer[512]; // big enough for max key length + max collection name length size_t pos = _resolver->getCollectionNameCluster(&buffer[0], TRI_EXTRACT_MARKER_TO_CID(_mptr)); buffer[pos++] = '/'; char const* key = TRI_EXTRACT_MARKER_TO_KEY(_mptr); if (key == nullptr) { setToNull(); return; } size_t len = strlen(key); memcpy(&buffer[pos], key, len); buffer[pos + len] = '\0'; _json.reset(TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, &buffer[0], pos + len)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } } // fall-through intentional } auto shaper = _document->getShaper(); TRI_shape_pid_t pid = shaper->lookupAttributePathByName(name); if (pid == 0) { // attribute does not exist setToNull(); return; } // attribute exists TRI_shaped_json_t document; TRI_EXTRACT_SHAPED_JSON_MARKER(document, _mptr->getDataPtr()); TRI_shaped_json_t json; TRI_shape_t const* shape; bool ok = shaper->extractShapedJson(&document, 0, pid, &json, &shape); if (ok && shape != nullptr) { _json.reset(TRI_JsonShapedJson(shaper, &json)); if (_json.get() == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } _current = _json.get(); return; } // not found setToNull(); }
int BitarrayIndex_generateInsertBitMask (BitarrayIndex* baIndex, const TRI_bitarray_index_key_t* element, TRI_bitarray_mask_t* mask) { TRI_shaper_t* shaper; int j; int shiftLeft; int result; // ........................................................................... // some safety checks first // ........................................................................... if (baIndex == NULL || element == NULL) { return TRI_ERROR_INTERNAL; } if (element->collection == NULL) { return TRI_ERROR_INTERNAL; } // ........................................................................... // We could be trying to store an 'undefined' document into the bitarray // We determine this implicitly. If element->numFields b == 0, then we // assume that the document did not have any matching attributes, yet since // we are here we wish to store this fact. // ........................................................................... if (!baIndex->_supportUndef && (element->numFields == 0 || element->fields == NULL)) { return TRI_ERROR_INTERNAL; } if (baIndex->_supportUndef && element->numFields == 0) { mask->_mask = 1; mask->_ignoreMask = 0; return TRI_ERROR_NO_ERROR; } // ........................................................................... // attempt to convert the stored TRI_shaped_json_t into TRI_Json_t so that // we can make a comparison between what values the bitarray index requires // and what values the document has sent. // ........................................................................... shaper = ((TRI_primary_collection_t*)(element->collection))->_shaper; mask->_mask = 0; shiftLeft = 0; for (j = 0; j < baIndex->_values._length; ++j) { TRI_json_t* valueList; TRI_json_t* value; uint64_t tempMask; value = TRI_JsonShapedJson(shaper, &(element->fields[j])); // from shaped json to simple json valueList = (TRI_json_t*)(TRI_AtVector(&(baIndex->_values),j)); tempMask = 0; // ......................................................................... // value is now the shaped json converted into plain json for comparison // ........................................................................ result = BitarrayIndex_generateEqualBitMaskHelper(valueList, value, &tempMask); // ............................................................................ // remove the json entry created from the shaped json // ............................................................................ TRI_FreeJson(shaper->_memoryZone, value); if (result != TRI_ERROR_NO_ERROR) { return result; } mask->_mask = mask->_mask | (tempMask << shiftLeft); shiftLeft += valueList->_value._objects._length; } return TRI_ERROR_NO_ERROR; }