diff --git a/arangod/Agency/State.cpp b/arangod/Agency/State.cpp index f19ba08126..c35df0466d 100644 --- a/arangod/Agency/State.cpp +++ b/arangod/Agency/State.cpp @@ -642,8 +642,7 @@ bool State::createCollection(std::string const& name) { body.add("isSystem", VPackValue(TRI_vocbase_t::IsSystemName(name))); } - arangodb::LogicalCollection const* collection = - _vocbase->createCollection(body.slice()); + auto collection = _vocbase->createCollection(body.slice()); if (collection == nullptr) { THROW_ARANGO_EXCEPTION_MESSAGE(TRI_errno(), "cannot create collection"); diff --git a/arangod/Aql/AqlTransaction.cpp b/arangod/Aql/AqlTransaction.cpp index 4335226f24..93d7dc27c3 100644 --- a/arangod/Aql/AqlTransaction.cpp +++ b/arangod/Aql/AqlTransaction.cpp @@ -81,9 +81,8 @@ Result AqlTransaction::processCollectionCoordinator( Result AqlTransaction::processCollectionNormal(aql::Collection* collection) { TRI_voc_cid_t cid = 0; + auto col = resolver()->getCollectionStruct(collection->name()); - arangodb::LogicalCollection const* col = - resolver()->getCollectionStruct(collection->name()); if (col != nullptr) { cid = col->id(); } else { @@ -94,7 +93,7 @@ Result AqlTransaction::processCollectionNormal(aql::Collection* collection) { addCollection(cid, collection->name(), collection->accessType()); if (res.ok() && col != nullptr) { - collection->setCollection(const_cast(col)); + collection->setCollection(col.get()); } return res; diff --git a/arangod/Aql/Functions.cpp b/arangod/Aql/Functions.cpp index fa49e7072f..da6f532bff 100644 --- a/arangod/Aql/Functions.cpp +++ b/arangod/Aql/Functions.cpp @@ -4325,41 +4325,23 @@ AqlValue Functions::Collections(arangodb::aql::Query* query, builder->openArray(); auto& vocbase = query->vocbase(); - std::vector colls; + auto colls = GetCollections(vocbase); - // clean memory - std::function cleanup; - - // if we are a coordinator, we need to fetch the collection info from the - // agency - if (ServerState::instance()->isCoordinator()) { - cleanup = [&colls]() { - for (auto& it : colls) { - if (it != nullptr) { - delete it; - } - } - }; - - colls = GetCollectionsCluster(&vocbase); - } else { - colls = vocbase.collections(false); - cleanup = []() {}; - } - - // make sure memory is cleaned up - TRI_DEFER(cleanup()); - - std::sort(colls.begin(), colls.end(), - [](LogicalCollection* lhs, LogicalCollection* rhs) -> bool { - return basics::StringUtils::tolower(lhs->name()) < - basics::StringUtils::tolower(rhs->name()); - }); + std::sort( + colls.begin(), + colls.end(), + []( + std::shared_ptr const& lhs, + std::shared_ptr const& rhs + )->bool { + return arangodb::basics::StringUtils::tolower(lhs->name()) < arangodb::basics::StringUtils::tolower(rhs->name()); + } + ); size_t const n = colls.size(); for (size_t i = 0; i < n; ++i) { - LogicalCollection* coll = colls[i]; + auto& coll = colls[i]; if (ExecContext::CURRENT != nullptr && !ExecContext::CURRENT->canUseCollection(vocbase.name(), coll->name(), auth::Level::RO)) { diff --git a/arangod/Cluster/CreateCollection.cpp b/arangod/Cluster/CreateCollection.cpp index 9cc24047b2..dec4801d66 100644 --- a/arangod/Cluster/CreateCollection.cpp +++ b/arangod/Cluster/CreateCollection.cpp @@ -155,12 +155,14 @@ bool CreateCollection::first() { _result = Collections::create( vocbase, shard, type, docket.slice(), waitForRepl, enforceReplFact, - [=](LogicalCollection& col) { + [=](std::shared_ptr const& col)->void { + TRI_ASSERT(col); LOG_TOPIC(DEBUG, Logger::MAINTENANCE) << "local collection " << database << "/" << shard << " successfully created"; - col.followers()->setTheLeader(leader); + col->followers()->setTheLeader(leader); + if (leader.empty()) { - col.followers()->clear(); + col->followers()->clear(); } }); @@ -176,6 +178,7 @@ bool CreateCollection::first() { } catch (std::exception const& e) { std::stringstream error; + error << "action " << _description << " failed with exception " << e.what(); LOG_TOPIC(WARN, Logger::MAINTENANCE) << error.str(); _result.reset(TRI_ERROR_FAILED, error.str()); @@ -188,6 +191,6 @@ bool CreateCollection::first() { } notify(); - return false; + return false; } diff --git a/arangod/Cluster/DropCollection.cpp b/arangod/Cluster/DropCollection.cpp index fae8296ef8..29b5c06d04 100644 --- a/arangod/Cluster/DropCollection.cpp +++ b/arangod/Cluster/DropCollection.cpp @@ -76,31 +76,39 @@ bool DropCollection::first() { DatabaseGuard guard(database); auto vocbase = &guard.database(); - Result found = methods::Collections::lookup( - vocbase, collection, [&](LogicalCollection& coll) { + vocbase, + collection, + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); LOG_TOPIC(DEBUG, Logger::MAINTENANCE) << "Dropping local collection " + collection; - _result = Collections::drop(vocbase, &coll, false, 120); - }); + _result = Collections::drop(vocbase, coll.get(), false, 120); + } + ); if (found.fail()) { std::stringstream error; + error << "failed to lookup local collection " << database << "/" << collection; LOG_TOPIC(ERR, Logger::MAINTENANCE) << "DropCollection: " << error.str(); _result.reset(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND, error.str()); + return false; } } catch (std::exception const& e) { std::stringstream error; + error << " action " << _description << " failed with exception " << e.what(); LOG_TOPIC(ERR, Logger::MAINTENANCE) << error.str(); _result.reset(TRI_ERROR_INTERNAL, error.str()); + return false; } notify(); + return false; } diff --git a/arangod/Cluster/UpdateCollection.cpp b/arangod/Cluster/UpdateCollection.cpp index edaf10c8f9..755f944e9a 100644 --- a/arangod/Cluster/UpdateCollection.cpp +++ b/arangod/Cluster/UpdateCollection.cpp @@ -133,12 +133,14 @@ bool UpdateCollection::first() { auto const& props = properties(); try { - DatabaseGuard guard(database); auto vocbase = &guard.database(); Result found = methods::Collections::lookup( - vocbase, shard, [&](LogicalCollection& coll) { + vocbase, + shard, + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); LOG_TOPIC(DEBUG, Logger::MAINTENANCE) << "Updating local collection " + shard; @@ -146,8 +148,8 @@ bool UpdateCollection::first() { // resignation case is not handled here, since then // ourselves does not appear in shards[shard] but only // "_" + ourselves. - handleLeadership(coll, localLeader, plannedLeader); - _result = Collections::updateProperties(&coll, props); + handleLeadership(*coll, localLeader, plannedLeader); + _result = Collections::updateProperties(coll.get(), props); if (!_result.ok()) { LOG_TOPIC(ERR, Logger::MAINTENANCE) << "failed to update properties" @@ -163,17 +165,20 @@ bool UpdateCollection::first() { << "in database " + database; LOG_TOPIC(ERR, Logger::MAINTENANCE) << error.str(); _result = actionError(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, error.str()); + return false; } } catch (std::exception const& e) { std::stringstream error; + error << "action " << _description << " failed with exception " << e.what(); LOG_TOPIC(WARN, Logger::MAINTENANCE) << "UpdateCollection: " << error.str(); _result.reset(TRI_ERROR_INTERNAL, error.str()); + return false; } notify(); - return false; + return false; } diff --git a/arangod/ClusterEngine/ClusterV8Functions.cpp b/arangod/ClusterEngine/ClusterV8Functions.cpp index 03f6e0d6c5..f8d7342f93 100644 --- a/arangod/ClusterEngine/ClusterV8Functions.cpp +++ b/arangod/ClusterEngine/ClusterV8Functions.cpp @@ -33,6 +33,7 @@ #include "V8/v8-globals.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" +#include "V8Server/v8-collection.h" #include "V8Server/v8-externals.h" #include "VocBase/LogicalCollection.h" @@ -142,11 +143,9 @@ static void JS_EstimateCollectionSize( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -154,9 +153,11 @@ static void JS_EstimateCollectionSize( builder.openObject(); builder.add("documents", VPackValue(0)); builder.add("indexes", VPackValue(VPackValueType::Object)); - for (std::shared_ptr const& i : collection->getIndexes()) { + + for (auto& i : collection->getIndexes()) { builder.add(std::to_string(i->id()), VPackValue(0)); } + builder.close(); builder.add("total", VPackValue(0)); builder.close(); diff --git a/arangod/Graph/GraphManager.cpp b/arangod/Graph/GraphManager.cpp index c9415e9cce..33299012cc 100644 --- a/arangod/Graph/GraphManager.cpp +++ b/arangod/Graph/GraphManager.cpp @@ -97,10 +97,15 @@ OperationResult GraphManager::createCollection(std::string const& name, VPackSlice options) { TRI_ASSERT(colType == TRI_COL_TYPE_DOCUMENT || colType == TRI_COL_TYPE_EDGE); - - Result res = methods::Collections::create(&ctx()->vocbase(), name, colType, - options, waitForSync, true, - [&](LogicalCollection& coll) {}); + Result res = methods::Collections::create( + &ctx()->vocbase(), + name, + colType, + options, + waitForSync, + true, + [](std::shared_ptr const&)->void {} + ); return OperationResult(res); } @@ -534,23 +539,33 @@ Result GraphManager::ensureCollections(Graph const* graph, bool waitForSync) con for (auto const& edgeColl : graph->edgeCollections()) { bool found = false; Result res = methods::Collections::lookup( - vocbase, edgeColl, [&found, &innerRes, &graph](LogicalCollection& col) { - if (col.type() != TRI_COL_TYPE_EDGE) { - innerRes.reset( - TRI_ERROR_GRAPH_EDGE_DEFINITION_IS_DOCUMENT, - "Collection: '" + col.name() + "' is not an EdgeCollection"); - } else { - innerRes = graph->validateCollection(col); - found = true; - } - }); + vocbase, + edgeColl, + [&found, &innerRes, &graph]( + std::shared_ptr const& col + )->void { + TRI_ASSERT(col); + if (col->type() != TRI_COL_TYPE_EDGE) { + innerRes.reset( + TRI_ERROR_GRAPH_EDGE_DEFINITION_IS_DOCUMENT, + "Collection: '" + col->name() + "' is not an EdgeCollection" + ); + } else { + innerRes = graph->validateCollection(*col); + found = true; + } + } + ); + if (innerRes.fail()) { return innerRes; } + // Check if we got an error other then CollectionNotFound if (res.fail() && !res.is(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND)) { return res; } + if (!found) { edgeCollectionsToCreate.emplace(edgeColl); } @@ -563,14 +578,21 @@ Result GraphManager::ensureCollections(Graph const* graph, bool waitForSync) con for (auto const& vertexColl : graph->vertexCollections()) { bool found = false; Result res = methods::Collections::lookup( - vocbase, vertexColl, - [&found, &innerRes, &graph](LogicalCollection& col) { - innerRes = graph->validateCollection(col); - found = true; - }); + vocbase, + vertexColl, + [&found, &innerRes, &graph]( + std::shared_ptr const& col + )->void { + TRI_ASSERT(col); + innerRes = graph->validateCollection(*col); + found = true; + } + ); + if (innerRes.fail()) { return innerRes; } + // Check if we got an error other then CollectionNotFound if (res.fail() && !res.is(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND)) { return res; @@ -583,8 +605,6 @@ Result GraphManager::ensureCollections(Graph const* graph, bool waitForSync) con } } - - #ifdef USE_ENTERPRISE { Result res = ensureSmartCollectionSharding(graph, waitForSync, documentCollectionsToCreate); @@ -603,8 +623,15 @@ Result GraphManager::ensureCollections(Graph const* graph, bool waitForSync) con // Create Document Collections for (auto const& vertexColl : documentCollectionsToCreate) { Result res = methods::Collections::create( - vocbase, vertexColl, TRI_COL_TYPE_DOCUMENT, options, waitForSync, true, - [&](LogicalCollection& coll) {}); + vocbase, + vertexColl, + TRI_COL_TYPE_DOCUMENT, + options, + waitForSync, + true, + [](std::shared_ptr const&)->void {} + ); + if (res.fail()) { return res; } @@ -612,16 +639,23 @@ Result GraphManager::ensureCollections(Graph const* graph, bool waitForSync) con // Create Edge Collections for (auto const& edgeColl : edgeCollectionsToCreate) { - Result res = methods::Collections::create(vocbase, edgeColl, TRI_COL_TYPE_EDGE, - options, waitForSync, true, - [&](LogicalCollection& coll) {}); + Result res = methods::Collections::create( + vocbase, + edgeColl, + TRI_COL_TYPE_EDGE, + options, + waitForSync, + true, + [](std::shared_ptr const&)->void {} + ); + if (res.fail()) { return res; } } return TRI_ERROR_NO_ERROR; -}; +} OperationResult GraphManager::readGraphs(velocypack::Builder& builder, aql::QueryPart const queryPart) const { @@ -859,15 +893,22 @@ OperationResult GraphManager::removeGraph(Graph const& graph, bool waitForSync, boost::join(followersToBeRemoved, leadersToBeRemoved)) { Result dropResult; Result found = methods::Collections::lookup( - &ctx()->vocbase(), collection, [&](LogicalCollection& coll) { - dropResult = methods::Collections::drop(&ctx()->vocbase(), &coll, - false, -1.0); - }); + &ctx()->vocbase(), + collection, + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + dropResult = methods::Collections::drop( + &ctx()->vocbase(), coll.get(), false, -1.0 + ); + } + ); + if (dropResult.fail()) { LOG_TOPIC(WARN, Logger::GRAPHS) << "While removing graph `" << graph.name() << "`: " << "Dropping collection `" << collection << "` failed with error " << dropResult.errorNumber() << ": " << dropResult.errorMessage(); + // save the first error: if (firstDropError.ok()) { firstDropError = dropResult; diff --git a/arangod/Graph/GraphOperations.cpp b/arangod/Graph/GraphOperations.cpp index eb0bce2287..d97c0a4149 100644 --- a/arangod/Graph/GraphOperations.cpp +++ b/arangod/Graph/GraphOperations.cpp @@ -156,10 +156,14 @@ OperationResult GraphOperations::eraseEdgeDefinition( for (auto const& collection : collectionsToBeRemoved) { Result resIn; Result found = methods::Collections::lookup( - &_vocbase, collection, [&](LogicalCollection& coll) { - resIn = methods::Collections::drop(&_vocbase, &coll, false, - -1.0); - }); + &_vocbase, + collection, + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + resIn = + methods::Collections::drop(&_vocbase, coll.get(), false, -1.0); + } + ); if (found.fail()) { res = trx.finish(result.result); @@ -176,6 +180,7 @@ OperationResult GraphOperations::eraseEdgeDefinition( if (result.ok() && res.fail()) { return OperationResult(res); } + return result; } @@ -410,10 +415,14 @@ OperationResult GraphOperations::eraseOrphanCollection( for (auto const& collection : collectionsToBeRemoved) { Result resIn; Result found = methods::Collections::lookup( - &_vocbase, collection, [&](LogicalCollection& coll) { - resIn = methods::Collections::drop(&_vocbase, &coll, false, - -1.0); - }); + &_vocbase, + collection, + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + resIn = + methods::Collections::drop(&_vocbase, coll.get(), false, -1.0); + } + ); if (found.fail()) { return OperationResult(res); @@ -426,6 +435,7 @@ OperationResult GraphOperations::eraseOrphanCollection( if (result.ok() && res.fail()) { return OperationResult(res); } + return result; } diff --git a/arangod/MMFiles/MMFilesCleanupThread.cpp b/arangod/MMFiles/MMFilesCleanupThread.cpp index 77d035d17a..0e8e0b6ed9 100644 --- a/arangod/MMFiles/MMFilesCleanupThread.cpp +++ b/arangod/MMFiles/MMFilesCleanupThread.cpp @@ -53,8 +53,7 @@ void MMFilesCleanupThread::signal() { void MMFilesCleanupThread::run() { MMFilesEngine* engine = static_cast(EngineSelectorFeature::ENGINE); uint64_t iterations = 0; - - std::vector collections; + std::vector> collections; while (true) { // keep initial _state value as vocbase->_state might change during cleanup @@ -102,7 +101,7 @@ void MMFilesCleanupThread::run() { // we're the only ones that can unload the collection, so using // the collection pointer outside the lock is ok - cleanupCollection(collection); + cleanupCollection(collection.get()); } }, false); diff --git a/arangod/MMFiles/MMFilesCompactorThread.cpp b/arangod/MMFiles/MMFilesCompactorThread.cpp index 5592fd2eaf..026be151fd 100644 --- a/arangod/MMFiles/MMFilesCompactorThread.cpp +++ b/arangod/MMFiles/MMFilesCompactorThread.cpp @@ -885,7 +885,7 @@ void MMFilesCompactorThread::signal() { void MMFilesCompactorThread::run() { MMFilesEngine* engine = static_cast(EngineSelectorFeature::ENGINE); - std::vector collections; + std::vector> collections; int numCompacted = 0; while (true) { // keep initial _state value as vocbase->_state might change during @@ -943,8 +943,7 @@ void MMFilesCompactorThread::run() { try { double const now = TRI_microtime(); if (physical->lastCompactionStamp() + MMFilesCompactionFeature::COMPACTOR->compactionCollectionInterval() <= now) { - auto ce = arangodb::MMFilesCollection::toMMFilesCollection( - collection) + auto ce = arangodb::MMFilesCollection::toMMFilesCollection(collection.get()) ->ditches() ->createMMFilesCompactionDitch(__FILE__, __LINE__); @@ -954,7 +953,7 @@ void MMFilesCompactorThread::run() { } else { try { bool wasBlocked = false; - worked = compactCollection(collection, wasBlocked); + worked = compactCollection(collection.get(), wasBlocked); if (!worked && !wasBlocked) { // set compaction stamp @@ -969,7 +968,7 @@ void MMFilesCompactorThread::run() { // in case an error occurs, we must still free this ditch } - arangodb::MMFilesCollection::toMMFilesCollection(collection) + arangodb::MMFilesCollection::toMMFilesCollection(collection.get()) ->ditches() ->freeDitch(ce); } diff --git a/arangod/MMFiles/MMFilesV8Functions.cpp b/arangod/MMFiles/MMFilesV8Functions.cpp index ab61bd9dc8..f10b593121 100644 --- a/arangod/MMFiles/MMFilesV8Functions.cpp +++ b/arangod/MMFiles/MMFilesV8Functions.cpp @@ -38,6 +38,7 @@ #include "V8/v8-conv.h" #include "V8/v8-globals.h" #include "V8/v8-utils.h" +#include "V8Server/v8-collection.h" #include "V8Server/v8-externals.h" #include "V8Server/v8-vocbaseprivate.h" #include "VocBase/LogicalCollection.h" @@ -54,10 +55,9 @@ static void JS_RotateVocbaseCol( PREVENT_EMBEDDED_TRANSACTION(); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -72,9 +72,10 @@ static void JS_RotateVocbaseCol( TRI_V8_THROW_EXCEPTION(res); } - OperationResult result = trx.rotateActiveJournal(collection->name(), OperationOptions()); - res.reset(result.result); + OperationResult result = + trx.rotateActiveJournal(collection->name(), OperationOptions()); + res.reset(result.result); trx.finish(res); if (!res.ok()) { @@ -93,10 +94,9 @@ static void JS_DatafilesVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -104,13 +104,16 @@ static void JS_DatafilesVocbaseCol( // TODO: move this into engine StorageEngine* engine = EngineSelectorFeature::ENGINE; - TRI_vocbase_col_status_e status = collection->getStatusLocked(); + auto status = collection->getStatusLocked(); + if (status != TRI_VOC_COL_STATUS_UNLOADED && status != TRI_VOC_COL_STATUS_CORRUPTED) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_UNLOADED); } - MMFilesEngineCollectionFiles structure = dynamic_cast(engine)->scanCollectionDirectory(collection->getPhysical()->path()); + auto structure = dynamic_cast(engine)->scanCollectionDirectory( + collection->getPhysical()->path() + ); // build result v8::Handle result = v8::Object::New(isolate); @@ -153,10 +156,9 @@ static void JS_DatafileScanVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -168,7 +170,8 @@ static void JS_DatafileScanVocbaseCol( v8::Handle result; { - TRI_vocbase_col_status_e status = collection->getStatusLocked(); + auto status = collection->getStatusLocked(); + if (status != TRI_VOC_COL_STATUS_UNLOADED && status != TRI_VOC_COL_STATUS_CORRUPTED) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_UNLOADED); @@ -239,10 +242,9 @@ static void JS_TryRepairDatafileVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -253,8 +255,8 @@ static void JS_TryRepairDatafileVocbaseCol( } std::string path = TRI_ObjectToString(args[0]); + auto status = collection->getStatusLocked(); - TRI_vocbase_col_status_e status = collection->getStatusLocked(); if (status != TRI_VOC_COL_STATUS_UNLOADED && status != TRI_VOC_COL_STATUS_CORRUPTED) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_UNLOADED); @@ -276,10 +278,9 @@ static void JS_TruncateDatafileVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -291,8 +292,7 @@ static void JS_TruncateDatafileVocbaseCol( std::string path = TRI_ObjectToString(args[0]); size_t size = (size_t)TRI_ObjectToInt64(args[1]); - - TRI_vocbase_col_status_e status = collection->getStatusLocked(); + auto status = collection->getStatusLocked(); if (status != TRI_VOC_COL_STATUS_UNLOADED && status != TRI_VOC_COL_STATUS_CORRUPTED) { diff --git a/arangod/MMFiles/MMFilesWalRecoverState.cpp b/arangod/MMFiles/MMFilesWalRecoverState.cpp index deed80a037..1953abb054 100644 --- a/arangod/MMFiles/MMFilesWalRecoverState.cpp +++ b/arangod/MMFiles/MMFilesWalRecoverState.cpp @@ -1058,12 +1058,10 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker, // restore the old behavior afterwards TRI_DEFER(state->databaseFeature->forceSyncProperties(oldSync)); - collection = - vocbase->createCollection(b2.slice()); + collection = vocbase->createCollection(b2.slice()).get(); } else { // collection will be kept - collection = - vocbase->createCollection(b2.slice()); + collection = vocbase->createCollection(b2.slice()).get(); } TRI_ASSERT(collection != nullptr); } catch (basics::Exception const& ex) { diff --git a/arangod/Replication/Syncer.cpp b/arangod/Replication/Syncer.cpp index 52bb155560..cf4f1eac7c 100644 --- a/arangod/Replication/Syncer.cpp +++ b/arangod/Replication/Syncer.cpp @@ -569,7 +569,7 @@ Result Syncer::createCollection(TRI_vocbase_t& vocbase, TRI_COL_TYPE_DOCUMENT)); // resolve collection by uuid, name, cid (in that order of preference) - auto* col = resolveCollection(vocbase, slice).get(); + auto col = resolveCollection(vocbase, slice); if (col != nullptr && col->type() == type && (!_state.master.simulate32Client() || col->name() == name)) { @@ -586,7 +586,7 @@ Result Syncer::createCollection(TRI_vocbase_t& vocbase, } // conflicting collections need to be dropped from 3.3 onwards - col = vocbase.lookupCollection(name).get(); + col = vocbase.lookupCollection(name); if (col != nullptr) { if (col->system()) { @@ -658,7 +658,7 @@ Result Syncer::createCollection(TRI_vocbase_t& vocbase, TRI_ASSERT(!uuid.isString() || uuid.compareString(col->guid()) == 0); if (dst != nullptr) { - *dst = col; + *dst = col.get(); } return Result(); diff --git a/arangod/RestHandler/RestCollectionHandler.cpp b/arangod/RestHandler/RestCollectionHandler.cpp index b8f05e2e3e..d95fb38c60 100644 --- a/arangod/RestHandler/RestCollectionHandler.cpp +++ b/arangod/RestHandler/RestCollectionHandler.cpp @@ -83,14 +83,15 @@ void RestCollectionHandler::handleCommandGet() { builder.openArray(); methods::Collections::enumerate( &_vocbase, - [&](LogicalCollection& coll)->void { + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); ExecContext const* exec = ExecContext::CURRENT; bool canUse = exec == nullptr - || exec->canUseCollection(coll.name(), auth::Level::RO); + || exec->canUseCollection(coll->name(), auth::Level::RO); - if (canUse && (!excludeSystem || !coll.system())) { + if (canUse && (!excludeSystem || !coll->system())) { // We do not need a transaction here - methods::Collections::Context ctxt(_vocbase, coll); + methods::Collections::Context ctxt(_vocbase, *coll); collectionRepresentation(builder, ctxt, /*showProperties*/ false, @@ -131,16 +132,18 @@ void RestCollectionHandler::handleCommandGet() { Result found = methods::Collections::lookup( &_vocbase, name, - [&](LogicalCollection& coll)->void { + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + if (sub == "checksum") { // /_api/collection//checksum - if (!coll.isLocal()) { + if (!coll->isLocal()) { THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED); } bool withRevisions = _request->parsedValue("withRevisions", false); bool withData = _request->parsedValue("withData", false); - auto result = coll.checksum(withRevisions, withData); + auto result = coll->checksum(withRevisions, withData); if (result.ok()) { VPackObjectBuilder obj(&builder, true); @@ -149,34 +152,53 @@ void RestCollectionHandler::handleCommandGet() { obj->add("revision", result.slice().get("revision")); // We do not need a transaction here - methods::Collections::Context ctxt(_vocbase, coll); + methods::Collections::Context ctxt(_vocbase, *coll); - collectionRepresentation(builder, coll, /*showProperties*/ false, - /*showFigures*/ false, /*showCount*/ false, - /*detailedCount*/ true); + collectionRepresentation( + builder, + *coll, + /*showProperties*/ false, + /*showFigures*/ false, + /*showCount*/ false, + /*detailedCount*/ true + ); } else { skipGenerate = true; this->generateError(result); } } else if (sub == "figures") { // /_api/collection//figures - collectionRepresentation(builder, coll, /*showProperties*/ true, - /*showFigures*/ true, /*showCount*/ true, - /*detailedCount*/ false); + collectionRepresentation( + builder, + *coll, + /*showProperties*/ true, + /*showFigures*/ true, + /*showCount*/ true, + /*detailedCount*/ false + ); } else if (sub == "count") { // /_api/collection//count bool details = _request->parsedValue("details", false); - collectionRepresentation(builder, coll, /*showProperties*/ true, - /*showFigures*/ false, /*showCount*/ true, - /*detailedCount*/ details); + collectionRepresentation( + builder, + *coll, + /*showProperties*/ true, + /*showFigures*/ false, + /*showCount*/ true, + /*detailedCount*/ details + ); } else if (sub == "properties") { // /_api/collection//properties - collectionRepresentation(builder, coll, /*showProperties*/ true, - /*showFigures*/ false, /*showCount*/ false, - /*detailedCount*/ true); + collectionRepresentation( + builder, + *coll, + /*showProperties*/ true, + /*showFigures*/ false, + /*showCount*/ false, + /*detailedCount*/ true + ); } else if (sub == "revision") { - - methods::Collections::Context ctxt(_vocbase, coll); + methods::Collections::Context ctxt(_vocbase, *coll); // /_api/collection//revision TRI_voc_rid_t revisionId; auto res = @@ -202,11 +224,18 @@ void RestCollectionHandler::handleCommandGet() { } VPackObjectBuilder obj(&builder, true); // need to open object - collectionRepresentation(builder, coll, /*showProperties*/ true, - /*showFigures*/ false, /*showCount*/ false, - /*detailedCount*/ true); + + collectionRepresentation( + builder, + *coll, + /*showProperties*/ true, + /*showFigures*/ false, + /*showCount*/ false, + /*detailedCount*/ true + ); + auto shards = ClusterInfo::instance()->getShardList( - std::to_string(coll.planId()) + std::to_string(coll->planId()) ); VPackArrayBuilder arr(&builder, "shards", true); @@ -290,10 +319,11 @@ void RestCollectionHandler::handleCommandPost() { parameters, waitForSyncReplication, enforceReplicationFactor, - [&](LogicalCollection& coll)->void { + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); collectionRepresentation( builder, - coll.name(), + coll->name(), /*showProperties*/ true, /*showFigures*/ false, /*showCount*/ false, @@ -334,9 +364,11 @@ void RestCollectionHandler::handleCommandPut() { Result found = methods::Collections::lookup( &_vocbase, name, - [&](LogicalCollection& coll)->void { + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + if (sub == "load") { - res = methods::Collections::load(_vocbase, &coll); + res = methods::Collections::load(_vocbase, coll.get()); if (res.ok()) { bool cc = VelocyPackHelper::getBooleanValue(body, "count", true); @@ -347,12 +379,12 @@ void RestCollectionHandler::handleCommandPut() { } else if (sub == "unload") { bool flush = _request->parsedValue("flush", false); - if (flush && - coll.status() == TRI_vocbase_col_status_e::TRI_VOC_COL_STATUS_LOADED) { + if (flush + && TRI_vocbase_col_status_e::TRI_VOC_COL_STATUS_LOADED == coll->status()) { EngineSelectorFeature::ENGINE->flushWal(false, false, false); } - res = methods::Collections::unload(&_vocbase, &coll); + res = methods::Collections::unload(&_vocbase, coll.get()); if (res.ok()) { collectionRepresentation(builder, name, /*showProperties*/ false, @@ -367,34 +399,38 @@ void RestCollectionHandler::handleCommandPut() { _request->value("isSynchronousReplication"); auto ctx = transaction::StandaloneContext::Create(_vocbase); - SingleCollectionTransaction trx(ctx, coll, AccessMode::Type::EXCLUSIVE); + SingleCollectionTransaction trx(ctx, *coll, AccessMode::Type::EXCLUSIVE); trx.addHint(transaction::Hints::Hint::INTERMEDIATE_COMMITS); trx.addHint(transaction::Hints::Hint::ALLOW_RANGE_DELETE); res = trx.begin(); if (res.ok()) { - auto result = trx.truncate(coll.name(), opts); + auto result = trx.truncate(coll->name(), opts); res = trx.finish(result.result); } if (res.ok()) { - if (!coll.isLocal()) { // ClusterInfo::loadPlan eventually updates status - coll.setStatus(TRI_vocbase_col_status_e::TRI_VOC_COL_STATUS_LOADED); - } + if (!coll->isLocal()) { // ClusterInfo::loadPlan eventually updates status + coll->setStatus(TRI_vocbase_col_status_e::TRI_VOC_COL_STATUS_LOADED); + } - collectionRepresentation(builder, coll, /*showProperties*/ false, - /*showFigures*/ false, /*showCount*/ false, - /*detailedCount*/ true); + collectionRepresentation( + builder, + *coll, + /*showProperties*/ false, + /*showFigures*/ false, + /*showCount*/ false, + /*detailedCount*/ true + ); } - } else if (sub == "properties") { std::vector keep = {"doCompact", "journalSize", "waitForSync", "indexBuckets", "replicationFactor", "cacheEnabled"}; VPackBuilder props = VPackCollection::keep(body, keep); - res = methods::Collections::updateProperties(&coll, props.slice()); + res = methods::Collections::updateProperties(coll.get(), props.slice()); if (res.ok()) { collectionRepresentation(builder, name, /*showProperties*/ true, @@ -410,7 +446,7 @@ void RestCollectionHandler::handleCommandPut() { } std::string const newName = newNameSlice.copyString(); - res = methods::Collections::rename(&coll, newName, false); + res = methods::Collections::rename(coll.get(), newName, false); if (res.ok()) { collectionRepresentation(builder, newName, /*showProperties*/ false, @@ -420,13 +456,13 @@ void RestCollectionHandler::handleCommandPut() { } else if (sub == "rotate") { auto ctx = transaction::StandaloneContext::Create(_vocbase); - SingleCollectionTransaction trx(ctx, coll, AccessMode::Type::WRITE); + SingleCollectionTransaction trx(ctx, *coll, AccessMode::Type::WRITE); res = trx.begin(); if (res.ok()) { auto result = - trx.rotateActiveJournal(coll.name(), OperationOptions()); + trx.rotateActiveJournal(coll->name(), OperationOptions()); res = trx.finish(result.result); } @@ -435,7 +471,7 @@ void RestCollectionHandler::handleCommandPut() { builder.add("result", VPackValue(true)); builder.close(); } else if (sub == "loadIndexesIntoMemory") { - res = methods::Collections::warmup(_vocbase, coll); + res = methods::Collections::warmup(_vocbase, *coll); VPackObjectBuilder obj(&builder, true); @@ -474,12 +510,16 @@ void RestCollectionHandler::handleCommandDelete() { Result found = methods::Collections::lookup( &_vocbase, name, - [&](LogicalCollection& coll)->void { - auto cid = std::to_string(coll.id()); + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + + auto cid = std::to_string(coll->id()); VPackObjectBuilder obj(&builder, true); obj->add("id", VPackValue(cid)); - res = methods::Collections::drop(&_vocbase, &coll, allowDropSystem, -1.0); + res = methods::Collections::drop( + &_vocbase, coll.get(), allowDropSystem, -1.0 + ); } ); @@ -503,9 +543,11 @@ void RestCollectionHandler::collectionRepresentation( Result r = methods::Collections::lookup( &_vocbase, name, - [&](LogicalCollection& coll)->void { - collectionRepresentation(builder, coll, showProperties, showFigures, - showCount, detailedCount); + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + collectionRepresentation( + builder, *coll, showProperties, showFigures, showCount, detailedCount + ); } ); diff --git a/arangod/RestHandler/RestReplicationHandler.cpp b/arangod/RestHandler/RestReplicationHandler.cpp index eddd5cd208..747e4c9e77 100644 --- a/arangod/RestHandler/RestReplicationHandler.cpp +++ b/arangod/RestHandler/RestReplicationHandler.cpp @@ -2564,14 +2564,14 @@ int RestReplicationHandler::createCollection(VPackSlice slice, TRI_col_type_e const type = static_cast( arangodb::basics::VelocyPackHelper::getNumericValue( slice, "type", int(TRI_COL_TYPE_DOCUMENT))); - arangodb::LogicalCollection* col = nullptr; + std::shared_ptr col; if (!uuid.empty()) { - col = _vocbase.lookupCollectionByUuid(uuid).get(); + col = _vocbase.lookupCollectionByUuid(uuid); } if (col != nullptr) { - col = _vocbase.lookupCollection(name).get(); + col = _vocbase.lookupCollection(name); } if (col != nullptr && col->type() == type) { @@ -2624,7 +2624,7 @@ int RestReplicationHandler::createCollection(VPackSlice slice, #endif if (dst != nullptr) { - *dst = col; + *dst = col.get(); } return TRI_ERROR_NO_ERROR; diff --git a/arangod/RestHandler/RestUsersHandler.cpp b/arangod/RestHandler/RestUsersHandler.cpp index 98751a47e6..08ec8a2c24 100644 --- a/arangod/RestHandler/RestUsersHandler.cpp +++ b/arangod/RestHandler/RestUsersHandler.cpp @@ -237,13 +237,11 @@ void RestUsersHandler::generateDatabaseResult(auth::UserManager* um, methods::Collections::enumerate( &vocbase, - [&](LogicalCollection& c)->void { + [&](std::shared_ptr const& c)->void { + TRI_ASSERT(c); lvl = - user.configuredCollectionAuthLevel(vocbase.name(), c.name()); - data.add( - c.name(), - velocypack::Value(convertFromAuthLevel(lvl)) - ); + user.configuredCollectionAuthLevel(vocbase.name(), c->name()); + data.add(c->name(), velocypack::Value(convertFromAuthLevel(lvl))); } ); lvl = user.configuredCollectionAuthLevel(vocbase.name(), "*"); diff --git a/arangod/RestHandler/RestViewHandler.cpp b/arangod/RestHandler/RestViewHandler.cpp index b26cf5bbe3..d2c44fc721 100644 --- a/arangod/RestHandler/RestViewHandler.cpp +++ b/arangod/RestHandler/RestViewHandler.cpp @@ -344,29 +344,35 @@ void RestViewHandler::modifyView(bool partialUpdate) { body, partialUpdate, true ); // TODO: not force sync? - if (result.ok()) { - VPackBuilder updated; - - updated.openObject(); - - auto res = view->toVelocyPack(updated, true, false); - - updated.close(); - - if (!res.ok()) { - generateError(res); - - return; - } - - generateResult(rest::ResponseCode::OK, updated.slice()); - - return; - } else { + if (!result.ok()) { generateError(GeneralResponse::responseCode(result.errorNumber()), result.errorNumber(), result.errorMessage()); return; } + + view = _vocbase.lookupView(view->id()); // ensure have the latest definition + + if (!view) { + generateError(arangodb::Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND)); + + return; + } + + arangodb::velocypack::Builder updated; + + updated.openObject(); + + auto res = view->toVelocyPack(updated, true, false); + + updated.close(); + + if (!res.ok()) { + generateError(res); + + return; + } + + generateResult(rest::ResponseCode::OK, updated.slice()); } catch (...) { // TODO: cleanup? throw; diff --git a/arangod/RocksDBEngine/RocksDBV8Functions.cpp b/arangod/RocksDBEngine/RocksDBV8Functions.cpp index 404dba9d5c..f0355deffb 100644 --- a/arangod/RocksDBEngine/RocksDBV8Functions.cpp +++ b/arangod/RocksDBEngine/RocksDBV8Functions.cpp @@ -34,6 +34,7 @@ #include "V8/v8-globals.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" +#include "V8Server/v8-collection.h" #include "V8Server/v8-externals.h" #include "VocBase/LogicalCollection.h" @@ -133,15 +134,13 @@ static void JS_RecalculateCounts( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - auto physical = toRocksDBCollection(*collection); + auto* physical = toRocksDBCollection(*collection); v8::Handle result = v8::Number::New( isolate, static_cast(physical->recalculateCounts())); @@ -155,15 +154,13 @@ static void JS_CompactCollection( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - RocksDBCollection* physical = toRocksDBCollection(*collection); + auto* physical = toRocksDBCollection(*collection); physical->compact(); TRI_V8_RETURN_UNDEFINED(); @@ -175,15 +172,13 @@ static void JS_EstimateCollectionSize( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - RocksDBCollection* physical = toRocksDBCollection(*collection); + auto* physical = toRocksDBCollection(*collection); VPackBuilder builder; physical->estimateSize(builder); diff --git a/arangod/Statistics/StatisticsWorker.cpp b/arangod/Statistics/StatisticsWorker.cpp index c27afb7907..cfd513d674 100644 --- a/arangod/Statistics/StatisticsWorker.cpp +++ b/arangod/Statistics/StatisticsWorker.cpp @@ -1019,7 +1019,7 @@ void StatisticsWorker::createCollection(std::string const& collection) const { s.slice(), false, true, - [&](LogicalCollection&) {} + [](std::shared_ptr const&)->void {} ); if (r.is(TRI_ERROR_SHUTTING_DOWN)) { @@ -1038,7 +1038,9 @@ void StatisticsWorker::createCollection(std::string const& collection) const { r = methods::Collections::lookup( &_vocbase, collection, - [&](LogicalCollection& coll) { + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + VPackBuilder t; t.openObject(); @@ -1054,7 +1056,7 @@ void StatisticsWorker::createCollection(std::string const& collection) const { VPackBuilder output; Result idxRes = - methods::Indexes::ensureIndex(&coll, t.slice(), true, output); + methods::Indexes::ensureIndex(coll.get(), t.slice(), true, output); if (!idxRes.ok()) { LOG_TOPIC(WARN, Logger::STATISTICS) diff --git a/arangod/Utils/CollectionNameResolver.cpp b/arangod/Utils/CollectionNameResolver.cpp index c5c3b7014e..008042029b 100644 --- a/arangod/Utils/CollectionNameResolver.cpp +++ b/arangod/Utils/CollectionNameResolver.cpp @@ -74,7 +74,7 @@ TRI_voc_cid_t CollectionNameResolver::getCollectionIdLocal( return NumberUtils::atoi_zero(name.data(), name.data() + name.size()); } - arangodb::LogicalCollection const* collection = getCollectionStruct(name); + auto collection = getCollectionStruct(name); if (collection != nullptr) { return collection->id(); @@ -146,7 +146,7 @@ TRI_voc_cid_t CollectionNameResolver::getCollectionIdCluster( std::shared_ptr CollectionNameResolver::getCollectionStructCluster( std::string const& name) const { if (!ServerState::isRunningInCluster(_serverRole)) { - return std::shared_ptr(const_cast(getCollectionStruct(name)), [](LogicalCollection*){}); + return getCollectionStruct(name); } try { @@ -183,8 +183,9 @@ TRI_voc_cid_t CollectionNameResolver::getCollectionId( /// @brief look up a collection struct for a collection name ////////////////////////////////////////////////////////////////////////////// -arangodb::LogicalCollection const* CollectionNameResolver::getCollectionStruct( - std::string const& name) const { +std::shared_ptr CollectionNameResolver::getCollectionStruct( + std::string const& name +) const { { READ_LOCKER(locker, _nameLock); auto it = _resolvedNames.find(name); @@ -194,7 +195,7 @@ arangodb::LogicalCollection const* CollectionNameResolver::getCollectionStruct( } } - auto* collection = _vocbase.lookupCollection(name).get(); + auto collection = _vocbase.lookupCollection(name); if (collection != nullptr) { WRITE_LOCKER(locker, _nameLock); diff --git a/arangod/Utils/CollectionNameResolver.h b/arangod/Utils/CollectionNameResolver.h index 7a40fd0c8d..b0a5e472ce 100644 --- a/arangod/Utils/CollectionNameResolver.h +++ b/arangod/Utils/CollectionNameResolver.h @@ -102,7 +102,9 @@ class CollectionNameResolver { ////////////////////////////////////////////////////////////////////////////// /// @brief look up a collection struct for a collection name ////////////////////////////////////////////////////////////////////////////// - arangodb::LogicalCollection const* getCollectionStruct(std::string const& name) const; + std::shared_ptr getCollectionStruct( + std::string const& name + ) const; ////////////////////////////////////////////////////////////////////////////// /// @brief look up a collection name for a collection id, this implements @@ -185,8 +187,7 @@ class CollectionNameResolver { ////////////////////////////////////////////////////////////////////////////// /// @brief collection id => collection struct map ////////////////////////////////////////////////////////////////////////////// - mutable std::unordered_map - _resolvedNames; + mutable std::unordered_map> _resolvedNames; ////////////////////////////////////////////////////////////////////////////// /// @brief collection id => collection name map @@ -199,4 +200,4 @@ class CollectionNameResolver { } -#endif +#endif \ No newline at end of file diff --git a/arangod/V8Server/v8-collection-util.cpp b/arangod/V8Server/v8-collection-util.cpp index 2619ab9b93..c512070ffa 100644 --- a/arangod/V8Server/v8-collection-util.cpp +++ b/arangod/V8Server/v8-collection-util.cpp @@ -62,50 +62,16 @@ bool EqualCollection(CollectionNameResolver const* resolver, return false; } -//////////////////////////////////////////////////////////////////////////////// -/// @brief weak reference callback for collections -//////////////////////////////////////////////////////////////////////////////// - -static void WeakCollectionCallback(const v8::WeakCallbackInfo< - v8::Persistent>& data) { - auto isolate = data.GetIsolate(); - auto persistent = data.GetParameter(); - auto myCollection = v8::Local::New(isolate, *persistent); - auto collection = static_cast(myCollection->Value()); - TRI_GET_GLOBALS(); - - v8g->decreaseActiveExternals(); - - // decrease the reference-counter for the database - TRI_ASSERT(!collection->vocbase().isDangling()); - - // find the persistent handle -#if ARANGODB_ENABLE_MAINTAINER_MODE - auto const& it = v8g->JSCollections.find(collection); - TRI_ASSERT(it != v8g->JSCollections.end()); -#endif - - // dispose and clear the persistent handle - v8g->JSCollections[collection].Reset(); - v8g->JSCollections.erase(collection); - - if (!collection->isLocal()) { - collection->vocbase().release(); - delete collection; - } else { - collection->vocbase().release(); - } -} - //////////////////////////////////////////////////////////////////////////////// /// @brief wraps a LogicalCollection /// Note that if collection is a local collection, then the object will never /// be freed. If it is not a local collection (coordinator case), then delete /// will be called when the V8 object is garbage collected. //////////////////////////////////////////////////////////////////////////////// - -v8::Handle WrapCollection(v8::Isolate* isolate, - arangodb::LogicalCollection const* collection) { +v8::Handle WrapCollection( + v8::Isolate* isolate, + std::shared_ptr const& collection +) { v8::EscapableHandleScope scope(isolate); TRI_GET_GLOBALS(); @@ -113,40 +79,32 @@ v8::Handle WrapCollection(v8::Isolate* isolate, v8::Handle result = VocbaseColTempl->NewInstance(); if (!result.IsEmpty()) { - LogicalCollection* nonconstCollection = - const_cast(collection); + auto* ptr = collection.get(); + auto itr = v8g->JSDatasources.emplace( + std::piecewise_construct, + std::forward_as_tuple(collection.get()), + std::forward_as_tuple( + isolate, + collection, + [ptr]()->void { // FIXME TODO find a way to move this callback code into DataSourcePersistent + TRI_ASSERT(!ptr->vocbase().isDangling()); + ptr->vocbase().release(); // decrease the reference-counter for the database + } + ) + ); + auto& entry = itr.first->second; - result->SetInternalField(SLOT_CLASS_TYPE, - v8::Integer::New(isolate, WRP_VOCBASE_COL_TYPE)); - result->SetInternalField(SLOT_CLASS, - v8::External::New(isolate, nonconstCollection)); - - auto const& it = v8g->JSCollections.find(nonconstCollection); - - if (it == v8g->JSCollections.end()) { - // increase the reference-counter for the database - TRI_ASSERT(!nonconstCollection->vocbase().isDangling()); - nonconstCollection->vocbase().forceUse(); - - try { - auto externalCollection = v8::External::New(isolate, nonconstCollection); - - result->SetInternalField(SLOT_EXTERNAL, externalCollection); - - v8g->JSCollections[nonconstCollection].Reset(isolate, externalCollection); - v8g->JSCollections[nonconstCollection].SetWeak(&v8g->JSCollections[nonconstCollection], - WeakCollectionCallback, - v8::WeakCallbackType::kFinalizer); - v8g->increaseActiveExternals(); - } catch (...) { - nonconstCollection->vocbase().release(); - throw; - } - } else { - auto myCollection = v8::Local::New(isolate, it->second); - - result->SetInternalField(SLOT_EXTERNAL, myCollection); + if (itr.second) { // FIXME TODO find a way to move this code into DataSourcePersistent + TRI_ASSERT(!ptr->vocbase().isDangling()); + ptr->vocbase().forceUse(); // increase the reference-counter for the database } + + result->SetInternalField( + SLOT_CLASS_TYPE, v8::Integer::New(isolate, WRP_VOCBASE_COL_TYPE) + ); + result->SetInternalField(SLOT_CLASS, entry.get()); + result->SetInternalField(SLOT_EXTERNAL, entry.get()); + TRI_GET_GLOBAL_STRING(_IdKey); TRI_GET_GLOBAL_STRING(_DbNameKey); TRI_GET_GLOBAL_STRING(VersionKeyHidden); @@ -164,3 +122,15 @@ v8::Handle WrapCollection(v8::Isolate* isolate, return scope.Escape(result); } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief unwrap a LogicalCollection wrapped via WrapCollection(...) +/// @return collection or nullptr on failure +//////////////////////////////////////////////////////////////////////////////// +arangodb::LogicalCollection* UnwrapCollection( + v8::Local const& holder +) { + return TRI_UnwrapClass( + holder, WRP_VOCBASE_COL_TYPE + ); +} diff --git a/arangod/V8Server/v8-collection.cpp b/arangod/V8Server/v8-collection.cpp index ae1d3864ed..a147d15602 100644 --- a/arangod/V8Server/v8-collection.cpp +++ b/arangod/V8Server/v8-collection.cpp @@ -72,23 +72,44 @@ #include #include +namespace { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief retrieves a collection from a V8 argument +//////////////////////////////////////////////////////////////////////////////// +std::shared_ptr GetCollectionFromArgument( + TRI_vocbase_t& vocbase, + v8::Handle const val +) { + if (arangodb::ServerState::instance()->isCoordinator()) { + try { + auto* ci = arangodb::ClusterInfo::instance(); + + return ci + ? ci->getCollection(vocbase.name(), TRI_ObjectToString(val)) : nullptr; + } catch (...) { + // NOOP + } + + return nullptr; // not found + } + + // number + if (val->IsNumber() || val->IsNumberObject()) { + uint64_t cid = TRI_ObjectToUInt64(val, true); + + return vocbase.lookupCollection(cid); + } + + return vocbase.lookupCollection(TRI_ObjectToString(val)); +} + +} + using namespace arangodb; using namespace arangodb::basics; using namespace arangodb::rest; -struct LocalCollectionGuard { - explicit LocalCollectionGuard(LogicalCollection* collection) - : _collection(collection) {} - - ~LocalCollectionGuard() { - if (_collection != nullptr && !_collection->isLocal()) { - delete _collection; - } - } - - LogicalCollection* _collection; -}; - //////////////////////////////////////////////////////////////////////////////// /// @brief extract a boolean flag from the arguments /// must specify the argument index starting from 1 @@ -149,14 +170,16 @@ static std::string ExtractIdString(v8::Isolate* isolate, /// @brief parse document or document handle from a v8 value (string | object) //////////////////////////////////////////////////////////////////////////////// -static int ParseDocumentOrDocumentHandle(v8::Isolate* isolate, - TRI_vocbase_t* vocbase, - CollectionNameResolver const* resolver, - LogicalCollection const*& collection, - std::string& collectionName, - VPackBuilder& builder, - bool includeRev, - v8::Handle const val) { +static int ParseDocumentOrDocumentHandle( + v8::Isolate* isolate, + TRI_vocbase_t* vocbase, + CollectionNameResolver const* resolver, + std::shared_ptr& collection, + std::string& collectionName, + VPackBuilder& builder, + bool includeRev, + v8::Handle const val +) { v8::HandleScope scope(isolate); // try to extract the collection name, key, and revision from the object @@ -177,7 +200,7 @@ static int ParseDocumentOrDocumentHandle(v8::Isolate* isolate, // we read a collection name from the document id // check cross-collection requests if (collection != nullptr) { - if (!EqualCollection(resolver, collectionName, collection)) { + if (!EqualCollection(resolver, collectionName, collection.get())) { return TRI_ERROR_ARANGO_CROSS_COLLECTION_REQUEST; } } @@ -191,10 +214,7 @@ static int ParseDocumentOrDocumentHandle(v8::Isolate* isolate, if (ServerState::instance()->isCoordinator()) { ClusterInfo* ci = ClusterInfo::instance(); try { - std::shared_ptr col = - ci->getCollection(vocbase->name(), collectionName); - auto colCopy = col->clone(); - collection = colCopy.release(); + collection = ci->getCollection(vocbase->name(), collectionName); } catch (...) { return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND; } @@ -247,20 +267,19 @@ static int V8ToVPackNoKeyRevId(v8::Isolate* isolate, /// @brief get all cluster collections cloned, caller needs to cleanupb //////////////////////////////////////////////////////////////////////////////// -std::vector GetCollectionsCluster( - TRI_vocbase_t* vocbase) { - std::vector result; +std::vector> GetCollections( + TRI_vocbase_t& vocbase +) { + if (arangodb::ServerState::instance()->isCoordinator()) { + auto* ci = ClusterInfo::instance(); - std::vector> const collections = - ClusterInfo::instance()->getCollections(vocbase->name()); - - for (auto& collection : collections) { - std::unique_ptr c(collection->clone()); - result.emplace_back(c.get()); - c.release(); + return ci + ? ci->getCollections(vocbase.name()) + : std::vector>() + ; } - return result; + return vocbase.collections(false); } //////////////////////////////////////////////////////////////////////////////// @@ -297,14 +316,13 @@ static void ExistsVocbaseVPack( } TRI_vocbase_t* vocbase; - LogicalCollection const* col = nullptr; + arangodb::LogicalCollection* col = nullptr; if (useCollection) { // called as db.collection.exists() - col = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + col = UnwrapCollection(args.Holder()); - if (col == nullptr) { + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -317,18 +335,25 @@ static void ExistsVocbaseVPack( auto transactionContext = std::make_shared(*vocbase, true); VPackBuilder builder; + std::shared_ptr collection(col, [](arangodb::LogicalCollection*)->void {}); std::string collectionName; Result res; { VPackObjectBuilder guard(&builder); - res = ParseDocumentOrDocumentHandle( - isolate, vocbase, &(transactionContext->resolver()), col, - collectionName, builder, true, args[0]); - } - LocalCollectionGuard g( - useCollection ? nullptr : const_cast(col)); + res = ParseDocumentOrDocumentHandle( + isolate, + vocbase, + &(transactionContext->resolver()), + collection, + collectionName, + builder, + true, + args[0] + ); + col = collection.get(); + } if (!res.ok()) { TRI_V8_THROW_EXCEPTION(res); @@ -391,15 +416,13 @@ static void DocumentVocbaseCol( options.ignoreRevs = false; // Find collection and vocbase - std::string collectionName; - arangodb::LogicalCollection const* col - = TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); - if (col == nullptr) { + auto* col = UnwrapCollection(args.Holder()); + + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - collectionName = col->name(); - + auto& collectionName = col->name(); VPackBuilder searchBuilder; auto workOnOneDocument = [&](v8::Local const searchValue, bool isBabies) { @@ -474,7 +497,7 @@ static void DocumentVocbase( TRI_V8_THROW_EXCEPTION_USAGE("document()"); } - LogicalCollection const* col = nullptr; + arangodb::LogicalCollection* col = nullptr; auto& vocbase = GetContextVocBase(isolate); if (vocbase.isDropped()) { @@ -484,6 +507,7 @@ static void DocumentVocbase( auto transactionContext = std::make_shared(vocbase, true); VPackBuilder builder; + std::shared_ptr collection(col, [](arangodb::LogicalCollection*)->void {}); std::string collectionName; { @@ -492,20 +516,20 @@ static void DocumentVocbase( isolate, &vocbase, &(transactionContext->resolver()), - col, + collection, collectionName, builder, true, args[0] ); + col = collection.get(); + if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(res); } } - LocalCollectionGuard g(const_cast(col)); - TRI_ASSERT(col != nullptr); TRI_ASSERT(!collectionName.empty()); @@ -598,13 +622,13 @@ static void RemoveVocbaseCol(v8::FunctionCallbackInfo const& args) { } // Find collection and vocbase - arangodb::LogicalCollection const* col - = TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); - if (col == nullptr) { + auto* col = UnwrapCollection(args.Holder()); + + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string collectionName = col->name(); + auto& collectionName = col->name(); VPackBuilder searchBuilder; auto workOnOneDocument = [&](v8::Local const searchValue, bool isBabies) { @@ -714,7 +738,7 @@ static void RemoveVocbase(v8::FunctionCallbackInfo const& args) { } } - LogicalCollection const* col = nullptr; + arangodb::LogicalCollection* col = nullptr; auto& vocbase = GetContextVocBase(isolate); if (vocbase.isDropped()) { @@ -724,6 +748,7 @@ static void RemoveVocbase(v8::FunctionCallbackInfo const& args) { auto transactionContext = std::make_shared(vocbase, true); VPackBuilder builder; + std::shared_ptr collection(col, [](arangodb::LogicalCollection*)->void {}); std::string collectionName; { @@ -732,20 +757,20 @@ static void RemoveVocbase(v8::FunctionCallbackInfo const& args) { isolate, &vocbase, &(transactionContext->resolver()), - col, + collection, collectionName, builder, !options.ignoreRevs, args[0] ); + col = collection.get(); + if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(res); } } - LocalCollectionGuard g(const_cast(col)); - TRI_ASSERT(col != nullptr); TRI_ASSERT(!collectionName.empty()); @@ -809,18 +834,15 @@ static void JS_BinaryDocumentVocbaseCol( options.ignoreRevs = false; // Find collection and vocbase - std::string collectionName; - arangodb::LogicalCollection const* col = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* col = UnwrapCollection(args.Holder()); - if (col == nullptr) { + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } VPackBuilder searchBuilder; v8::Local const searchValue = args[0]; - collectionName = col->name(); + auto& collectionName = col->name(); { VPackObjectBuilder guard(&searchBuilder); @@ -838,7 +860,7 @@ static void JS_BinaryDocumentVocbaseCol( VPackSlice search = searchBuilder.slice(); auto transactionContext = - std::make_shared(col->vocbase(), true); + std::make_shared(col->vocbase(), true); SingleCollectionTransaction trx(transactionContext, collectionName, AccessMode::Type::READ); @@ -917,10 +939,9 @@ static void JS_DropVocbaseCol(v8::FunctionCallbackInfo const& args) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND); } - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -947,8 +968,9 @@ static void JS_DropVocbaseCol(v8::FunctionCallbackInfo const& args) { } } - auto res = - methods::Collections::drop(&vocbase, collection, allowDropSystem, timeout); + auto res = methods::Collections::drop( + &vocbase, collection, allowDropSystem, timeout + ); if (res.fail()) { TRI_V8_THROW_EXCEPTION(res); @@ -980,11 +1002,9 @@ static void JS_FiguresVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -999,7 +1019,7 @@ static void JS_FiguresVocbaseCol( TRI_V8_THROW_EXCEPTION(res); } - std::shared_ptr builder = collection->figures(); + auto builder = collection->figures(); trx.finish(TRI_ERROR_NO_ERROR); @@ -1023,15 +1043,13 @@ static void JS_SetTheLeader(v8::FunctionCallbackInfo const& args) { } if (ServerState::instance()->isDBServer()) { - arangodb::LogicalCollection const* v8Collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* v8Collection = UnwrapCollection(args.Holder()); - if (v8Collection == nullptr) { + if (!v8Collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string collectionName = v8Collection->name(); + auto& collectionName = v8Collection->name(); auto collection = v8Collection->vocbase().lookupCollection(collectionName); if (collection == nullptr) { @@ -1077,15 +1095,13 @@ static void JS_GetLeader(v8::FunctionCallbackInfo const& args) { std::string theLeader; if (ServerState::instance()->isDBServer()) { - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string collectionName = collection->name(); + auto& collectionName = collection->name(); auto realCollection = collection->vocbase().lookupCollection(collectionName); @@ -1121,15 +1137,13 @@ static void JS_RemoveFollower(v8::FunctionCallbackInfo const& args) { ServerID const serverId = TRI_ObjectToString(args[0]); if (ServerState::instance()->isDBServer()) { - arangodb::LogicalCollection const* v8Collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* v8Collection = UnwrapCollection(args.Holder()); - if (v8Collection == nullptr) { + if (!v8Collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string collectionName = v8Collection->name(); + auto& collectionName = v8Collection->name(); auto collection = v8Collection->vocbase().lookupCollection(collectionName); if (collection == nullptr) { @@ -1160,15 +1174,13 @@ static void JS_GetFollowers(v8::FunctionCallbackInfo const& args) { v8::Handle list = v8::Array::New(isolate); if (ServerState::instance()->isDBServer()) { - arangodb::LogicalCollection const* v8Collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* v8Collection = UnwrapCollection(args.Holder()); - if (v8Collection == nullptr) { + if (!v8Collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string collectionName = v8Collection->name(); + auto& collectionName = v8Collection->name(); auto collection = v8Collection->vocbase().lookupCollection(collectionName); if (collection == nullptr) { @@ -1202,11 +1214,9 @@ static void JS_LoadVocbaseCol(v8::FunctionCallbackInfo const& args) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND); } - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -1228,15 +1238,13 @@ static void JS_NameVocbaseCol(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string const collectionName(collection->name()); + auto& collectionName = collection->name(); if (collectionName.empty()) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND); @@ -1254,15 +1262,13 @@ static void JS_PathVocbaseCol(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string const path(collection->getPhysical()->path()); + std::string path(collection->getPhysical()->path()); v8::Handle result = TRI_V8_STD_STRING(isolate, path); TRI_V8_RETURN(result); @@ -1278,11 +1284,9 @@ static void JS_PlanIdVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -1303,9 +1307,9 @@ static void JS_PropertiesVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - LogicalCollection* consoleColl = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); - if (consoleColl == nullptr) { + auto* consoleColl = UnwrapCollection(args.Holder()); + + if (!consoleColl) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -1321,10 +1325,15 @@ static void JS_PropertiesVocbaseCol( TRI_V8_THROW_EXCEPTION(res); } } - Result res = methods::Collections::updateProperties(consoleColl, builder.slice()); + + auto res = methods::Collections::updateProperties( + consoleColl, builder.slice() + ); + if (res.fail() && ServerState::instance()->isCoordinator()) { TRI_V8_THROW_EXCEPTION(res); } + // TODO Review // TODO API compatibility, for now we ignore if persisting fails... } @@ -1336,9 +1345,11 @@ static void JS_PropertiesVocbaseCol( methods::Collections::lookup( &(consoleColl->vocbase()), consoleColl->name(), - [&](LogicalCollection& coll)->void { + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + VPackObjectBuilder object(&builder, true); - methods::Collections::Context ctxt(coll.vocbase(), coll); + methods::Collections::Context ctxt(coll->vocbase(), *coll); Result res = methods::Collections::properties(ctxt, builder); if (res.fail()) { @@ -1384,13 +1395,14 @@ static void JS_RenameVocbaseCol( PREVENT_EMBEDDED_TRANSACTION(); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); - if (collection == nullptr) { + auto* collection = UnwrapCollection(args.Holder()); + + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - Result res = methods::Collections::rename(collection, name, doOverride); + auto res = methods::Collections::rename(collection, name, doOverride); + if (res.fail()) { TRI_V8_THROW_EXCEPTION(res); } @@ -1526,16 +1538,17 @@ static void ModifyVocbaseCol(TRI_voc_document_operation_e operation, } // Find collection and vocbase - arangodb::LogicalCollection const* col = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); - if (col == nullptr) { + auto* col = UnwrapCollection(args.Holder()); + + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - std::string collectionName = col->name(); + auto& collectionName = col->name(); VPackBuilder updateBuilder; auto workOnOneSearchVal = [&](v8::Local const searchVal, bool isBabies) { std::string collName; + if (!ExtractDocumentHandle(isolate, searchVal, collName, updateBuilder, !options.isRestore)) { // If this is no restore, then we must extract the _rev from the @@ -1547,6 +1560,7 @@ static void ModifyVocbaseCol(TRI_voc_document_operation_e operation, return; } } + if (!collName.empty() && collName != collectionName) { THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_CROSS_COLLECTION_REQUEST); } @@ -1710,7 +1724,8 @@ static void ModifyVocbase(TRI_voc_document_operation_e operation, parseReplaceAndUpdateOptions(isolate, args, options, operation); } - LogicalCollection const* col = nullptr; + arangodb::LogicalCollection* col = nullptr; + std::shared_ptr collection(col, [](arangodb::LogicalCollection*)->void {}); std::string collectionName; auto& vocbase = GetContextVocBase(isolate); auto transactionContext = @@ -1729,21 +1744,19 @@ static void ModifyVocbase(TRI_voc_document_operation_e operation, isolate, &vocbase, &(transactionContext->resolver()), - col, + collection, collectionName, updateBuilder, !options.ignoreRevs, args[0] ); + col = collection.get(); if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION(res); } } - // We need to free the collection object in the end - LocalCollectionGuard g(const_cast(col)); - SingleCollectionTransaction trx(transactionContext, collectionName, AccessMode::Type::WRITE); trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION); @@ -1968,10 +1981,9 @@ static void JS_RevisionVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -1989,23 +2001,6 @@ static void JS_RevisionVocbaseCol( TRI_V8_TRY_CATCH_END } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief retrieves a collection from a V8 argument -//////////////////////////////////////////////////////////////////////////////// - -static arangodb::LogicalCollection* GetCollectionFromArgument( - TRI_vocbase_t* vocbase, v8::Handle const val) { - // number - if (val->IsNumber() || val->IsNumberObject()) { - uint64_t cid = TRI_ObjectToUInt64(val, true); - - return vocbase->lookupCollection(cid).get(); - } - - return vocbase->lookupCollection(TRI_ObjectToString(val)).get(); -} - //////////////////////////////////////////////////////////////////////////////// /// @brief inserts a document, using VPack //////////////////////////////////////////////////////////////////////////////// @@ -2015,16 +2010,13 @@ static void InsertVocbaseCol(v8::Isolate* isolate, std::string* attachment) { v8::HandleScope scope(isolate); - auto collection = TRI_UnwrapClass( - args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - bool const isEdgeCollection = - ((TRI_col_type_e)collection->type() == TRI_COL_TYPE_EDGE); - + auto isEdgeCollection = (collection->type() == TRI_COL_TYPE_EDGE); uint32_t const argLength = args.Length(); // Position of and @@ -2152,7 +2144,7 @@ static void InsertVocbaseCol(v8::Isolate* isolate, // load collection auto transactionContext = - std::make_shared(collection->vocbase(), true); + std::make_shared(collection->vocbase(), true); SingleCollectionTransaction trx( transactionContext, *collection, AccessMode::Type::WRITE ); @@ -2167,8 +2159,7 @@ static void InsertVocbaseCol(v8::Isolate* isolate, TRI_V8_THROW_EXCEPTION(res); } - OperationResult result = - trx.insert(collection->name(), builder.slice(), options); + auto result = trx.insert(collection->name(), builder.slice(), options); res = trx.finish(result.result); @@ -2232,10 +2223,9 @@ static void JS_GloballyUniqueIdVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2254,10 +2244,9 @@ static void JS_StatusVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2265,10 +2254,9 @@ static void JS_StatusVocbaseCol( auto& databaseName = collection->vocbase().name(); try { - std::shared_ptr const ci = - ClusterInfo::instance()->getCollection( - databaseName, std::to_string(collection->id()) - ); + auto ci = ClusterInfo::instance()->getCollection( + databaseName, std::to_string(collection->id()) + ); TRI_V8_RETURN(v8::Number::New(isolate, (int)ci->status())); } catch (...) { TRI_V8_RETURN(v8::Number::New(isolate, (int)TRI_VOC_COL_STATUS_DELETED)); @@ -2276,7 +2264,7 @@ static void JS_StatusVocbaseCol( } // intentionally falls through - TRI_vocbase_col_status_e status = collection->status(); + auto status = collection->status(); TRI_V8_RETURN(v8::Number::New(isolate, (int)status)); TRI_V8_TRY_CATCH_END @@ -2295,10 +2283,9 @@ static void JS_TruncateVocbaseCol( opOptions.waitForSync = ExtractBooleanArgument(args, 1); ExtractStringArgument(args, 2, opOptions.isSynchronousReplicationFrom); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2314,7 +2301,8 @@ static void JS_TruncateVocbaseCol( TRI_V8_THROW_EXCEPTION(res); } - OperationResult result = trx.truncate(collection->name(), opOptions); + auto result = trx.truncate(collection->name(), opOptions); + res = trx.finish(result.result); if (result.fail()) { @@ -2337,10 +2325,9 @@ static void JS_TypeVocbaseCol(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2348,18 +2335,17 @@ static void JS_TypeVocbaseCol(v8::FunctionCallbackInfo const& args) { auto& databaseName = collection->vocbase().name(); try { - std::shared_ptr const ci = - ClusterInfo::instance()->getCollection( - databaseName, std::to_string(collection->id()) - ); + auto ci = ClusterInfo::instance()->getCollection( + databaseName, std::to_string(collection->id()) + ); TRI_V8_RETURN(v8::Number::New(isolate, (int)ci->type())); } catch (...) { - TRI_V8_RETURN(v8::Number::New(isolate, (int)collection->type())); + TRI_V8_RETURN(v8::Number::New(isolate, (int)(collection->type()))); } } // intentionally falls through - TRI_col_type_e type = collection->type(); + auto type = collection->type(); TRI_V8_RETURN(v8::Number::New(isolate, (int)type)); TRI_V8_TRY_CATCH_END @@ -2375,10 +2361,9 @@ static void JS_UnloadVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2401,10 +2386,9 @@ static void JS_VersionVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2433,23 +2417,7 @@ static void JS_CollectionVocbase( } v8::Handle val = args[0]; - std::string const name = TRI_ObjectToString(val); - arangodb::LogicalCollection const* collection = nullptr; - - if (ServerState::instance()->isCoordinator()) { - try { - std::shared_ptr const ci = - ClusterInfo::instance()->getCollection(vocbase.name(), name); - auto colCopy = ci->clone(); - - collection = colCopy.release(); - } catch (...) { - // not found - TRI_V8_RETURN_NULL(); - } - } else { - collection = GetCollectionFromArgument(&vocbase, val); - } + auto collection = GetCollectionFromArgument(vocbase, val); if (collection == nullptr) { TRI_V8_RETURN_NULL(); @@ -2458,8 +2426,10 @@ static void JS_CollectionVocbase( // check authentication after ensuring the collection exists if (ExecContext::CURRENT != nullptr && !ExecContext::CURRENT->canUseCollection(collection->name(), auth::Level::RO)) { - TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, - std::string("No access to collection '") + name + "'"); + TRI_V8_THROW_EXCEPTION_MESSAGE( + TRI_ERROR_FORBIDDEN, + std::string("No access to collection '") + TRI_ObjectToString(val) + "'" + ); } v8::Handle result = WrapCollection(isolate, collection); @@ -2474,7 +2444,6 @@ static void JS_CollectionVocbase( //////////////////////////////////////////////////////////////////////////////// /// @brief was docuBlock collectionDatabaseNameAll //////////////////////////////////////////////////////////////////////////////// - static void JS_CollectionsVocbase( v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); @@ -2485,34 +2454,18 @@ static void JS_CollectionsVocbase( TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND); } - std::vector colls; + auto colls = GetCollections(vocbase); - // clean memory - std::function cleanup; - - // if we are a coordinator, we need to fetch the collection info from the - // agency - if (ServerState::instance()->isCoordinator()) { - cleanup = [&colls]() { - for (auto& it : colls) { - if (it != nullptr) { - delete it; - } - } - }; - colls = GetCollectionsCluster(&vocbase); - } else { - // no cleanup needed on single server / dbserver - cleanup = []() {}; - colls = vocbase.collections(false); - } - - // make sure memory is cleaned up - TRI_DEFER(cleanup()); - - std::sort(colls.begin(), colls.end(), [](LogicalCollection* lhs, LogicalCollection* rhs) -> bool { - return StringUtils::tolower(lhs->name()) < StringUtils::tolower(rhs->name()); - }); + std::sort( + colls.begin(), + colls.end(), + []( + std::shared_ptr const& lhs, + std::shared_ptr const& rhs + )->bool { + return arangodb::basics::StringUtils::tolower(lhs->name()) < arangodb::basics::StringUtils::tolower(rhs->name()); + } + ); bool error = false; @@ -2537,8 +2490,7 @@ static void JS_CollectionsVocbase( error = true; break; } - // avoid duplicate deletion - collection = nullptr; + result->Set(static_cast(x++), c); } @@ -2667,10 +2619,9 @@ static void JS_CountVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* col = - TRI_UnwrapClass(args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* col = UnwrapCollection(args.Holder()); - if (col == nullptr) { + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -2683,7 +2634,7 @@ static void JS_CountVocbaseCol( details = TRI_ObjectToBoolean(args[0]); } - std::string collectionName(col->name()); + auto& collectionName = col->name(); SingleCollectionTransaction trx( transaction::V8Context::Create(col->vocbase(), true), collectionName, @@ -2728,15 +2679,14 @@ static void JS_WarmupVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection =UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - auto res = methods::Collections::warmup(collection->vocbase(), *collection); + auto res = + arangodb::methods::Collections::warmup(collection->vocbase(), *collection); if (res.fail()) { TRI_V8_THROW_EXCEPTION(res); diff --git a/arangod/V8Server/v8-collection.h b/arangod/V8Server/v8-collection.h index 037ec35036..14874ff4ad 100644 --- a/arangod/V8Server/v8-collection.h +++ b/arangod/V8Server/v8-collection.h @@ -42,9 +42,9 @@ void ReleaseCollection(arangodb::LogicalCollection const* collection); //////////////////////////////////////////////////////////////////////////////// /// @brief return all collections in a cluster //////////////////////////////////////////////////////////////////////////////// - -std::vector GetCollectionsCluster( - TRI_vocbase_t* vocbase); +std::vector> GetCollections( + TRI_vocbase_t& vocbase +); /////////////////////////////////////////////////////////////////////////////// /// @brief check if a name belongs to a collection @@ -60,13 +60,22 @@ bool EqualCollection(arangodb::CollectionNameResolver const* resolver, /// be freed. If it is not a local collection (coordinator case), then delete /// will be called when the V8 object is garbage collected. //////////////////////////////////////////////////////////////////////////////// - v8::Handle WrapCollection( - v8::Isolate* isolate, arangodb::LogicalCollection const* collection); + v8::Isolate* isolate, + std::shared_ptr const& collection +); void TRI_InitV8Collections(v8::Handle context, TRI_vocbase_t* vocbase, TRI_v8_global_t* v8g, v8::Isolate* isolate, v8::Handle ArangoDBNS); -#endif +//////////////////////////////////////////////////////////////////////////////// +/// @brief unwrap a LogicalCollection wrapped via WrapCollection(...) +/// @return collection or nullptr on failure +//////////////////////////////////////////////////////////////////////////////// +arangodb::LogicalCollection* UnwrapCollection( + v8::Local const& holder +); + +#endif \ No newline at end of file diff --git a/arangod/V8Server/v8-query.cpp b/arangod/V8Server/v8-query.cpp index 6962bd43c1..81e8995826 100644 --- a/arangod/V8Server/v8-query.cpp +++ b/arangod/V8Server/v8-query.cpp @@ -36,6 +36,7 @@ #include "V8/v8-conv.h" #include "V8/v8-utils.h" #include "V8/v8-vpack.h" +#include "V8Server/v8-collection.h" #include "V8Server/v8-externals.h" #include "V8Server/v8-vocbase.h" #include "V8Server/v8-vocindex.h" @@ -132,19 +133,16 @@ static void EdgesQuery(TRI_edge_direction_e direction, THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid edge index direction"); }; - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } - - if (collection->type() != TRI_COL_TYPE_EDGE) { + + if (TRI_COL_TYPE_EDGE != collection->type()) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_TYPE_INVALID); } - auto addOne = [](v8::Isolate* isolate, VPackBuilder* builder, v8::Handle const val) { if (val->IsString() || val->IsStringObject()) { builder->add(VPackValue(TRI_ObjectToString(val))); @@ -189,8 +187,7 @@ static void EdgesQuery(TRI_edge_direction_e direction, } std::string const queryString = "FOR doc IN @@collection " + filter + " RETURN doc"; - - aql::QueryResultV8 queryResult = AqlQuery(isolate, collection, queryString, bindVars); + auto queryResult = AqlQuery(isolate, collection, queryString, bindVars); if (!queryResult.result.IsEmpty()) { TRI_V8_RETURN(queryResult.result); @@ -207,18 +204,16 @@ static void JS_AllQuery(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } std::string const collectionName(collection->name()); - std::shared_ptr transactionContext = - transaction::V8Context::Create(collection->vocbase(), true); + auto transactionContext = + transaction::V8Context::Create(collection->vocbase(), true); SingleCollectionTransaction trx( transactionContext, *collection, AccessMode::Type::READ ); @@ -289,17 +284,16 @@ static void JS_AnyQuery(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* col = TRI_UnwrapClass( - args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* col = UnwrapCollection(args.Holder()); - if (col == nullptr) { + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } std::string const collectionName(col->name()); - std::shared_ptr transactionContext = - transaction::V8Context::Create(col->vocbase(), true); + auto transactionContext = + transaction::V8Context::Create(col->vocbase(), true); SingleCollectionTransaction trx( transactionContext, *col, AccessMode::Type::READ ); @@ -345,10 +339,9 @@ static void JS_ChecksumCollection( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* col = TRI_UnwrapClass( - args.Holder(), WRP_VOCBASE_COL_TYPE); + auto* col = UnwrapCollection(args.Holder()); - if (col == nullptr) { + if (!col) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -364,7 +357,8 @@ static void JS_ChecksumCollection( } } - ChecksumResult result = col->checksum(withRevisions, withData); + auto result = col->checksum(withRevisions, withData); + if (!result.ok()) { TRI_V8_THROW_EXCEPTION(result); } @@ -414,11 +408,9 @@ static void JS_LookupByKeys(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -438,13 +430,15 @@ static void JS_LookupByKeys(v8::FunctionCallbackInfo const& args) { } bindVars->add(VPackValue("keys")); - arangodb::aql::BindParameters::stripCollectionNames(keys.slice(), collection->name(), *bindVars.get()); + arangodb::aql::BindParameters::stripCollectionNames( + keys.slice(), collection->name(), *bindVars.get() + ); bindVars->close(); std::string const queryString( "FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc"); - aql::QueryResultV8 queryResult = AqlQuery(isolate, collection, queryString, bindVars); + auto queryResult = AqlQuery(isolate, collection, queryString, bindVars); v8::Handle result = v8::Object::New(isolate); if (!queryResult.result.IsEmpty()) { @@ -463,11 +457,9 @@ static void JS_RemoveByKeys(v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection const* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -489,7 +481,7 @@ static void JS_RemoveByKeys(v8::FunctionCallbackInfo const& args) { std::string const queryString( "FOR key IN @keys REMOVE key IN @@collection OPTIONS { ignoreErrors: true }"); - aql::QueryResultV8 queryResult = AqlQuery(isolate, collection, queryString, bindVars); + auto queryResult = AqlQuery(isolate, collection, queryString, bindVars); size_t ignored = 0; size_t removed = 0; diff --git a/arangod/V8Server/v8-views.cpp b/arangod/V8Server/v8-views.cpp index 25fd3abfea..7be8742328 100644 --- a/arangod/V8Server/v8-views.cpp +++ b/arangod/V8Server/v8-views.cpp @@ -59,58 +59,45 @@ bool canUse( ); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief retrieves a view from a V8 argument +//////////////////////////////////////////////////////////////////////////////// +std::shared_ptr GetViewFromArgument( + TRI_vocbase_t& vocbase, + v8::Handle const val +) { + // number + if (val->IsNumber() || val->IsNumberObject()) { + uint64_t id = TRI_ObjectToUInt64(val, true); + + return vocbase.lookupView(id); + } + + return vocbase.lookupView(TRI_ObjectToString(val)); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief unwraps a LogicalView wrapped via WrapView(...) +/// @return collection or nullptr on failure +//////////////////////////////////////////////////////////////////////////////// +arangodb::LogicalView* UnwrapView( + v8::Local const& holder +) { + return TRI_UnwrapClass(holder, WRP_VOCBASE_VIEW_TYPE); +} + } using namespace arangodb; using namespace arangodb::basics; -static std::shared_ptr GetViewFromArgument( - TRI_vocbase_t* vocbase, v8::Handle const val) { - // number - if (val->IsNumber() || val->IsNumberObject()) { - uint64_t id = TRI_ObjectToUInt64(val, true); - return vocbase->lookupView(id); - } - - return vocbase->lookupView(TRI_ObjectToString(val)); -} - -/// @brief weak reference callback for views -static void WeakViewCallback( - const v8::WeakCallbackInfo>& data) { - auto isolate = data.GetIsolate(); - auto persistent = data.GetParameter(); - auto myView = v8::Local::New(isolate, *persistent); - auto v = static_cast*>(myView->Value()); - - TRI_ASSERT(v != nullptr); - LogicalView* view = v->get(); - TRI_ASSERT(view != nullptr); - - TRI_GET_GLOBALS(); - - v8g->decreaseActiveExternals(); - - // decrease the reference-counter for the database - TRI_ASSERT(!view->vocbase().isDangling()); - -// find the persistent handle -#if ARANGODB_ENABLE_MAINTAINER_MODE - auto const& it = v8g->JSViews.find(view); - TRI_ASSERT(it != v8g->JSViews.end()); -#endif - - // dispose and clear the persistent handle - v8g->JSViews[view].Reset(); - v8g->JSViews.erase(view); - - view->vocbase().release(); - delete v; // delete the shared_ptr on the heap -} - +//////////////////////////////////////////////////////////////////////////////// /// @brief wraps a LogicalView -v8::Handle WrapView(v8::Isolate* isolate, - std::shared_ptr view) { +//////////////////////////////////////////////////////////////////////////////// +v8::Handle WrapView( + v8::Isolate* isolate, + std::shared_ptr const& view +) { v8::EscapableHandleScope scope(isolate); TRI_GET_GLOBALS(); @@ -118,40 +105,32 @@ v8::Handle WrapView(v8::Isolate* isolate, v8::Handle result = VocbaseViewTempl->NewInstance(); if (!result.IsEmpty()) { - // create a new shared_ptr on the heap - result->SetInternalField(SLOT_CLASS_TYPE, - v8::Integer::New(isolate, WRP_VOCBASE_VIEW_TYPE)); + auto* ptr = view.get(); + auto itr = v8g->JSDatasources.emplace( + std::piecewise_construct, + std::forward_as_tuple(view.get()), + std::forward_as_tuple( + isolate, + view, + [ptr]()->void { // FIXME TODO find a way to move this callback code into DataSourcePersistent + TRI_ASSERT(!ptr->vocbase().isDangling()); + ptr->vocbase().release(); // decrease the reference-counter for the database + } + ) + ); + auto& entry = itr.first->second; - auto const& it = v8g->JSViews.find(view.get()); - - if (it == v8g->JSViews.end()) { - // increase the reference-counter for the database - TRI_ASSERT(!view->vocbase().isDangling()); - view->vocbase().forceUse(); - - try { - auto v = new std::shared_ptr(view); - auto externalView = v8::External::New(isolate, v); - - result->SetInternalField(SLOT_CLASS, v8::External::New(isolate, v)); - - result->SetInternalField(SLOT_EXTERNAL, externalView); - - v8g->JSViews[view.get()].Reset(isolate, externalView); - v8g->JSViews[view.get()].SetWeak(&v8g->JSViews[view.get()], - WeakViewCallback, - v8::WeakCallbackType::kFinalizer); - v8g->increaseActiveExternals(); - } catch (...) { - view->vocbase().release(); - throw; - } - } else { - auto myView = v8::Local::New(isolate, it->second); - result->SetInternalField(SLOT_CLASS, - v8::External::New(isolate, myView->Value())); - result->SetInternalField(SLOT_EXTERNAL, myView); + if (itr.second) { // FIXME TODO find a way to move this code into DataSourcePersistent + TRI_ASSERT(!ptr->vocbase().isDangling()); + ptr->vocbase().forceUse(); // increase the reference-counter for the database } + + result->SetInternalField( + SLOT_CLASS_TYPE, v8::Integer::New(isolate, WRP_VOCBASE_VIEW_TYPE) + ); + result->SetInternalField(SLOT_CLASS, entry.get()); + result->SetInternalField(SLOT_EXTERNAL, entry.get()); + TRI_GET_GLOBAL_STRING(_IdKey); TRI_GET_GLOBAL_STRING(_DbNameKey); result->ForceSet(_IdKey, @@ -306,16 +285,12 @@ static void JS_DropViewVocbaseObj( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - std::shared_ptr* v = - TRI_UnwrapClass>( - args.Holder(), WRP_VOCBASE_VIEW_TYPE); + auto* view = UnwrapView(args.Holder()); - if (v == nullptr || v->get() == nullptr) { + if (!view) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract view"); } - LogicalView* view = v->get(); - PREVENT_EMBEDDED_TRANSACTION(); bool allowDropSystem = false; @@ -369,7 +344,7 @@ static void JS_ViewVocbase(v8::FunctionCallbackInfo const& args) { } v8::Handle val = args[0]; - auto view = GetViewFromArgument(&vocbase, val); + auto view = GetViewFromArgument(vocbase, val); if (view == nullptr) { TRI_V8_RETURN_NULL(); @@ -488,16 +463,12 @@ static void JS_NameViewVocbase( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - std::shared_ptr* v = - TRI_UnwrapClass>( - args.Holder(), WRP_VOCBASE_VIEW_TYPE); + auto* view = UnwrapView(args.Holder()); - if (v == nullptr || v->get() == nullptr) { + if (!view) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract view"); } - LogicalView* view = v->get(); - // ........................................................................... // end of parameter parsing // ........................................................................... @@ -524,19 +495,15 @@ static void JS_PropertiesViewVocbase( ) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - auto* viewPtr = TRI_UnwrapClass>( - args.Holder(), WRP_VOCBASE_VIEW_TYPE - ); + auto* viewPtr = UnwrapView(args.Holder()); - if (!viewPtr || !*viewPtr) { + if (!viewPtr) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract view"); } - auto view = *viewPtr; - // In the cluster the view object might contain outdated properties, // which will break tests. We need an extra lookup for each operation. - arangodb::CollectionNameResolver resolver(view->vocbase()); + arangodb::CollectionNameResolver resolver(viewPtr->vocbase()); // check if we want to change some parameters if (args.Length() > 0 && args[0]->IsObject()) { @@ -564,8 +531,8 @@ static void JS_PropertiesViewVocbase( // end of parameter parsing // ........................................................................... - if (!canUse(auth::Level::RW, view->vocbase())) { // as per https://github.com/arangodb/backlog/issues/459 - //if (!canUse(auth::Level::RW, view->vocbase(), &view->name())) { // check auth after ensuring that the view exists + if (!canUse(auth::Level::RW, viewPtr->vocbase())) { // as per https://github.com/arangodb/backlog/issues/459 + //if (!canUse(auth::Level::RW, viewPtr->vocbase(), &viewPtr->name())) { // check auth after ensuring that the view exists TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_FORBIDDEN, "insufficient rights to modify view"); } @@ -575,7 +542,7 @@ static void JS_PropertiesViewVocbase( builderCurrent.openObject(); - auto resCurrent = view->toVelocyPack(builderCurrent, true, false); + auto resCurrent = viewPtr->toVelocyPack(builderCurrent, true, false); if (!resCurrent.ok()) { TRI_V8_THROW_EXCEPTION(resCurrent); @@ -586,7 +553,7 @@ static void JS_PropertiesViewVocbase( DatabaseFeature >("Database")->forceSyncProperties(); - view = resolver.getView(view->id()); // ensure have the latest definition + auto view = resolver.getView(viewPtr->id()); // ensure have the latest definition if (!view) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND); @@ -599,7 +566,7 @@ static void JS_PropertiesViewVocbase( } } - view = resolver.getView(view->id()); + auto view = resolver.getView(viewPtr->id()); if (!view) { TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND); @@ -651,16 +618,12 @@ static void JS_RenameViewVocbase( TRI_V8_THROW_EXCEPTION_PARAMETER(" must be non-empty"); } - std::shared_ptr* v = - TRI_UnwrapClass>( - args.Holder(), WRP_VOCBASE_VIEW_TYPE); + auto* view = UnwrapView(args.Holder()); - if (v == nullptr || v->get() == nullptr) { + if (!view) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract view"); } - std::shared_ptr view = *v; - PREVENT_EMBEDDED_TRANSACTION(); // ........................................................................... @@ -687,7 +650,11 @@ static void JS_RenameViewVocbase( TRI_V8_THROW_EXCEPTION(TRI_ERROR_INTERNAL); // skip view } - int res = view->vocbase().renameView(view, name); + // need to get the sharedPtr from the vocbase + arangodb::CollectionNameResolver resolver(view->vocbase()); + auto viewPtr = resolver.getView(view->id()); + + int res = view->vocbase().renameView(viewPtr, name); if (res != TRI_ERROR_NO_ERROR) { TRI_V8_THROW_EXCEPTION_MESSAGE(res, "cannot rename view"); @@ -702,17 +669,12 @@ static void JS_TypeViewVocbase( v8::FunctionCallbackInfo const& args) { TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); + auto* view = UnwrapView(args.Holder()); - std::shared_ptr* v = - TRI_UnwrapClass>( - args.Holder(), WRP_VOCBASE_VIEW_TYPE); - - if (v == nullptr || v->get() == nullptr) { + if (!view) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract view"); } - LogicalView* view = v->get(); - // ........................................................................... // end of parameter parsing // ........................................................................... diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 32af480173..546c952540 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -1329,29 +1329,26 @@ static void MapGetVocBase(v8::Local const name, cacheObject = globals->Get(_DbCacheKey)->ToObject(); } - arangodb::LogicalCollection* collection = nullptr; - if (!cacheObject.IsEmpty() && cacheObject->HasRealNamedProperty(cacheName)) { v8::Handle value = cacheObject->GetRealNamedProperty(cacheName)->ToObject(); - - collection = TRI_UnwrapClass( - value, WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(value); // check if the collection is from the same database - if (collection != nullptr && &(collection->vocbase()) == &vocbase) { + if (collection && &(collection->vocbase()) == &vocbase) { // we cannot use collection->getStatusLocked() here, because we // have no idea who is calling us (db[...]). The problem is that // if we are called from within a JavaScript transaction, the // caller may have already acquired the collection's status lock // with that transaction. if we now lock again, we may deadlock! - TRI_vocbase_col_status_e status = collection->status(); - TRI_voc_cid_t cid = collection->id(); - uint32_t internalVersion = collection->internalVersion(); + auto status = collection->status(); + auto cid = collection->id(); + auto internalVersion = collection->internalVersion(); // check if the collection is still alive - if (status != TRI_VOC_COL_STATUS_DELETED && cid > 0 && - collection->isLocal()) { + if (status != TRI_VOC_COL_STATUS_DELETED + && cid > 0 + && collection->isLocal()) { TRI_GET_GLOBAL_STRING(_IdKey); TRI_GET_GLOBAL_STRING(VersionKeyHidden); if (value->Has(_IdKey)) { @@ -1381,15 +1378,16 @@ static void MapGetVocBase(v8::Local const name, cacheObject->Delete(cacheName); } + std::shared_ptr collection; + try { if (ServerState::instance()->isCoordinator()) { - auto ci = ClusterInfo::instance()->getCollection( - vocbase.name(), std::string(key) - ); - auto colCopy = ci->clone(); - collection = colCopy.release(); // will be delete on garbage collection + auto* ci = arangodb::ClusterInfo::instance(); + + collection = ci + ? ci->getCollection(vocbase.name(), std::string(key)) : nullptr; } else { - collection = vocbase.lookupCollection(std::string(key)).get(); + collection = vocbase.lookupCollection(std::string(key)); } } catch (...) { // do not propagate exception from here @@ -1407,10 +1405,6 @@ static void MapGetVocBase(v8::Local const name, v8::Handle result = WrapCollection(isolate, collection); if (result.IsEmpty()) { - if (ServerState::instance()->isCoordinator()) { - // TODO Do we need this? - delete collection; - } TRI_V8_RETURN_UNDEFINED(); } diff --git a/arangod/V8Server/v8-vocindex.cpp b/arangod/V8Server/v8-vocindex.cpp index 2e911da4c4..1db700a068 100644 --- a/arangod/V8Server/v8-vocindex.cpp +++ b/arangod/V8Server/v8-vocindex.cpp @@ -68,11 +68,9 @@ static void EnsureIndex(v8::FunctionCallbackInfo const& args, v8::Isolate* isolate = args.GetIsolate(); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -86,11 +84,14 @@ static void EnsureIndex(v8::FunctionCallbackInfo const& args, TRI_V8ToVPackSimple(isolate, builder, args[0]); VPackBuilder output; - Result res = methods::Indexes::ensureIndex(collection, builder.slice(), - create, output); + auto res = methods::Indexes::ensureIndex( + collection, builder.slice(), create, output + ); + if (res.fail()) { TRI_V8_THROW_EXCEPTION(res); } + v8::Handle result = TRI_VPackToV8(isolate, output.slice()); TRI_V8_RETURN(result); } @@ -134,11 +135,9 @@ static void JS_DropIndexVocbaseCol( PREVENT_EMBEDDED_TRANSACTION(); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } @@ -149,10 +148,12 @@ static void JS_DropIndexVocbaseCol( VPackBuilder builder; TRI_V8ToVPackSimple(isolate, builder, args[0]); - Result res = methods::Indexes::drop(collection, builder.slice()); + auto res = methods::Indexes::drop(collection, builder.slice()); + if (res.ok()) { TRI_V8_RETURN_TRUE(); } + TRI_V8_RETURN_FALSE(); TRI_V8_TRY_CATCH_END } @@ -166,25 +167,27 @@ static void JS_GetIndexesVocbaseCol( TRI_V8_TRY_CATCH_BEGIN(isolate); v8::HandleScope scope(isolate); - arangodb::LogicalCollection* collection = - TRI_UnwrapClass(args.Holder(), - WRP_VOCBASE_COL_TYPE); + auto* collection = UnwrapCollection(args.Holder()); - if (collection == nullptr) { + if (!collection) { TRI_V8_THROW_EXCEPTION_INTERNAL("cannot extract collection"); } auto flags = Index::makeFlags(Index::Serialize::Estimates); + if (args.Length() > 0 && TRI_ObjectToBoolean(args[0])) { flags = Index::makeFlags(Index::Serialize::Estimates, Index::Serialize::Figures); } + bool withLinks = false; + if (args.Length() > 1) { withLinks = TRI_ObjectToBoolean(args[1]); } VPackBuilder output; - Result res = methods::Indexes::getAll(collection, flags, withLinks, output); + auto res = methods::Indexes::getAll(collection, flags, withLinks, output); + if (res.fail()) { TRI_V8_THROW_EXCEPTION(res); } @@ -266,15 +269,9 @@ static void CreateVocBase(v8::FunctionCallbackInfo const& args, propSlice, createWaitsForSyncReplication, enforceReplicationFactor, - [&isolate, &result](LogicalCollection& coll)->void { - if (ServerState::instance()->isCoordinator()) { - std::unique_ptr cc = coll.clone(); - - result = WrapCollection(isolate, cc.get()); - cc.release(); - } else { - result = WrapCollection(isolate, &coll); - } + [&isolate, &result](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + result = WrapCollection(isolate, coll); } ); diff --git a/arangod/VocBase/Methods/Collections.cpp b/arangod/VocBase/Methods/Collections.cpp index cf6ff65bd7..eaa2e47d1b 100644 --- a/arangod/VocBase/Methods/Collections.cpp +++ b/arangod/VocBase/Methods/Collections.cpp @@ -109,23 +109,21 @@ LogicalCollection* Collections::Context::coll() const { return &_coll; } void Collections::enumerate( TRI_vocbase_t* vocbase, - std::function const& func) { + std::function const&)> const& func +) { if (ServerState::instance()->isCoordinator()) { std::vector> colls = ClusterInfo::instance()->getCollections(vocbase->name()); for (std::shared_ptr const& c : colls) { if (!c->deleted()) { - func(*c); + func(c); } } } else { - std::vector colls = - vocbase->collections(false); - - for (LogicalCollection* c : colls) { + for (auto& c: vocbase->collections(false)) { if (!c->deleted()) { - func(*c); + func(c); } } } @@ -153,7 +151,7 @@ Result methods::Collections::lookup(TRI_vocbase_t* vocbase, } if (coll) { - func(*coll); + func(coll); return Result(); } @@ -179,7 +177,7 @@ Result methods::Collections::lookup(TRI_vocbase_t* vocbase, "No access to collection '" + name + "'"); } try { - func(*coll); + func(coll); } catch (basics::Exception const& ex) { return Result(ex.code(), ex.what()); } catch (std::exception const& ex) { @@ -273,9 +271,9 @@ Result Collections::create(TRI_vocbase_t* vocbase, std::string const& name, } // reload otherwise collection might not be in yet - func(*col); + func(col); } else { - arangodb::LogicalCollection* col = vocbase->createCollection(infoSlice); + auto col = vocbase->createCollection(infoSlice); TRI_ASSERT(col != nullptr); // do not grant rights on system collections @@ -291,7 +289,7 @@ Result Collections::create(TRI_vocbase_t* vocbase, std::string const& name, }); } - func(*col); + func(col); } } catch (basics::Exception const& ex) { return Result(ex.code(), ex.what()); diff --git a/arangod/VocBase/Methods/Collections.h b/arangod/VocBase/Methods/Collections.h index 4167ef739d..1a8240e67e 100644 --- a/arangod/VocBase/Methods/Collections.h +++ b/arangod/VocBase/Methods/Collections.h @@ -65,7 +65,7 @@ struct Collections { bool const _responsibleForTrx; }; - typedef std::function const& FuncCallback; + typedef std::function const&)> const& FuncCallback; typedef std::function const& DocCallback; static void enumerate(TRI_vocbase_t* vocbase, FuncCallback); diff --git a/arangod/VocBase/Methods/UpgradeTasks.cpp b/arangod/VocBase/Methods/UpgradeTasks.cpp index 5685872223..d671e91704 100644 --- a/arangod/VocBase/Methods/UpgradeTasks.cpp +++ b/arangod/VocBase/Methods/UpgradeTasks.cpp @@ -59,8 +59,9 @@ namespace { /// create a collection if it does not exists. bool createSystemCollection(TRI_vocbase_t* vocbase, std::string const& name) { - auto res = - methods::Collections::lookup(vocbase, name, [](LogicalCollection& coll) {}); + auto res = methods::Collections::lookup( + vocbase, name, [](std::shared_ptr const&)->void {} + ); if (res.is(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND)) { uint32_t defaultReplFactor = 1; @@ -84,15 +85,21 @@ bool createSystemCollection(TRI_vocbase_t* vocbase, } bb.close(); - res = - Collections::create(vocbase, name, TRI_COL_TYPE_DOCUMENT, bb.slice(), - /*waitsForSyncReplication*/ true, - /*enforceReplicationFactor*/ true, - [](LogicalCollection& coll)->void {}); + res = Collections::create( + vocbase, + name, + TRI_COL_TYPE_DOCUMENT, + bb.slice(), + /*waitsForSyncReplication*/ true, + /*enforceReplicationFactor*/ true, + [](std::shared_ptr const&)->void {} + ); } + if (res.fail()) { THROW_ARANGO_EXCEPTION(res); } + return true; } @@ -107,8 +114,10 @@ bool createIndex(TRI_vocbase_t* vocbase, std::string const& name, res1 = methods::Collections::lookup( vocbase, name, - [&](LogicalCollection& coll)->void { - res2 = methods::Indexes::createIndex(&coll, type, fields, unique, sparse); + [&](std::shared_ptr const& coll)->void { + TRI_ASSERT(coll); + res2 = + methods::Indexes::createIndex(coll.get(), type, fields, unique, sparse); } ); diff --git a/arangod/VocBase/vocbase.cpp b/arangod/VocBase/vocbase.cpp index fb0190451d..20c0c4257e 100644 --- a/arangod/VocBase/vocbase.cpp +++ b/arangod/VocBase/vocbase.cpp @@ -1186,8 +1186,9 @@ std::shared_ptr TRI_vocbase_t::lookupView( /// this means that the system will assign a new collection id automatically /// using a cid of > 0 is supported to import dumps from other servers etc. /// but the functionality is not advertised -arangodb::LogicalCollection* TRI_vocbase_t::createCollection( - VPackSlice parameters) { +std::shared_ptr TRI_vocbase_t::createCollection( + arangodb::velocypack::Slice parameters +) { // check that the name does not contain any strange characters if (!IsAllowedName(parameters)) { THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME); @@ -1224,7 +1225,7 @@ arangodb::LogicalCollection* TRI_vocbase_t::createCollection( DatabaseFeature::DATABASE->versionTracker()->track("create collection"); } - return collection.get(); + return collection; } /// @brief unloads a collection @@ -2068,21 +2069,17 @@ void TRI_vocbase_t::processCollections( } } -std::vector TRI_vocbase_t::collections( +std::vector> TRI_vocbase_t::collections( bool includeDeleted ) { - std::vector collections; - - { RECURSIVE_READ_LOCKER(_dataSourceLock, _dataSourceLockWriteOwner); - if (includeDeleted) { - // return deleted collections as well. the cleanup thread needs them - collections.reserve(_collections.size()); - for (auto const& it : _collections) { - collections.emplace_back(it.get()); - } - } else { + if (includeDeleted) { + return _collections; // create copy + } + + std::vector> collections; + collections.reserve(_dataSourceById.size()); for (auto& entry: _dataSourceById) { @@ -2099,10 +2096,8 @@ std::vector TRI_vocbase_t::collections( auto collection = std::static_pointer_cast(entry.second); #endif - collections.emplace_back(collection.get()); + collections.emplace_back(collection); } - } - } return collections; } diff --git a/arangod/VocBase/vocbase.h b/arangod/VocBase/vocbase.h index eee5076591..75f8075ddf 100644 --- a/arangod/VocBase/vocbase.h +++ b/arangod/VocBase/vocbase.h @@ -265,7 +265,9 @@ struct TRI_vocbase_t { std::vector> views(); /// @brief returns all known collections - std::vector collections(bool includeDeleted); + std::vector> collections( + bool includeDeleted + ); void processCollections(std::function const& cb, bool includeDeleted); @@ -340,7 +342,7 @@ struct TRI_vocbase_t { /// this means that the system will assign a new collection id automatically /// using a cid of > 0 is supported to import dumps from other servers etc. /// but the functionality is not advertised - arangodb::LogicalCollection* createCollection( + std::shared_ptr createCollection( arangodb::velocypack::Slice parameters); /// @brief drops a collection, no timeout if timeout is < 0.0, otherwise diff --git a/lib/V8/v8-globals.cpp b/lib/V8/v8-globals.cpp index b1b16f0a6f..f027396c42 100644 --- a/lib/V8/v8-globals.cpp +++ b/lib/V8/v8-globals.cpp @@ -24,9 +24,7 @@ #include "v8-globals.h" TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate) - : JSCollections(), - JSViews(), - + : AgencyTempl(), AgentTempl(), ClusterInfoTempl(), @@ -213,6 +211,40 @@ TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate) _ToKey.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "_to")); } +TRI_v8_global_t::DataSourcePersistent::DataSourcePersistent( + v8::Isolate* isolate, + std::shared_ptr const& datasource, + std::function&& cleanupCallback +): _cleanupCallback(std::move(cleanupCallback)), + _datasource(datasource), + _isolate(isolate) { + TRI_GET_GLOBALS(); + _persistent.Reset(isolate, v8::External::New(isolate, datasource.get())); + _persistent.SetWeak( + this, + [](v8::WeakCallbackInfo const& data)->void { + auto isolate = data.GetIsolate(); + auto* persistent = data.GetParameter(); + + persistent->_cleanupCallback(); + + TRI_GET_GLOBALS();isolate = nullptr; + auto* key = persistent->_datasource.get(); // same key as was used for v8g->JSDatasources.emplace(...) + auto count = v8g->JSDatasources.erase(key); + TRI_ASSERT(count); // zero indicates that v8g was probably deallocated before calling the v8::WeakCallbackInfo::Callback + }, + v8::WeakCallbackType::kFinalizer + ); + v8g->increaseActiveExternals(); +} + +TRI_v8_global_t::DataSourcePersistent::~DataSourcePersistent() { + auto* isolate = _isolate; + TRI_GET_GLOBALS(); + v8g->decreaseActiveExternals(); + _persistent.Reset(); // dispose and clear the persistent handle (SIGSEGV here may indicate that v8::Isolate was already deallocated) +} + TRI_v8_global_t::~TRI_v8_global_t() {} /// @brief creates a global context diff --git a/lib/V8/v8-globals.h b/lib/V8/v8-globals.h index 68331401f0..d60406838a 100644 --- a/lib/V8/v8-globals.h +++ b/lib/V8/v8-globals.h @@ -30,6 +30,12 @@ struct TRI_vocbase_t; +namespace arangodb { + + class LogicalDataSource; // forward declaration + +} + /// @brief shortcut for fetching the isolate from the thread context #define ISOLATE v8::Isolate* isolate = v8::Isolate::GetCurrent() @@ -311,6 +317,28 @@ static inline v8::Handle v8Utf8StringFactory(v8::Isolate* isolate, v /// @brief globals stored in the isolate struct TRI_v8_global_t { + /// @brief wrapper around a v8::Persistent to hold a shared_ptr and cleanup + class DataSourcePersistent { + public: + DataSourcePersistent( + v8::Isolate* isolate, + std::shared_ptr const& datasource, + std::function&& cleanupCallback // function to call at the end of the Persistent WeakCallbackInfo::Callback (to avoid linking against arangod) + ); + DataSourcePersistent(DataSourcePersistent&&) = delete; + DataSourcePersistent(DataSourcePersistent const&) = delete; + ~DataSourcePersistent(); + DataSourcePersistent& operator=(DataSourcePersistent&&) = delete; + DataSourcePersistent& operator=(DataSourcePersistent const&) = delete; + v8::Local get() const { return _persistent.Get(_isolate); } + + private: + std::function _cleanupCallback; + std::shared_ptr _datasource; + v8::Isolate* _isolate; + v8::Persistent _persistent; + }; + explicit TRI_v8_global_t(v8::Isolate*); ~TRI_v8_global_t(); @@ -324,11 +352,8 @@ struct TRI_v8_global_t { /// @brief decrease the number of active externals inline void decreaseActiveExternals() { --_activeExternals; } - /// @brief collections mapping for weak pointers - std::unordered_map> JSCollections; - - /// @brief views mapping for weak pointers - std::unordered_map> JSViews; + /// @brief datasource mapping for weak pointers + std::unordered_map JSDatasources; /// @brief agency template v8::Persistent AgencyTempl; @@ -710,4 +735,4 @@ void TRI_AddGlobalVariableVocbase(v8::Isolate* isolate, v8::Handle name, v8::Handle value); -#endif +#endif \ No newline at end of file diff --git a/tests/IResearch/IResearchIndex-test.cpp b/tests/IResearch/IResearchIndex-test.cpp index e131b18c8c..ad253b463b 100644 --- a/tests/IResearch/IResearchIndex-test.cpp +++ b/tests/IResearch/IResearchIndex-test.cpp @@ -228,9 +228,9 @@ SECTION("test_analyzer") { auto createCollection1 = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); auto createView = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* collection0 = vocbase.createCollection(createCollection0->slice()); + auto collection0 = vocbase.createCollection(createCollection0->slice()); REQUIRE((nullptr != collection0)); - auto* collection1 = vocbase.createCollection(createCollection1->slice()); + auto collection1 = vocbase.createCollection(createCollection1->slice()); REQUIRE((nullptr != collection1)); auto viewImpl = vocbase.createView(createView->slice()); REQUIRE((nullptr != viewImpl)); @@ -478,9 +478,9 @@ SECTION("test_async_index") { auto createCollection1 = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); auto createView = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* collection0 = vocbase.createCollection(createCollection0->slice()); + auto collection0 = vocbase.createCollection(createCollection0->slice()); REQUIRE((nullptr != collection0)); - auto* collection1 = vocbase.createCollection(createCollection1->slice()); + auto collection1 = vocbase.createCollection(createCollection1->slice()); REQUIRE((nullptr != collection1)); auto viewImpl = vocbase.createView(createView->slice()); REQUIRE((nullptr != viewImpl)); @@ -834,9 +834,9 @@ SECTION("test_fields") { auto createCollection1 = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); auto createView = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* collection0 = vocbase.createCollection(createCollection0->slice()); + auto collection0 = vocbase.createCollection(createCollection0->slice()); REQUIRE((nullptr != collection0)); - auto* collection1 = vocbase.createCollection(createCollection1->slice()); + auto collection1 = vocbase.createCollection(createCollection1->slice()); REQUIRE((nullptr != collection1)); auto viewImpl = vocbase.createView(createView->slice()); REQUIRE((nullptr != viewImpl)); diff --git a/tests/IResearch/IResearchLink-test.cpp b/tests/IResearch/IResearchLink-test.cpp index ced845d862..530bad0361 100644 --- a/tests/IResearch/IResearchLink-test.cpp +++ b/tests/IResearch/IResearchLink-test.cpp @@ -169,7 +169,7 @@ SECTION("test_defaults") { s.engine.views.clear(); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto json = arangodb::velocypack::Parser::fromJson("{}"); auto link = arangodb::iresearch::IResearchMMFilesLink::make(*logicalCollection, json->slice(), 1, false); @@ -181,7 +181,7 @@ SECTION("test_defaults") { s.engine.views.clear(); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto json = arangodb::velocypack::Parser::fromJson("{ \"view\": 42 }"); auto link = arangodb::iresearch::IResearchMMFilesLink::make(*logicalCollection, json->slice(), 1, false); @@ -195,7 +195,7 @@ SECTION("test_defaults") { auto linkJson = arangodb::velocypack::Parser::fromJson("{ \"type\": \"arangosearch\", \"view\": 42 }"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"id\": 42, \"type\": \"arangosearch\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -204,7 +204,7 @@ SECTION("test_defaults") { auto link = logicalCollection->createIndex(nullptr, linkJson->slice(), created); REQUIRE((false == !link && created)); CHECK((true == link->canBeDropped())); - CHECK((logicalCollection == link->collection())); + CHECK((logicalCollection.get() == link->collection())); CHECK((link->fieldNames().empty())); CHECK((link->fields().empty())); CHECK((true == link->hasBatchInsert())); @@ -247,7 +247,7 @@ SECTION("test_defaults") { auto linkJson = arangodb::velocypack::Parser::fromJson("{ \"type\": \"arangosearch\", \"view\": 42 }"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"id\": 42, \"type\": \"arangosearch\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -256,7 +256,7 @@ SECTION("test_defaults") { auto link = logicalCollection->createIndex(nullptr, linkJson->slice(), created); REQUIRE((false == !link && created)); CHECK((true == link->canBeDropped())); - CHECK((logicalCollection == link->collection())); + CHECK((logicalCollection.get() == link->collection())); CHECK((link->fieldNames().empty())); CHECK((link->fields().empty())); CHECK((true == link->hasBatchInsert())); @@ -317,7 +317,7 @@ SECTION("test_init") { auto linkJson = arangodb::velocypack::Parser::fromJson("{ \"type\": \"arangosearch\", \"view\": 42 }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"id\": 42, \"type\": \"arangosearch\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -376,7 +376,7 @@ SECTION("test_init") { auto linkJson = arangodb::velocypack::Parser::fromJson("{ \"type\": \"arangosearch\", \"view\": 43 }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"id\": 43, \"type\": \"arangosearch\", \"collections\": [ 101 ] }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -437,7 +437,7 @@ SECTION("test_drop") { auto linkJson = arangodb::velocypack::Parser::fromJson("{ \"type\": \"arangosearch\", \"view\": 42 }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"id\": 42, \"type\": \"arangosearch\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -519,7 +519,7 @@ SECTION("test_unload") { auto linkJson = arangodb::velocypack::Parser::fromJson("{ \"type\": \"arangosearch\", \"view\": 42 }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"id\": 42, \"type\": \"arangosearch\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -590,7 +590,7 @@ SECTION("test_write") { \"name\": \"testView\", \ \"type\": \"arangosearch\" \ }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = std::dynamic_pointer_cast( vocbase.createView(viewJson->slice()) diff --git a/tests/IResearch/IResearchQueryAggregate-test.cpp b/tests/IResearch/IResearchQueryAggregate-test.cpp index c962d27c93..efebece696 100644 --- a/tests/IResearch/IResearchQueryAggregate-test.cpp +++ b/tests/IResearch/IResearchQueryAggregate-test.cpp @@ -184,7 +184,7 @@ TEST_CASE("IResearchQueryTestAggregate", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -217,7 +217,7 @@ TEST_CASE("IResearchQueryTestAggregate", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQueryAnd-test.cpp b/tests/IResearch/IResearchQueryAnd-test.cpp index 67ab3c0497..19f8d8404e 100644 --- a/tests/IResearch/IResearchQueryAnd-test.cpp +++ b/tests/IResearch/IResearchQueryAnd-test.cpp @@ -184,7 +184,7 @@ TEST_CASE("IResearchQueryTestAnd", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -217,7 +217,7 @@ TEST_CASE("IResearchQueryTestAnd", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQueryBooleanTerm-test.cpp b/tests/IResearch/IResearchQueryBooleanTerm-test.cpp index 5c1995e6f4..abbff50c87 100644 --- a/tests/IResearch/IResearchQueryBooleanTerm-test.cpp +++ b/tests/IResearch/IResearchQueryBooleanTerm-test.cpp @@ -186,7 +186,7 @@ TEST_CASE("IResearchQueryTestBooleanTerm", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -222,7 +222,7 @@ TEST_CASE("IResearchQueryTestBooleanTerm", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { diff --git a/tests/IResearch/IResearchQueryComplexBoolean-test.cpp b/tests/IResearch/IResearchQueryComplexBoolean-test.cpp index 6f5dadc725..d6370a8db3 100644 --- a/tests/IResearch/IResearchQueryComplexBoolean-test.cpp +++ b/tests/IResearch/IResearchQueryComplexBoolean-test.cpp @@ -194,7 +194,7 @@ TEST_CASE("IResearchQueryTestComplexBoolean", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -227,7 +227,7 @@ TEST_CASE("IResearchQueryTestComplexBoolean", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQueryExists-test.cpp b/tests/IResearch/IResearchQueryExists-test.cpp index b33ee8e5b7..eb8d6103cf 100644 --- a/tests/IResearch/IResearchQueryExists-test.cpp +++ b/tests/IResearch/IResearchQueryExists-test.cpp @@ -186,7 +186,7 @@ TEST_CASE("IResearchQueryTestExists", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -219,7 +219,7 @@ TEST_CASE("IResearchQueryTestExists", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; @@ -1444,7 +1444,7 @@ TEST_CASE("IResearchQueryTestExistsStoreMaskPartially", "[iresearch][iresearch-q // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -1477,7 +1477,7 @@ TEST_CASE("IResearchQueryTestExistsStoreMaskPartially", "[iresearch][iresearch-q // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQueryIn-test.cpp b/tests/IResearch/IResearchQueryIn-test.cpp index 7b0d58a5e8..4729a23710 100644 --- a/tests/IResearch/IResearchQueryIn-test.cpp +++ b/tests/IResearch/IResearchQueryIn-test.cpp @@ -184,7 +184,7 @@ TEST_CASE("IResearchQueryTestIn", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -217,7 +217,7 @@ TEST_CASE("IResearchQueryTestIn", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQueryJoin-test.cpp b/tests/IResearch/IResearchQueryJoin-test.cpp index 437263ffe7..94ae7678f4 100644 --- a/tests/IResearch/IResearchQueryJoin-test.cpp +++ b/tests/IResearch/IResearchQueryJoin-test.cpp @@ -325,9 +325,9 @@ TEST_CASE("IResearchQueryTestJoinDuplicateDataSource", "[iresearch][iresearch-qu }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; - arangodb::LogicalCollection* logicalCollection3{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; + std::shared_ptr logicalCollection3; // add collection_1 { @@ -416,7 +416,7 @@ TEST_CASE("IResearchQueryTestJoinDuplicateDataSource", "[iresearch][iresearch-qu size_t i = 0; - arangodb::LogicalCollection* collections[] { + std::shared_ptr collections[] { logicalCollection1, logicalCollection2 }; @@ -482,9 +482,9 @@ TEST_CASE("IResearchQueryTestJoin", "[iresearch][iresearch-query]") { }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; - arangodb::LogicalCollection* logicalCollection3{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; + std::shared_ptr logicalCollection3; // add collection_1 { @@ -566,7 +566,7 @@ TEST_CASE("IResearchQueryTestJoin", "[iresearch][iresearch-query]") { size_t i = 0; - arangodb::LogicalCollection* collections[] { + std::shared_ptr collections[] { logicalCollection1, logicalCollection2 }; diff --git a/tests/IResearch/IResearchQueryNullTerm-test.cpp b/tests/IResearch/IResearchQueryNullTerm-test.cpp index 29c28fa327..7ce1abfe6e 100644 --- a/tests/IResearch/IResearchQueryNullTerm-test.cpp +++ b/tests/IResearch/IResearchQueryNullTerm-test.cpp @@ -184,7 +184,7 @@ TEST_CASE("IResearchQueryTestNullTerm", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -220,7 +220,7 @@ TEST_CASE("IResearchQueryTestNullTerm", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { diff --git a/tests/IResearch/IResearchQueryNumericTerm-test.cpp b/tests/IResearch/IResearchQueryNumericTerm-test.cpp index 374d6fc95e..52aac0637b 100644 --- a/tests/IResearch/IResearchQueryNumericTerm-test.cpp +++ b/tests/IResearch/IResearchQueryNumericTerm-test.cpp @@ -195,8 +195,8 @@ TEST_CASE("IResearchQueryTestNumericTerm", "[iresearch][iresearch-query]") { }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; // add collection_1 { @@ -269,7 +269,7 @@ TEST_CASE("IResearchQueryTestNumericTerm", "[iresearch][iresearch-query]") { size_t i = 0; - arangodb::LogicalCollection* collections[] { + std::shared_ptr collections[] { logicalCollection1, logicalCollection2 }; diff --git a/tests/IResearch/IResearchQueryOr-test.cpp b/tests/IResearch/IResearchQueryOr-test.cpp index 4267fd62c5..cad0a8c894 100644 --- a/tests/IResearch/IResearchQueryOr-test.cpp +++ b/tests/IResearch/IResearchQueryOr-test.cpp @@ -196,8 +196,8 @@ TEST_CASE("IResearchQueryTestOr", "[iresearch][iresearch-query]") { }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; // add collection_1 { @@ -270,7 +270,7 @@ TEST_CASE("IResearchQueryTestOr", "[iresearch][iresearch-query]") { size_t i = 0; - arangodb::LogicalCollection* collections[] { + std::shared_ptr collections[] { logicalCollection1, logicalCollection2 }; diff --git a/tests/IResearch/IResearchQueryPhrase-test.cpp b/tests/IResearch/IResearchQueryPhrase-test.cpp index 27929233c2..910120d094 100644 --- a/tests/IResearch/IResearchQueryPhrase-test.cpp +++ b/tests/IResearch/IResearchQueryPhrase-test.cpp @@ -194,7 +194,7 @@ TEST_CASE("IResearchQueryTestPhrase", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -227,7 +227,7 @@ TEST_CASE("IResearchQueryTestPhrase", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQuerySelectAll-test.cpp b/tests/IResearch/IResearchQuerySelectAll-test.cpp index 4f0c7583a2..4bd130ca3b 100644 --- a/tests/IResearch/IResearchQuerySelectAll-test.cpp +++ b/tests/IResearch/IResearchQuerySelectAll-test.cpp @@ -186,8 +186,8 @@ TEST_CASE("IResearchQueryTestSelectAll", "[iresearch][iresearch-query]") { }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; // add collection_1 { diff --git a/tests/IResearch/IResearchQueryStartsWith-test.cpp b/tests/IResearch/IResearchQueryStartsWith-test.cpp index 9e0f7d000c..00719c2598 100644 --- a/tests/IResearch/IResearchQueryStartsWith-test.cpp +++ b/tests/IResearch/IResearchQueryStartsWith-test.cpp @@ -186,8 +186,8 @@ TEST_CASE("IResearchQueryTestStartsWith", "[iresearch][iresearch-query]") { }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; // add collection_1 { @@ -260,7 +260,7 @@ TEST_CASE("IResearchQueryTestStartsWith", "[iresearch][iresearch-query]") { size_t i = 0; - arangodb::LogicalCollection* collections[] { + std::shared_ptr collections[] { logicalCollection1, logicalCollection2 }; diff --git a/tests/IResearch/IResearchQueryStringTerm-test.cpp b/tests/IResearch/IResearchQueryStringTerm-test.cpp index b0a5b555a0..0c41186a4b 100644 --- a/tests/IResearch/IResearchQueryStringTerm-test.cpp +++ b/tests/IResearch/IResearchQueryStringTerm-test.cpp @@ -225,8 +225,8 @@ TEST_CASE("IResearchQueryTestStringTerm", "[iresearch][iresearch-query]") { }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* logicalCollection1{}; - arangodb::LogicalCollection* logicalCollection2{}; + std::shared_ptr logicalCollection1; + std::shared_ptr logicalCollection2; // add collection_1 { @@ -299,7 +299,7 @@ TEST_CASE("IResearchQueryTestStringTerm", "[iresearch][iresearch-query]") { size_t i = 0; - arangodb::LogicalCollection* collections[] { + std::shared_ptr collections[] { logicalCollection1, logicalCollection2 }; diff --git a/tests/IResearch/IResearchQueryTokens-test.cpp b/tests/IResearch/IResearchQueryTokens-test.cpp index 0a633237c5..e9a4f650c4 100644 --- a/tests/IResearch/IResearchQueryTokens-test.cpp +++ b/tests/IResearch/IResearchQueryTokens-test.cpp @@ -192,7 +192,7 @@ TEST_CASE("IResearchQueryTestTokens", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -225,7 +225,7 @@ TEST_CASE("IResearchQueryTestTokens", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchQueryTraversal-test.cpp b/tests/IResearch/IResearchQueryTraversal-test.cpp index 351d340741..c671d15d0d 100644 --- a/tests/IResearch/IResearchQueryTraversal-test.cpp +++ b/tests/IResearch/IResearchQueryTraversal-test.cpp @@ -184,7 +184,7 @@ TEST_CASE("IResearchQueryTestTraversal", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -218,7 +218,7 @@ TEST_CASE("IResearchQueryTestTraversal", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; @@ -250,7 +250,7 @@ TEST_CASE("IResearchQueryTestTraversal", "[iresearch][iresearch-query]") { // create edge collection { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"edges\", \"type\": 3 }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); arangodb::SingleCollectionTransaction trx( diff --git a/tests/IResearch/IResearchQueryValue-test.cpp b/tests/IResearch/IResearchQueryValue-test.cpp index c63e759d2d..26de4e5c07 100644 --- a/tests/IResearch/IResearchQueryValue-test.cpp +++ b/tests/IResearch/IResearchQueryValue-test.cpp @@ -184,7 +184,7 @@ TEST_CASE("IResearchQueryTestValue", "[iresearch][iresearch-query]") { // create collection0 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); std::vector> docs { @@ -217,7 +217,7 @@ TEST_CASE("IResearchQueryTestValue", "[iresearch][iresearch-query]") { // create collection1 { auto createJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* collection = vocbase.createCollection(createJson->slice()); + auto collection = vocbase.createCollection(createJson->slice()); REQUIRE((nullptr != collection)); irs::utf8_path resource; diff --git a/tests/IResearch/IResearchView-test.cpp b/tests/IResearch/IResearchView-test.cpp index a3f0e6b2e4..6e4068bdb1 100644 --- a/tests/IResearch/IResearchView-test.cpp +++ b/tests/IResearch/IResearchView-test.cpp @@ -328,7 +328,7 @@ SECTION("test_defaults") { auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\", \"id\": 101, \"links\": { \"testCollection\": {} } }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); CHECK((nullptr != logicalCollection)); CHECK((true == !vocbase.lookupView("testView"))); CHECK((true == logicalCollection->getIndexes().empty())); @@ -347,7 +347,7 @@ SECTION("test_defaults") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -389,7 +389,7 @@ SECTION("test_defaults") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -494,7 +494,7 @@ SECTION("test_drop") { CHECK((false == TRI_IsDirectory(dataPath.c_str()))); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); CHECK((nullptr != logicalCollection)); CHECK((true == !vocbase.lookupView("testView"))); CHECK((true == logicalCollection->getIndexes().empty())); @@ -523,7 +523,7 @@ SECTION("test_drop_with_link") { CHECK((false == TRI_IsDirectory(dataPath.c_str()))); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); CHECK((nullptr != logicalCollection)); CHECK((true == !vocbase.lookupView("testView"))); CHECK((true == logicalCollection->getIndexes().empty())); @@ -588,7 +588,7 @@ SECTION("test_drop_collection") { auto viewCreateJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }"); auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": { \"includeAllFields\": true } } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((false == !logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -1802,7 +1802,7 @@ SECTION("test_query") { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); std::vector collections{ logicalCollection->name() }; auto logicalView = vocbase.createView(createJson->slice()); CHECK((false == !logicalView)); @@ -1892,7 +1892,7 @@ SECTION("test_query") { >("Flush"); REQUIRE(feature); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); auto* view = dynamic_cast(logicalView.get()); @@ -1968,7 +1968,7 @@ SECTION("test_register_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((false == !logicalCollection)); auto logicalView = vocbase.createView(viewJson0->slice()); REQUIRE((false == !logicalView)); @@ -2024,7 +2024,7 @@ SECTION("test_register_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((false == !logicalCollection)); auto logicalView = vocbase.createView(viewJson0->slice()); REQUIRE((false == !logicalView)); @@ -2103,7 +2103,7 @@ SECTION("test_register_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((false == !logicalCollection)); auto logicalView = vocbase.createView(viewJson1->slice()); REQUIRE((false == !logicalView)); @@ -2214,7 +2214,7 @@ SECTION("test_unregister_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); auto* view = dynamic_cast(logicalView.get()); @@ -2313,7 +2313,7 @@ SECTION("test_unregister_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); auto* view = dynamic_cast(logicalView.get()); @@ -2408,7 +2408,7 @@ SECTION("test_unregister_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); auto* view = dynamic_cast(logicalView.get()); @@ -2437,7 +2437,7 @@ SECTION("test_unregister_link") { { s.engine.views.clear(); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); { auto createJson = arangodb::velocypack::Parser::fromJson("{}"); @@ -2524,7 +2524,7 @@ SECTION("test_tracked_cids") { s.engine.views.clear(); auto updateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": { } } }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), true, 0); REQUIRE((false == !logicalView)); @@ -2552,7 +2552,7 @@ SECTION("test_tracked_cids") { auto updateJson0 = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": { } } }"); auto updateJson1 = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": null } }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), true, 0); REQUIRE((false == !logicalView)); @@ -2640,7 +2640,7 @@ SECTION("test_tracked_cids") { s.engine.views.clear(); auto updateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": { } } }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -2666,7 +2666,7 @@ SECTION("test_tracked_cids") { auto updateJson0 = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": { } } }"); auto updateJson1 = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": null } }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -2704,9 +2704,9 @@ SECTION("test_transaction_registration") { auto collectionJson1 = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }"); Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collectionJson0->slice()); + auto logicalCollection0 = vocbase.createCollection(collectionJson0->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collectionJson1->slice()); + auto logicalCollection1 = vocbase.createCollection(collectionJson1->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewJson->slice()); REQUIRE((false == !logicalView)); @@ -3299,7 +3299,7 @@ SECTION("test_update_overwrite") { { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(createJson->slice()); REQUIRE((false == !logicalView)); @@ -3449,9 +3449,9 @@ SECTION("test_update_overwrite") { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson0 = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection0\" }"); auto collectionJson1 = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection1\" }"); - auto* logicalCollection0 = vocbase.createCollection(collectionJson0->slice()); + auto logicalCollection0 = vocbase.createCollection(collectionJson0->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collectionJson1->slice()); + auto logicalCollection1 = vocbase.createCollection(collectionJson1->slice()); REQUIRE((nullptr != logicalCollection1)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -3624,7 +3624,7 @@ SECTION("test_update_overwrite") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -3734,7 +3734,7 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"cleanupIntervalStep\": 62, \"links\": { \"testCollection\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -3815,7 +3815,7 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -3848,7 +3848,7 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": null } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -3908,9 +3908,9 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection0\": {}, \"testCollection1\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase.createCollection(collection0Json->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase.createCollection(collection1Json->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -3976,9 +3976,9 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection0\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase.createCollection(collection0Json->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase.createCollection(collection1Json->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -4043,7 +4043,7 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": null } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -4103,9 +4103,9 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection0\": {}, \"testCollection1\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase.createCollection(collection0Json->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase.createCollection(collection1Json->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -4171,9 +4171,9 @@ SECTION("test_update_overwrite") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection0\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase.createCollection(collection0Json->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase.createCollection(collection1Json->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -4373,7 +4373,7 @@ SECTION("test_update_partial") { { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(createJson->slice()); REQUIRE((false == !logicalView)); @@ -4545,7 +4545,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -4608,7 +4608,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -4698,7 +4698,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -4869,7 +4869,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -4941,7 +4941,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -5132,7 +5132,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -5198,7 +5198,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -5313,7 +5313,7 @@ SECTION("test_update_partial") { { Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\" }"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto view = vocbase.createView(createJson->slice()); REQUIRE((false == !view)); @@ -5424,7 +5424,7 @@ SECTION("test_update_partial") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"cleanupIntervalStep\": 62 }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -5505,7 +5505,7 @@ SECTION("test_update_partial") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -5538,7 +5538,7 @@ SECTION("test_update_partial") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": null } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection = vocbase.createCollection(collectionJson->slice()); + auto logicalCollection = vocbase.createCollection(collectionJson->slice()); REQUIRE((nullptr != logicalCollection)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -5598,9 +5598,9 @@ SECTION("test_update_partial") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection1\": {} } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase.createCollection(collection0Json->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase.createCollection(collection1Json->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); @@ -5666,9 +5666,9 @@ SECTION("test_update_partial") { auto viewUpdateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection1\": null } }"); TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - auto* logicalCollection0 = vocbase.createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase.createCollection(collection0Json->slice()); REQUIRE((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase.createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase.createCollection(collection1Json->slice()); REQUIRE((nullptr != logicalCollection1)); auto logicalView = vocbase.createView(viewCreateJson->slice()); REQUIRE((false == !logicalView)); diff --git a/tests/IResearch/IResearchViewDBServer-test.cpp b/tests/IResearch/IResearchViewDBServer-test.cpp index 21d44ab0b1..55c0680280 100644 --- a/tests/IResearch/IResearchViewDBServer-test.cpp +++ b/tests/IResearch/IResearchViewDBServer-test.cpp @@ -525,7 +525,7 @@ SECTION("test_query") { REQUIRE((TRI_ERROR_NO_ERROR == databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); REQUIRE((nullptr != vocbase)); REQUIRE((TRI_ERROR_NO_ERROR == ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), error, 0.))); - auto* logicalCollection = vocbase->createCollection(collectionJson->slice()); + auto logicalCollection = vocbase->createCollection(collectionJson->slice()); std::vector collections{ logicalCollection->name() }; CHECK((TRI_ERROR_NO_ERROR == ci->createViewCoordinator(vocbase->name(), "42", createJson->slice(), error))); auto logicalWiew = ci->getView(vocbase->name(), "42"); // link creation requires cluster-view to be in ClusterInfo instead of TRI_vocbase_t @@ -626,7 +626,7 @@ SECTION("test_query") { REQUIRE((TRI_ERROR_NO_ERROR == databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); REQUIRE((nullptr != vocbase)); REQUIRE((TRI_ERROR_NO_ERROR == ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), error, 0.))); - auto* logicalCollection = vocbase->createCollection(collectionJson->slice()); + auto logicalCollection = vocbase->createCollection(collectionJson->slice()); CHECK((TRI_ERROR_NO_ERROR == ci->createViewCoordinator(vocbase->name(), "42", createJson->slice(), error))); auto logicalWiew = ci->getView(vocbase->name(), "42"); // link creation requires cluster-view to be in ClusterInfo instead of TRI_vocbase_t REQUIRE((false == !logicalWiew)); @@ -970,7 +970,7 @@ SECTION("test_updateProperties") { REQUIRE((TRI_ERROR_NO_ERROR == databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); REQUIRE((nullptr != vocbase)); REQUIRE((TRI_ERROR_NO_ERROR == ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), error, 0.))); - auto* logicalCollection = vocbase->createCollection(collectionJson->slice()); + auto logicalCollection = vocbase->createCollection(collectionJson->slice()); CHECK((nullptr != logicalCollection)); CHECK((TRI_ERROR_NO_ERROR == ci->createViewCoordinator(vocbase->name(), "42", viewJson->slice(), error))); auto wiew = ci->getView(vocbase->name(), "42"); // link creation requires cluster-view to be in ClusterInfo instead of TRI_vocbase_t @@ -1060,7 +1060,7 @@ SECTION("test_updateProperties") { REQUIRE((TRI_ERROR_NO_ERROR == databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); REQUIRE((nullptr != vocbase)); REQUIRE((TRI_ERROR_NO_ERROR == ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), error, 0.))); - auto* logicalCollection = vocbase->createCollection(collectionJson->slice()); + auto logicalCollection = vocbase->createCollection(collectionJson->slice()); CHECK((nullptr != logicalCollection)); CHECK((TRI_ERROR_NO_ERROR == ci->createViewCoordinator(vocbase->name(), "42", viewJson->slice(), error))); auto wiew = ci->getView(vocbase->name(), "42"); // link creation requires cluster-view to be in ClusterInfo instead of TRI_vocbase_t @@ -1150,7 +1150,7 @@ SECTION("test_updateProperties") { REQUIRE((TRI_ERROR_NO_ERROR == databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); REQUIRE((nullptr != vocbase)); REQUIRE((TRI_ERROR_NO_ERROR == ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), error, 0.))); - auto* logicalCollection = vocbase->createCollection(collectionJson->slice()); + auto logicalCollection = vocbase->createCollection(collectionJson->slice()); CHECK((nullptr != logicalCollection)); CHECK((TRI_ERROR_NO_ERROR == ci->createViewCoordinator(vocbase->name(), "42", viewJson->slice(), error))); auto wiew = ci->getView(vocbase->name(), "42"); // link creation requires cluster-view to be in ClusterInfo instead of TRI_vocbase_t @@ -1243,9 +1243,9 @@ SECTION("test_updateProperties") { REQUIRE((TRI_ERROR_NO_ERROR == databaseFeature->createDatabase(0, "testDatabase" TOSTRING(__LINE__), vocbase))); REQUIRE((nullptr != vocbase)); REQUIRE((TRI_ERROR_NO_ERROR == ci->createDatabaseCoordinator(vocbase->name(), arangodb::velocypack::Slice::emptyObjectSlice(), error, 0.))); - auto* logicalCollection0 = vocbase->createCollection(collection0Json->slice()); + auto logicalCollection0 = vocbase->createCollection(collection0Json->slice()); CHECK((nullptr != logicalCollection0)); - auto* logicalCollection1 = vocbase->createCollection(collection1Json->slice()); + auto logicalCollection1 = vocbase->createCollection(collection1Json->slice()); CHECK((nullptr != logicalCollection1)); CHECK((TRI_ERROR_NO_ERROR == ci->createViewCoordinator(vocbase->name(), "42", viewJson->slice(), error))); auto wiew = ci->getView(vocbase->name(), "42"); // link creation requires cluster-view to be in ClusterInfo instead of TRI_vocbase_t diff --git a/tests/IResearch/IResearchViewNode-test.cpp b/tests/IResearch/IResearchViewNode-test.cpp index de946bd48a..808122d132 100644 --- a/tests/IResearch/IResearchViewNode-test.cpp +++ b/tests/IResearch/IResearchViewNode-test.cpp @@ -1017,8 +1017,8 @@ SECTION("serialize") { SECTION("collections") { TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase"); - arangodb::LogicalCollection* collection0{}; - arangodb::LogicalCollection* collection1{}; + std::shared_ptr collection0; + std::shared_ptr collection1; // create collection0 { diff --git a/tests/RestHandler/RestUsersHandler-test.cpp b/tests/RestHandler/RestUsersHandler-test.cpp index 8122b0ea44..bd17977518 100644 --- a/tests/RestHandler/RestUsersHandler-test.cpp +++ b/tests/RestHandler/RestUsersHandler-test.cpp @@ -237,7 +237,7 @@ SECTION("test_collection_auth") { // test auth missing (grant) { - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -259,7 +259,7 @@ SECTION("test_collection_auth") { // test auth missing (revoke) { - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -283,14 +283,14 @@ SECTION("test_collection_auth") { // test auth collection (grant) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) userManager->storeUser(false, userName, arangodb::StaticStrings::Empty, true, arangodb::velocypack::Slice()); userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::NONE == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); @@ -306,7 +306,7 @@ SECTION("test_collection_auth") { // test auth collection (revoke) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -314,7 +314,7 @@ SECTION("test_collection_auth") { userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); userPtr->grantCollection(vocbase->name(), "testDataSource", arangodb::auth::Level::RO); // for missing collections User::collectionAuthLevel(...) returns database auth::Level - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::RO == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); @@ -331,7 +331,7 @@ SECTION("test_collection_auth") { // test auth view (grant) { auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\", \"type\": \"testViewType\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -356,7 +356,7 @@ SECTION("test_collection_auth") { // test auth view (revoke) { auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\", \"type\": \"testViewType\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -382,14 +382,14 @@ SECTION("test_collection_auth") { // test auth wildcard (grant) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) userManager->storeUser(false, userName, arangodb::StaticStrings::Empty, true, arangodb::velocypack::Slice()); userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::NONE == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); @@ -405,7 +405,7 @@ SECTION("test_collection_auth") { // test auth wildcard (revoke) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -413,7 +413,7 @@ SECTION("test_collection_auth") { userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); userPtr->grantCollection(vocbase->name(), "testDataSource", arangodb::auth::Level::RO); // for missing collections User::collectionAuthLevel(...) returns database auth::Level - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::RO == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); diff --git a/tests/Utils/CollectionNameResolver-test.cpp b/tests/Utils/CollectionNameResolver-test.cpp index 4b132cb815..1019940b35 100644 --- a/tests/Utils/CollectionNameResolver-test.cpp +++ b/tests/Utils/CollectionNameResolver-test.cpp @@ -186,7 +186,7 @@ SECTION("test_getDataSource") { CHECK((true == !resolver.getView("testViewGUID"))); } - auto* collection = vocbase.createCollection(collectionJson->slice()); + auto collection = vocbase.createCollection(collectionJson->slice()); auto view = vocbase.createView(viewJson->slice()); CHECK((false == collection->deleted())); diff --git a/tests/V8Server/v8-users-test.cpp b/tests/V8Server/v8-users-test.cpp index aa7b9610f4..3650844154 100644 --- a/tests/V8Server/v8-users-test.cpp +++ b/tests/V8Server/v8-users-test.cpp @@ -198,13 +198,9 @@ SECTION("test_collection_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - } + [](v8::Isolate* p)->void { p->Dispose(); } ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) @@ -212,7 +208,7 @@ SECTION("test_collection_auth") { v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = vocbase; TRI_InitV8Users(context, vocbase, v8g.get(), isolate.get()); @@ -258,7 +254,7 @@ SECTION("test_collection_auth") { // test auth missing (grant) { - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -281,7 +277,7 @@ SECTION("test_collection_auth") { // test auth missing (revoke) { - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -306,14 +302,14 @@ SECTION("test_collection_auth") { // test auth collection (grant) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) userManager->storeUser(false, userName, arangodb::StaticStrings::Empty, true, arangodb::velocypack::Slice()); userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::NONE == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); @@ -329,7 +325,7 @@ SECTION("test_collection_auth") { // test auth collection (revoke) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -337,7 +333,7 @@ SECTION("test_collection_auth") { userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); userPtr->grantCollection(vocbase->name(), "testDataSource", arangodb::auth::Level::RO); // for missing collections User::collectionAuthLevel(...) returns database auth::Level - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::RO == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); @@ -353,7 +349,7 @@ SECTION("test_collection_auth") { // test auth view (grant) { auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\", \"type\": \"testViewType\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -379,7 +375,7 @@ SECTION("test_collection_auth") { // test auth view (revoke) { auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\", \"type\": \"testViewType\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -406,14 +402,14 @@ SECTION("test_collection_auth") { // test auth wildcard (grant) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) userManager->storeUser(false, userName, arangodb::StaticStrings::Empty, true, arangodb::velocypack::Slice()); userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::NONE == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); @@ -429,7 +425,7 @@ SECTION("test_collection_auth") { // test auth wildcard (revoke) { auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testDataSource\" }"); - auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); + auto scopedUsers = std::shared_ptr(s.system->createCollection(usersJson->slice()).get(), [&s](arangodb::LogicalCollection* ptr)->void{ s.system->dropCollection(ptr->id(), true, 0.0); }); arangodb::auth::UserMap userMap; arangodb::auth::User* userPtr = nullptr; userManager->setAuthInfo(userMap); // insure an empy map is set before UserManager::storeUser(...) @@ -437,7 +433,7 @@ SECTION("test_collection_auth") { userManager->accessUser(userName, [&userPtr](arangodb::auth::User const& user)->arangodb::Result { userPtr = const_cast(&user); return arangodb::Result(); }); REQUIRE((nullptr != userPtr)); userPtr->grantCollection(vocbase->name(), "testDataSource", arangodb::auth::Level::RO); // for missing collections User::collectionAuthLevel(...) returns database auth::Level - auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); + auto logicalCollection = std::shared_ptr(vocbase->createCollection(collectionJson->slice()).get(), [vocbase](arangodb::LogicalCollection* ptr)->void{ vocbase->dropCollection(ptr->id(), false, 0); }); REQUIRE((false == !logicalCollection)); CHECK((arangodb::auth::Level::RO == execContext.collectionAuthLevel(vocbase->name(), "testDataSource"))); diff --git a/tests/V8Server/v8-views-test.cpp b/tests/V8Server/v8-views-test.cpp index 719ccd0616..e51b5c39b4 100644 --- a/tests/V8Server/v8-views-test.cpp +++ b/tests/V8Server/v8-views-test.cpp @@ -184,20 +184,17 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::internal::Isolate::Current()->InitializeLoggingAndCounters(); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -271,7 +268,7 @@ SECTION("test_auth") { auto result = v8::Function::Cast(*fn_createView)->CallAsFunction(context, fn_createView, args.size(), args.data()); CHECK((!result.IsEmpty())); CHECK((result.ToLocalChecked()->IsObject())); - auto v8View = *TRI_UnwrapClass>(result.ToLocalChecked()->ToObject(), WRP_VOCBASE_VIEW_TYPE); + auto* v8View = TRI_UnwrapClass(result.ToLocalChecked()->ToObject(), WRP_VOCBASE_VIEW_TYPE); CHECK((false == !v8View)); CHECK((std::string("testView") == v8View->name())); CHECK((std::string("testViewType") == v8View->type().name())); @@ -290,20 +287,17 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::internal::Isolate::Current()->InitializeLoggingAndCounters(); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -426,20 +420,17 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::internal::Isolate::Current()->InitializeLoggingAndCounters(); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -450,8 +441,8 @@ SECTION("test_auth") { CHECK((fn_drop->IsFunction())); arangoView->SetInternalField(SLOT_CLASS_TYPE, v8::Integer::New(isolate.get(), WRP_VOCBASE_VIEW_TYPE)); - arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), &logicalView)); - arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), &logicalView)); + arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), logicalView.get())); + arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), logicalView.get())); std::vector> args = { }; @@ -565,20 +556,17 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::internal::Isolate::Current()->InitializeLoggingAndCounters(); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -589,8 +577,8 @@ SECTION("test_auth") { CHECK((fn_rename->IsFunction())); arangoView->SetInternalField(SLOT_CLASS_TYPE, v8::Integer::New(isolate.get(), WRP_VOCBASE_VIEW_TYPE)); - arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), &logicalView)); - arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), &logicalView)); + arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), logicalView.get())); + arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), logicalView.get())); std::vector> args = { TRI_V8_ASCII_STRING(isolate.get(), "testView1"), }; @@ -743,13 +731,10 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); char isolateData[64]; // 64 > sizeof(arangodb::V8PlatformFeature::IsolateData) std::memset(isolateData, 0, 64); // otherwise arangodb::V8PlatformFeature::isOutOfMemory(isolate) returns true @@ -759,7 +744,7 @@ SECTION("test_auth") { v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -770,8 +755,8 @@ SECTION("test_auth") { CHECK((fn_properties->IsFunction())); arangoView->SetInternalField(SLOT_CLASS_TYPE, v8::Integer::New(isolate.get(), WRP_VOCBASE_VIEW_TYPE)); - arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), &logicalView)); - arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), &logicalView)); + arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), logicalView.get())); + arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), logicalView.get())); std::vector> args = { TRI_VPackToV8(isolate.get(), arangodb::velocypack::Parser::fromJson("{ \"key\": \"value\" }")->slice()), }; @@ -958,20 +943,17 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::internal::Isolate::Current()->InitializeLoggingAndCounters(); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -1048,7 +1030,7 @@ SECTION("test_auth") { auto result = v8::Function::Cast(*fn_view)->CallAsFunction(context, fn_view, args.size(), args.data()); CHECK((!result.IsEmpty())); CHECK((result.ToLocalChecked()->IsObject())); - auto v8View = *TRI_UnwrapClass>(result.ToLocalChecked()->ToObject(), WRP_VOCBASE_VIEW_TYPE); + auto* v8View = TRI_UnwrapClass(result.ToLocalChecked()->ToObject(), WRP_VOCBASE_VIEW_TYPE); CHECK((false == !v8View)); CHECK((std::string("testView") == v8View->name())); CHECK((std::string("testViewType") == v8View->type().name())); @@ -1088,7 +1070,7 @@ SECTION("test_auth") { auto result = v8::Function::Cast(*fn_view)->CallAsFunction(context, fn_view, args.size(), args.data()); CHECK((!result.IsEmpty())); CHECK((result.ToLocalChecked()->IsObject())); - auto v8View = *TRI_UnwrapClass>(result.ToLocalChecked()->ToObject(), WRP_VOCBASE_VIEW_TYPE); + auto* v8View = TRI_UnwrapClass(result.ToLocalChecked()->ToObject(), WRP_VOCBASE_VIEW_TYPE); CHECK((false == !v8View)); CHECK((std::string("testView") == v8View->name())); CHECK((std::string("testViewType") == v8View->type().name())); @@ -1108,13 +1090,10 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); char isolateData[64]; // 64 > sizeof(arangodb::V8PlatformFeature::IsolateData) std::memset(isolateData, 0, 64); // otherwise arangodb::V8PlatformFeature::isOutOfMemory(isolate) returns true @@ -1124,7 +1103,7 @@ SECTION("test_auth") { v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -1135,8 +1114,8 @@ SECTION("test_auth") { CHECK((fn_properties->IsFunction())); arangoView->SetInternalField(SLOT_CLASS_TYPE, v8::Integer::New(isolate.get(), WRP_VOCBASE_VIEW_TYPE)); - arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), &logicalView)); - arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), &logicalView)); + arangoView->SetInternalField(SLOT_CLASS, v8::External::New(isolate.get(), logicalView.get())); + arangoView->SetInternalField(SLOT_EXTERNAL, v8::External::New(isolate.get(), logicalView.get())); std::vector> args = { }; @@ -1269,20 +1248,17 @@ SECTION("test_auth") { v8::Isolate::CreateParams isolateParams; ArrayBufferAllocator arrayBufferAllocator; isolateParams.array_buffer_allocator = &arrayBufferAllocator; - std::unique_ptr v8g; // define before creating the 'isolate' so that it is destroyed after 'isolate' auto isolate = std::shared_ptr( v8::Isolate::New(isolateParams), - [](v8::Isolate* p)->void { - p->LowMemoryNotification(); // garbage collection - p->Dispose(); - }); + [](v8::Isolate* p)->void { p->Dispose(); } + ); REQUIRE((nullptr != isolate)); v8::Isolate::Scope isolateScope(isolate.get()); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::internal::Isolate::Current()->InitializeLoggingAndCounters(); // otherwise v8::Isolate::Logger() will fail (called from v8::Exception::Error) v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...) auto context = v8::Context::New(isolate.get()); v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...) - v8g.reset(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' + std::unique_ptr v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()' v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail v8g->_vocbase = &vocbase; auto arangoDBNS = v8::ObjectTemplate::New(isolate.get()); @@ -1342,7 +1318,7 @@ SECTION("test_auth") { CHECK((result.ToLocalChecked()->IsArray())); auto* resultArray = v8::Array::Cast(*result.ToLocalChecked()); CHECK((1U == resultArray->Length())); - auto v8View = *TRI_UnwrapClass>(resultArray->Get(0).As(), WRP_VOCBASE_VIEW_TYPE); + auto* v8View = TRI_UnwrapClass(resultArray->Get(0).As(), WRP_VOCBASE_VIEW_TYPE); CHECK((false == !v8View)); CHECK((std::string("testView1") == v8View->name())); CHECK((std::string("testViewType") == v8View->type().name())); @@ -1364,7 +1340,7 @@ SECTION("test_auth") { CHECK((result.ToLocalChecked()->IsArray())); auto* resultArray = v8::Array::Cast(*result.ToLocalChecked()); CHECK((1U == resultArray->Length())); - auto v8View = *TRI_UnwrapClass>(resultArray->Get(0).As(), WRP_VOCBASE_VIEW_TYPE); + auto* v8View = TRI_UnwrapClass(resultArray->Get(0).As(), WRP_VOCBASE_VIEW_TYPE); CHECK((false == !v8View)); CHECK((std::string("testView1") == v8View->name())); CHECK((std::string("testViewType") == v8View->type().name())); @@ -1406,7 +1382,7 @@ SECTION("test_auth") { CHECK((result.ToLocalChecked()->IsArray())); auto* resultArray = v8::Array::Cast(*result.ToLocalChecked()); CHECK((1U == resultArray->Length())); - auto v8View = *TRI_UnwrapClass>(resultArray->Get(0).As(), WRP_VOCBASE_VIEW_TYPE); + auto* v8View = TRI_UnwrapClass(resultArray->Get(0).As(), WRP_VOCBASE_VIEW_TYPE); CHECK((false == !v8View)); CHECK((std::string("testView1") == v8View->name())); CHECK((std::string("testViewType") == v8View->type().name())); diff --git a/tests/VocBase/vocbase-test.cpp b/tests/VocBase/vocbase-test.cpp index df19a5be56..f762a5359e 100644 --- a/tests/VocBase/vocbase-test.cpp +++ b/tests/VocBase/vocbase-test.cpp @@ -287,7 +287,7 @@ SECTION("test_lookupDataSource") { CHECK((true == !vocbase.lookupView("testViewGUID"))); } - auto* collection = vocbase.createCollection(collectionJson->slice()); + auto collection = vocbase.createCollection(collectionJson->slice()); auto view = vocbase.createView(viewJson->slice()); CHECK((false == collection->deleted()));