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 int RemoveGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, bool isRollback) { GeoCoordinate gc; TRI_shaped_json_t shapedJson; TRI_geo_index_t* geo; TRI_shaper_t* shaper; bool missing; bool ok; double latitude; double longitude; geo = (TRI_geo_index_t*) idx; shaper = geo->base._collection->getShaper(); // ONLY IN INDEX, PROTECTED by RUNTIME TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, doc->getDataPtr()); // ONLY IN INDEX, PROTECTED by RUNTIME // lookup OLD latitude and longitude if (geo->_location != 0) { ok = ExtractDoubleList(shaper, &shapedJson, geo->_location, &latitude, &longitude, &missing); } else { ok = ExtractDoubleArray(shaper, &shapedJson, geo->_latitude, &latitude, &missing); ok = ok && ExtractDoubleArray(shaper, &shapedJson, geo->_longitude, &longitude, &missing); } // and remove old entry if (ok) { gc.latitude = latitude; gc.longitude = longitude; gc.data = CONST_CAST(doc); // ignore non-existing elements in geo-index GeoIndex_remove(geo->_geoIndex, &gc); } return TRI_ERROR_NO_ERROR; }
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(); }
static int HashIndexHelper (TRI_hash_index_t const* hashIndex, TRI_hash_index_element_t* hashElement, TRI_doc_mptr_t const* document) { int res; size_t j; TRI_shaper_t* shaper; // underlying shaper TRI_shape_access_t const* acc; // shape accessor TRI_shaped_json_t shapedObject; // the sub-object TRI_shaped_json_t shapedJson; // the object behind document TRI_shaped_sub_t shapedSub; // the relative sub-object shaper = hashIndex->base._collection->_shaper; // ............................................................................. // Assign the document to the TRI_hash_index_element_t structure - so that it // can later be retreived. // ............................................................................. TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, document->_data); hashElement->_document = CONST_CAST(document); // ............................................................................. // Extract the attribute values // ............................................................................. res = TRI_ERROR_NO_ERROR; for (j = 0; j < hashIndex->_paths._length; ++j) { TRI_shape_pid_t path = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths, j))); // determine if document has that particular shape acc = TRI_FindAccessorVocShaper(shaper, shapedJson._sid, path); // field not part of the object if (acc == NULL || acc->_shape == NULL) { shapedSub._sid = shaper->_sidNull; shapedSub._length = 0; shapedSub._offset = 0; res = TRI_WARNING_ARANGO_INDEX_HASH_DOCUMENT_ATTRIBUTE_MISSING; } // extract the field else { if (! TRI_ExecuteShapeAccessor(acc, &shapedJson, &shapedObject)) { // hashElement->fields: memory deallocated in the calling procedure return TRI_ERROR_INTERNAL; } if (shapedObject._sid == shaper->_sidNull) { res = TRI_WARNING_ARANGO_INDEX_HASH_DOCUMENT_ATTRIBUTE_MISSING; } shapedSub._sid = shapedObject._sid; shapedSub._length = shapedObject._data.length; shapedSub._offset = ((char const*) shapedObject._data.data) - ((char const*) document->_data); } // store the json shaped sub-object -- this is what will be hashed hashElement->_subObjects[j] = shapedSub; } return res; }
bool TRI_LoadAuthInfo (TRI_vocbase_t* vocbase) { TRI_vocbase_col_t* collection; TRI_primary_collection_t* primary; void** beg; void** end; void** ptr; LOG_DEBUG("starting to load authentication and authorisation information"); collection = TRI_LookupCollectionByNameVocBase(vocbase, "_users"); if (collection == NULL) { LOG_INFO("collection '_users' does not exist, no authentication available"); return false; } TRI_UseCollectionVocBase(vocbase, collection); primary = collection->_collection; if (primary == NULL) { LOG_FATAL_AND_EXIT("collection '_users' cannot be loaded"); } if (! TRI_IS_DOCUMENT_COLLECTION(primary->base._info._type)) { TRI_ReleaseCollectionVocBase(vocbase, collection); LOG_FATAL_AND_EXIT("collection '_users' has an unknown collection type"); } TRI_WriteLockReadWriteLock(&vocbase->_authInfoLock); // ............................................................................. // inside a write transaction // ............................................................................. collection->_collection->beginWrite(collection->_collection); beg = primary->_primaryIndex._table; end = beg + primary->_primaryIndex._nrAlloc; ptr = beg; for (; ptr < end; ++ptr) { if (*ptr) { TRI_doc_mptr_t const* d; TRI_shaped_json_t shapedJson; d = (TRI_doc_mptr_t const*) *ptr; if (d->_validTo == 0) { TRI_vocbase_auth_t* auth; TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, d->_data); auth = ConvertAuthInfo(vocbase, primary, &shapedJson); if (auth != NULL) { TRI_vocbase_auth_t* old; old = TRI_InsertKeyAssociativePointer(&vocbase->_authInfo, auth->_username, auth, true); if (old != NULL) { FreeAuthInfo(old); } } } } } collection->_collection->endWrite(collection->_collection); // ............................................................................. // outside a write transaction // ............................................................................. vocbase->_authInfoFlush = true; TRI_WriteUnlockReadWriteLock(&vocbase->_authInfoLock); TRI_ReleaseCollectionVocBase(vocbase, collection); return true; }
static int HashIndexHelper (TRI_hash_index_t const* hashIndex, T* hashElement, TRI_doc_mptr_t const* document) { TRI_shaper_t* shaper; // underlying shaper TRI_shaped_json_t shapedObject; // the sub-object TRI_shaped_json_t shapedJson; // the object behind document TRI_shaped_sub_t shapedSub; // the relative sub-object shaper = hashIndex->base._collection->getShaper(); // ONLY IN INDEX, PROTECTED by RUNTIME // ............................................................................. // Assign the document to the TRI_hash_index_element_t structure - so that it // can later be retreived. // ............................................................................. TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, document->getDataPtr()); // ONLY IN INDEX, PROTECTED by RUNTIME hashElement->_document = const_cast<TRI_doc_mptr_t*>(document); char const* ptr = document->getShapedJsonPtr(); // ONLY IN INDEX // ............................................................................. // Extract the attribute values // ............................................................................. int res = TRI_ERROR_NO_ERROR; size_t const n = NumPaths(hashIndex); for (size_t j = 0; j < n; ++j) { TRI_shape_pid_t path = *((TRI_shape_pid_t*)(TRI_AtVector(&hashIndex->_paths, j))); // determine if document has that particular shape TRI_shape_access_t const* acc = TRI_FindAccessorVocShaper(shaper, shapedJson._sid, path); // field not part of the object if (acc == nullptr || acc->_resultSid == TRI_SHAPE_ILLEGAL) { shapedSub._sid = TRI_LookupBasicSidShaper(TRI_SHAPE_NULL); shapedSub._length = 0; shapedSub._offset = 0; res = TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING; } // extract the field else { if (! TRI_ExecuteShapeAccessor(acc, &shapedJson, &shapedObject)) { // hashElement->fields: memory deallocated in the calling procedure return TRI_ERROR_INTERNAL; } if (shapedObject._sid == TRI_LookupBasicSidShaper(TRI_SHAPE_NULL)) { res = TRI_ERROR_ARANGO_INDEX_DOCUMENT_ATTRIBUTE_MISSING; } shapedSub._sid = shapedObject._sid; shapedSub._length = shapedObject._data.length; shapedSub._offset = static_cast<uint32_t>(((char const*) shapedObject._data.data) - ptr); } // store the json shaped sub-object -- this is what will be hashed hashElement->_subObjects[j] = shapedSub; } return res; }
static int InsertGeoIndex (TRI_index_t* idx, TRI_doc_mptr_t const* doc, bool isRollback) { GeoCoordinate gc; TRI_shaped_json_t shapedJson; TRI_geo_index_t* geo; TRI_shaper_t* shaper; bool missing; bool ok; double latitude; double longitude; int res; geo = (TRI_geo_index_t*) idx; shaper = geo->base._collection->getShaper(); // ONLY IN INDEX, PROTECTED by RUNTIME // lookup latitude and longitude TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, doc->getDataPtr()); // ONLY IN INDEX, PROTECTED by RUNTIME if (geo->_location != 0) { if (geo->_geoJson) { ok = ExtractDoubleList(shaper, &shapedJson, geo->_location, &longitude, &latitude, &missing); } else { ok = ExtractDoubleList(shaper, &shapedJson, geo->_location, &latitude, &longitude, &missing); } } else { ok = ExtractDoubleArray(shaper, &shapedJson, geo->_latitude, &latitude, &missing); ok = ok && ExtractDoubleArray(shaper, &shapedJson, geo->_longitude, &longitude, &missing); } if (! ok) { if (idx->_unique) { if (idx->_ignoreNull && missing) { return TRI_ERROR_NO_ERROR; } else { return TRI_set_errno(TRI_ERROR_ARANGO_GEO_INDEX_VIOLATED); } } else { return TRI_ERROR_NO_ERROR; } } // and insert into index gc.latitude = latitude; gc.longitude = longitude; gc.data = CONST_CAST(doc); res = GeoIndex_insert(geo->_geoIndex, &gc); if (res == -1) { LOG_WARNING("found duplicate entry in geo-index, should not happen"); return TRI_set_errno(TRI_ERROR_INTERNAL); } else if (res == -2) { return TRI_set_errno(TRI_ERROR_OUT_OF_MEMORY); } else if (res == -3) { if (idx->_unique) { LOG_DEBUG("illegal geo-coordinates, ignoring entry"); return TRI_set_errno(TRI_ERROR_ARANGO_GEO_INDEX_VIOLATED); } else { return TRI_ERROR_NO_ERROR; } } else if (res < 0) { return TRI_set_errno(TRI_ERROR_INTERNAL); } return TRI_ERROR_NO_ERROR; }