static TRI_json_t* JsonGeo2Index (TRI_index_t const* idx) { TRI_json_t* json; TRI_json_t* fields; TRI_shape_path_t const* path; char const* latitude; char const* longitude; TRI_geo_index_t const* geo = (TRI_geo_index_t const*) idx; TRI_document_collection_t* document = idx->_collection; // convert latitude to string path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_latitude); // ONLY IN INDEX, PROTECTED by RUNTIME if (path == 0) { return nullptr; } latitude = TRI_NAME_SHAPE_PATH(path); // convert longitude to string path = document->getShaper()->lookupAttributePathByPid(document->getShaper(), geo->_longitude); // ONLY IN INDEX, PROTECTED by RUNTIME if (path == 0) { return nullptr; } longitude = TRI_NAME_SHAPE_PATH(path); // create json json = TRI_JsonIndex(TRI_CORE_MEM_ZONE, idx); if (json == nullptr) { return nullptr; } // "constraint" and "unique" are identical for geo indexes. // we return "constraint" just for downwards-compatibility TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "constraint", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, idx->_unique)); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "ignoreNull", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, geo->base._ignoreNull)); fields = TRI_CreateListJson(TRI_CORE_MEM_ZONE); TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, latitude)); TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, fields, TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, longitude)); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "fields", fields); return json; }
bool TRI_LoadAuthInfo (TRI_vocbase_t* vocbase) { LOG_DEBUG("starting to load authentication and authorization information"); TRI_vocbase_col_t* collection = TRI_LookupCollectionByNameVocBase(vocbase, TRI_COL_NAME_USERS); if (collection == nullptr) { LOG_INFO("collection '_users' does not exist, no authentication available"); return false; } SingleCollectionReadOnlyTransaction trx(new StandaloneTransactionContext(), vocbase, collection->_cid); int res = trx.begin(); if (res != TRI_ERROR_NO_ERROR) { return false; } TRI_document_collection_t* document = trx.documentCollection(); TRI_WriteLockReadWriteLock(&vocbase->_authInfoLock); ClearAuthInfo(vocbase); auto work = [&](TRI_doc_mptr_t const* ptr) -> void { TRI_vocbase_auth_t* auth = ConvertAuthInfo(vocbase, document, ptr); if (auth != nullptr) { TRI_vocbase_auth_t* old = static_cast<TRI_vocbase_auth_t*>(TRI_InsertKeyAssociativePointer(&vocbase->_authInfo, auth->_username, auth, true)); if (old != nullptr) { FreeAuthInfo(old); } } }; document->primaryIndex()->invokeOnAllElements(work); TRI_WriteUnlockReadWriteLock(&vocbase->_authInfoLock); trx.finish(TRI_ERROR_NO_ERROR); return true; }
int Syncer::applyCollectionDumpMarker (TRI_transaction_collection_t* trxCollection, TRI_replication_operation_e type, const TRI_voc_key_t key, const TRI_voc_rid_t rid, TRI_json_t const* json, string& errorMsg) { if (type == REPLICATION_MARKER_DOCUMENT || type == REPLICATION_MARKER_EDGE) { // {"type":2400,"key":"230274209405676","data":{"_key":"230274209405676","_rev":"230274209405676","foo":"bar"}} TRI_ASSERT(json != nullptr); TRI_document_collection_t* document = trxCollection->_collection->_collection; TRI_memory_zone_t* zone = document->getShaper()->_memoryZone; // PROTECTED by trx in trxCollection TRI_shaped_json_t* shaped = TRI_ShapedJsonJson(document->getShaper(), json, true); // PROTECTED by trx in trxCollection if (shaped == nullptr) { errorMsg = TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY); return TRI_ERROR_OUT_OF_MEMORY; } try { TRI_doc_mptr_copy_t mptr; bool const isLocked = TRI_IsLockedCollectionTransaction(trxCollection); int res = TRI_ReadShapedJsonDocumentCollection(trxCollection, key, &mptr, ! isLocked); if (res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { // insert if (type == REPLICATION_MARKER_EDGE) { // edge if (document->_info._type != TRI_COL_TYPE_EDGE) { res = TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID; } else { res = TRI_ERROR_NO_ERROR; } string const from = JsonHelper::getStringValue(json, TRI_VOC_ATTRIBUTE_FROM, ""); string const to = JsonHelper::getStringValue(json, TRI_VOC_ATTRIBUTE_TO, ""); CollectionNameResolver resolver(_vocbase); // parse _from TRI_document_edge_t edge; if (! DocumentHelper::parseDocumentId(resolver, from.c_str(), edge._fromCid, &edge._fromKey)) { res = TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD; } // parse _to if (! DocumentHelper::parseDocumentId(resolver, to.c_str(), edge._toCid, &edge._toKey)) { res = TRI_ERROR_ARANGO_DOCUMENT_HANDLE_BAD; } if (res == TRI_ERROR_NO_ERROR) { res = TRI_InsertShapedJsonDocumentCollection(trxCollection, key, rid, nullptr, &mptr, shaped, &edge, ! isLocked, false, true); } } else { // document if (document->_info._type != TRI_COL_TYPE_DOCUMENT) { res = TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID; } else { res = TRI_InsertShapedJsonDocumentCollection(trxCollection, key, rid, nullptr, &mptr, shaped, nullptr, ! isLocked, false, true); } } } else { // update res = TRI_UpdateShapedJsonDocumentCollection(trxCollection, key, rid, nullptr, &mptr, shaped, &_policy, ! isLocked, false); } TRI_FreeShapedJson(zone, shaped); return res; } catch (triagens::arango::Exception const& ex) { return ex.code(); } catch (...) { return TRI_ERROR_INTERNAL; } } else if (type == REPLICATION_MARKER_REMOVE) { // {"type":2402,"key":"592063"} int res = TRI_ERROR_INTERNAL; bool const isLocked = TRI_IsLockedCollectionTransaction(trxCollection); try { res = TRI_RemoveShapedJsonDocumentCollection(trxCollection, key, rid, nullptr, &_policy, ! isLocked, false); if (res != TRI_ERROR_NO_ERROR && res == TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) { // ignore this error res = TRI_ERROR_NO_ERROR; } } catch (triagens::arango::Exception const& ex) { res = ex.code(); } catch (...) { res = TRI_ERROR_INTERNAL; } if (res != TRI_ERROR_NO_ERROR) { errorMsg = "document removal operation failed: " + string(TRI_errno_string(res)); } return res; } else { errorMsg = "unexpected marker type " + StringUtils::itoa(type); return TRI_ERROR_REPLICATION_UNEXPECTED_MARKER; } }
void TRI_CleanupVocBase (void* data) { TRI_vocbase_t* vocbase; TRI_vector_pointer_t collections; uint64_t iterations = 0; vocbase = data; assert(vocbase); assert(vocbase->_state == 1); TRI_InitVectorPointer(&collections, TRI_UNKNOWN_MEM_ZONE); while (true) { int state; // keep initial _state value as vocbase->_state might change during cleanup loop state = vocbase->_state; ++iterations; if (state == 2) { // shadows must be cleaned before collections are handled // otherwise the shadows might still hold barriers on collections // and collections cannot be closed properly CleanupCursors(vocbase, true); } // check if we can get the compactor lock exclusively if (TRI_CheckAndLockCompactorVocBase(vocbase)) { size_t i, n; TRI_col_type_e type; // copy all collections TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase); TRI_CopyDataVectorPointer(&collections, &vocbase->_collections); TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase); n = collections._length; for (i = 0; i < n; ++i) { TRI_vocbase_col_t* collection; TRI_primary_collection_t* primary; collection = collections._buffer[i]; TRI_READ_LOCK_STATUS_VOCBASE_COL(collection); primary = collection->_collection; if (primary == NULL) { TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); continue; } type = primary->base._info._type; TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection); // we're the only ones that can unload the collection, so using // the collection pointer outside the lock is ok // maybe cleanup indexes, unload the collection or some datafiles if (TRI_IS_DOCUMENT_COLLECTION(type)) { TRI_document_collection_t* document = (TRI_document_collection_t*) primary; // clean indexes? if (iterations % (uint64_t) CLEANUP_INDEX_ITERATIONS == 0) { document->cleanupIndexes(document); } CleanupDocumentCollection(document); } } TRI_UnlockCompactorVocBase(vocbase); } if (vocbase->_state >= 1) { // server is still running, clean up unused shadows if (iterations % CLEANUP_SHADOW_ITERATIONS == 0) { CleanupCursors(vocbase, false); } // clean up expired compactor locks TRI_CleanupCompactorVocBase(vocbase); if (state == 1) { TRI_LockCondition(&vocbase->_cleanupCondition); TRI_TimedWaitCondition(&vocbase->_cleanupCondition, (uint64_t) CLEANUP_INTERVAL); TRI_UnlockCondition(&vocbase->_cleanupCondition); } } if (state == 3) { // server shutdown break; } } TRI_DestroyVectorPointer(&collections); LOG_TRACE("shutting down cleanup thread"); }