1
0
Fork 0

issue 355.4: remove redundant methods and code, use 'cp' instead of 'cmake copy_directory' where possible, use vocbase reference instead of pointer

This commit is contained in:
Vasiliy 2018-04-04 10:53:48 +03:00
parent d2bf3b3878
commit 635db3b409
54 changed files with 745 additions and 844 deletions

View File

@ -163,9 +163,17 @@ if (USE_IRESEARCH)
# cmake will seemingly randomly delete files from ${IRESEARCH_BUILD_DIR} during configuration
# so must copy required files only after the cmake configuration phase is complete, not via file(COPY ...)
# this command must _always_ be executed because the subsequent cmake configuration runs will once again delete files
add_custom_command(OUTPUT "${IRESEARCH_BUILD_DIR}/copy_iresearch.build" # non-existent file
COMMAND ${CMAKE_COMMAND} -E copy_directory "${IRESEARCH_ROOT}.build/" "${IRESEARCH_BUILD_DIR}/"
)
if(MSVC)
add_custom_command(OUTPUT "${IRESEARCH_BUILD_DIR}/copy_iresearch.build" # non-existent file
COMMAND ${CMAKE_COMMAND} -E copy_directory "${IRESEARCH_ROOT}.build/" "${IRESEARCH_BUILD_DIR}/"
)
else()
# 'cmake -E copy_directory' does not preserve timestamps, use 'cp' directly where avalable
add_custom_command(OUTPUT "${IRESEARCH_BUILD_DIR}/copy_iresearch.build" # non-existent file
COMMAND cp -rup "${IRESEARCH_ROOT}.build" "${IRESEARCH_BUILD_DIR}/"
)
endif()
add_custom_target("copy_iresearch.build" ALL
DEPENDS "${IRESEARCH_BUILD_DIR}/copy_iresearch.build"
)

View File

@ -100,7 +100,8 @@ bool RestActionHandler::cancel() {
TRI_action_result_t RestActionHandler::executeAction() {
TRI_action_result_t result = _action->execute(
_vocbase, _request.get(), _response.get(), &_dataLock, &_data);
&_vocbase, _request.get(), _response.get(), &_dataLock, &_data
);
if (!result.isValid) {
if (result.canceled) {

View File

@ -64,7 +64,6 @@ RestAqlHandler::RestAqlHandler(GeneralRequest* request,
_queryRegistry(registries->first),
_traverserRegistry(registries->second),
_qId(0) {
TRI_ASSERT(_vocbase != nullptr);
TRI_ASSERT(_queryRegistry != nullptr);
TRI_ASSERT(_traverserRegistry != nullptr);
}
@ -286,8 +285,14 @@ bool RestAqlHandler::registerSnippets(
// All snippets know all collections.
// The first snippet will provide proper locking
auto query = std::make_unique<Query>(false, _vocbase, planBuilder, options,
(needToLock ? PART_MAIN : PART_DEPENDENT));
auto query = std::make_unique<Query>(
false,
&_vocbase,
planBuilder,
options,
(needToLock ? PART_MAIN : PART_DEPENDENT)
);
try {
query->prepare(_queryRegistry, 0);
} catch (std::exception const& ex) {
@ -366,7 +371,8 @@ bool RestAqlHandler::registerTraverserEngines(VPackSlice const traverserEngines,
for (auto const& te : VPackArrayIterator(traverserEngines)) {
try {
traverser::TraverserEngineID id =
_traverserRegistry->createNew(_vocbase, te, needToLock, ttl);
_traverserRegistry->createNew(&_vocbase, te, needToLock, ttl);
needToLock = false;
TRI_ASSERT(id != 0);
answerBuilder.add(VPackValue(id));
@ -419,9 +425,13 @@ void RestAqlHandler::createQueryFromVelocyPack() {
VelocyPackHelper::getStringValue(querySlice, "part", "");
auto planBuilder = std::make_shared<VPackBuilder>(VPackBuilder::clone(plan));
auto query =
std::make_unique<Query>(false, _vocbase, planBuilder, options,
(part == "main" ? PART_MAIN : PART_DEPENDENT));
auto query = std::make_unique<Query>(
false,
&_vocbase,
planBuilder,
options,
(part == "main" ? PART_MAIN : PART_DEPENDENT)
);
try {
query->prepare(_queryRegistry, 0);
@ -506,9 +516,15 @@ void RestAqlHandler::parseQuery() {
}
auto query = std::make_unique<Query>(
false, _vocbase, QueryString(queryString),
std::shared_ptr<VPackBuilder>(), nullptr, PART_MAIN);
false,
&_vocbase,
QueryString(queryString),
std::shared_ptr<VPackBuilder>(),
nullptr,
PART_MAIN
);
QueryResult res = query->parse();
if (res.code != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "failed to instantiate the Query: " << res.details;
@ -583,8 +599,15 @@ void RestAqlHandler::explainQuery() {
VPackBuilder::clone(querySlice.get("options")));
auto query = std::make_unique<Query>(
false, _vocbase, QueryString(queryString), bindVars, options, PART_MAIN);
false,
&_vocbase,
QueryString(queryString),
bindVars,
options,
PART_MAIN
);
QueryResult res = query->explain();
if (res.code != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "failed to instantiate the Query: " << res.details;
@ -658,8 +681,13 @@ void RestAqlHandler::createQueryFromString() {
VPackBuilder::clone(querySlice.get("options")));
auto query = std::make_unique<Query>(
false, _vocbase, QueryString(queryString), bindVars, options,
(part == "main" ? PART_MAIN : PART_DEPENDENT));
false,
&_vocbase,
QueryString(queryString),
bindVars,
options,
(part == "main" ? PART_MAIN : PART_DEPENDENT)
);
try {
query->prepare(_queryRegistry, 0);
@ -767,26 +795,29 @@ void RestAqlHandler::useQuery(std::string const& operation,
TRI_ASSERT(query->engine() != nullptr);
std::shared_ptr<VPackBuilder> queryBuilder = parseVelocyPackBody();
if (queryBuilder == nullptr) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
return;
}
try {
handleUseQuery(operation, query, queryBuilder->slice());
if (_qId != 0) {
try {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
} catch (...) {
// ignore errors on unregistering
// an error might occur if "shutdown" is called
}
}
} catch (arangodb::basics::Exception const& ex) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
generateError(rest::ResponseCode::SERVER_ERROR, ex.code(), ex.what());
} catch (std::exception const& ex) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed during use of Query: "
<< ex.what();
@ -794,7 +825,7 @@ void RestAqlHandler::useQuery(std::string const& operation,
generateError(rest::ResponseCode::SERVER_ERROR, TRI_ERROR_HTTP_SERVER_ERROR,
ex.what());
} catch (...) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "failed during use of Query: Unknown exception occurred";
@ -880,7 +911,7 @@ void RestAqlHandler::getInfoQuery(std::string const& operation,
answerBody.add("hasMore", VPackValue(hasMore));
} else {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "referenced query not found";
generateError(rest::ResponseCode::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
return;
@ -888,11 +919,11 @@ void RestAqlHandler::getInfoQuery(std::string const& operation,
answerBody.add("error", VPackValue(false));
} catch (arangodb::basics::Exception const& ex) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed during use of query: " << ex.message();
generateError(rest::ResponseCode::SERVER_ERROR, ex.code(), ex.what());
} catch (std::exception const& ex) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "failed during use of query: "
<< ex.what();
@ -900,7 +931,7 @@ void RestAqlHandler::getInfoQuery(std::string const& operation,
generateError(rest::ResponseCode::SERVER_ERROR, TRI_ERROR_HTTP_SERVER_ERROR,
ex.what());
} catch (...) {
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "failed during use of query: Unknown exception occurred";
@ -909,7 +940,7 @@ void RestAqlHandler::getInfoQuery(std::string const& operation,
"an unknown exception occurred");
}
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
sendResponse(rest::ResponseCode::OK, answerBody.slice(),
query->trx()->transactionContext().get());
@ -1002,7 +1033,7 @@ bool RestAqlHandler::findQuery(std::string const& idString, Query*& query) {
// probably need to cycle here until we can get hold of the query
while (++iterations < MaxIterations) {
try {
query = _queryRegistry->open(_vocbase, _qId);
query = _queryRegistry->open(&_vocbase, _qId);
// we got the query (or it was not found - at least no one else
// can now have access to the same query)
break;
@ -1216,10 +1247,10 @@ void RestAqlHandler::handleUseQuery(std::string const& operation, Query* query,
query->addWarningsToVelocyPackObject(answerBuilder);
// return the query to the registry
_queryRegistry->close(_vocbase, _qId);
_queryRegistry->close(&_vocbase, _qId);
// delete the query from the registry
_queryRegistry->destroy(_vocbase, _qId, errorCode);
_queryRegistry->destroy(&_vocbase, _qId, errorCode);
_qId = 0;
} catch (arangodb::basics::Exception const& ex) {
generateError(rest::ResponseCode::SERVER_ERROR, ex.code(), std::string("shutdown lead to an exception: ") + ex.what());

View File

@ -529,27 +529,34 @@ void ClusterInfo::loadPlan() {
try {
std::shared_ptr<LogicalCollection> newCollection;
#ifndef USE_ENTERPRISE
newCollection = std::make_shared<LogicalCollection>(
vocbase, collectionSlice, true);
vocbase, collectionSlice, true, newPlanVersion
);
#else
VPackSlice isSmart = collectionSlice.get("isSmart");
if (isSmart.isTrue()) {
VPackSlice type = collectionSlice.get("type");
if (type.isInteger() && type.getUInt() == TRI_COL_TYPE_EDGE) {
newCollection = std::make_shared<VirtualSmartEdgeCollection>(
vocbase, collectionSlice);
vocbase, collectionSlice, newPlanVersion
);
} else {
newCollection = std::make_shared<SmartVertexCollection>(
vocbase, collectionSlice);
vocbase, collectionSlice, newPlanVersion
);
}
} else {
newCollection = std::make_shared<LogicalCollection>(
vocbase, collectionSlice, true);
vocbase, collectionSlice, true, newPlanVersion
);
}
#endif
newCollection->setPlanVersion(newPlanVersion);
std::string const collectionName = newCollection->name();
auto& collectionName = newCollection->name();
if (isCoordinator && !selectivityEstimates.empty()){
LOG_TOPIC(TRACE, Logger::CLUSTER) << "copy index estimates";
newCollection->clusterIndexEstimates(std::move(selectivityEstimates));
@ -671,7 +678,7 @@ void ClusterInfo::loadPlan() {
try {
const auto newView = LogicalView::create(
*vocbase, viewPairSlice.value, false
*vocbase, viewPairSlice.value, newPlanVersion
);
if (!newView) {
@ -682,7 +689,6 @@ void ClusterInfo::loadPlan() {
<< viewSlice.toJson();
}
newView->setPlanVersion(newPlanVersion);
std::string const viewName = newView->name();
// register with name as well as with id:
databaseViews.emplace(std::make_pair(viewName, newView));

View File

@ -2603,7 +2603,7 @@ std::shared_ptr<LogicalCollection> ClusterMethods::createCollectionOnCoordinator
TRI_col_type_e collectionType, TRI_vocbase_t* vocbase, VPackSlice parameters,
bool ignoreDistributeShardsLikeErrors, bool waitForSyncReplication,
bool enforceReplicationFactor) {
auto col = std::make_unique<LogicalCollection>(vocbase, parameters, true);
auto col = std::make_unique<LogicalCollection>(vocbase, parameters, 0, true);
// Collection is a temporary collection object that undergoes sanity checks etc.
// It is not used anywhere and will be cleaned up after this call.
// Persist collection will return the real object.

View File

@ -229,9 +229,9 @@ static bool SetRequestContext(GeneralRequest* request, void* data) {
vocbase->release();
return false;
}
// the vocbase context is now responsible for releasing the vocbase
request->setRequestContext(VocbaseContext::create(request, vocbase), true);
request->setRequestContext(VocbaseContext::create(request, *vocbase), true);
// the "true" means the request is the owner of the context
return true;

View File

@ -482,30 +482,6 @@ Result IResearchLink::remove(
return true;
}
arangodb::Result IResearchLink::recover() {
if (!_collection) {
return {TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND}; // current link isn't associated with the collection
}
ReadMutex mutex(_mutex); // '_view' can be asynchronously modified
SCOPED_LOCK(mutex); // FIXME TODO check for deadlock
if (!_view) {
return {TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND}; // slice has identifier but the current object does not
}
arangodb::velocypack::Builder link;
link.openObject();
if (!json(link, false)) {
return {TRI_ERROR_INTERNAL};
}
link.close();
// re-insert link into the view
return _view->link(_collection->id(), link.slice());
}
Index::IndexType IResearchLink::type() const {
// TODO: don't use enum
return Index::TRI_IDX_TYPE_IRESEARCH_LINK;
@ -596,4 +572,4 @@ NS_END // arangodb
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -159,13 +159,6 @@ class IResearchLink {
TRI_voc_cid_t value
);
////////////////////////////////////////////////////////////////////////////////
/// @brief recover IResearch Link index in a view by dropping existing and
/// creating a new one
/// @return success
////////////////////////////////////////////////////////////////////////////////
arangodb::Result recover();
////////////////////////////////////////////////////////////////////////////////
/// @brief iResearch Link index type enum value
////////////////////////////////////////////////////////////////////////////////

View File

@ -193,14 +193,48 @@ void ensureLink(
<< "found create index marker, databaseId: '" << dbId
<< "', collectionId: '" << cid << "'";
// re-insert link
if (link->recover().fail()) {
arangodb::velocypack::Builder json;
json.openObject();
if (!link->json(json, false)) {
LOG_TOPIC(ERR, arangodb::iresearch::IResearchFeature::IRESEARCH)
<< "Failed to recover the link '" << iid
<< "Failed to generate jSON definition for link '" << iid
<< "' to the collection '" << cid
<< "' in the database '" << dbId;
return;
}
json.close();
static std::vector<std::string> const EMPTY;
arangodb::SingleCollectionTransaction trx(
arangodb::transaction::StandaloneContext::Create(vocbase),
col->id(),
arangodb::AccessMode::Type::EXCLUSIVE
);
auto res = trx.begin();
bool created;
if (!res.ok()) {
LOG_TOPIC(ERR, arangodb::iresearch::IResearchFeature::IRESEARCH)
<< "Failed to begin transaction while recovering link '" << iid
<< "' to the collection '" << cid
<< "' in the database '" << dbId;
return;
}
// re-insert link
if (!col->dropIndex(link->id())
|| !col->createIndex(&trx, json.slice(), created)
|| !created
|| !trx.commit().ok()) {
LOG_TOPIC(ERR, arangodb::iresearch::IResearchFeature::IRESEARCH)
<< "Failed to recreate the link '" << iid
<< "' to the collection '" << cid
<< "' in the database '" << dbId;
}
}
void dropCollectionFromAllViews(
@ -433,4 +467,4 @@ void IResearchRocksDBRecoveryHelper::LogData(const rocksdb::Slice& blob) {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -882,8 +882,8 @@ IResearchView::IResearchView(
TRI_vocbase_t* vocbase,
arangodb::velocypack::Slice const& info,
arangodb::DatabasePathFeature const& dbPathFeature,
bool isNew
): DBServerLogicalView(vocbase, info, isNew),
uint64_t planVersion
): DBServerLogicalView(vocbase, info, planVersion),
FlushTransaction(toString(*this)),
_asyncMetaRevision(1),
_asyncSelf(irs::memory::make_unique<AsyncSelf>(this)),
@ -1715,42 +1715,10 @@ int IResearchView::insert(
return TRI_ERROR_NO_ERROR;
}
arangodb::Result IResearchView::link(
TRI_voc_cid_t cid,
arangodb::velocypack::Slice const link
) {
auto* vocbase = this->vocbase();
if (!vocbase) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to find vocbase while linking IResearch view '") + std::to_string(id()) + "'"
);
}
arangodb::velocypack::Builder builder;
builder.openObject();
builder.add(
std::to_string(cid),
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Null)
);
if (link.isObject()) {
builder.add(std::to_string(cid), link);
}
builder.close();
std::unordered_set<TRI_voc_cid_t> collections;
return updateLinks(collections, *vocbase, *this, builder.slice());
}
/*static*/ std::shared_ptr<LogicalView> IResearchView::make(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
uint64_t planVersion
) {
auto* feature =
arangodb::iresearch::getFeature<arangodb::DatabasePathFeature>("DatabasePath");
@ -1762,7 +1730,7 @@ arangodb::Result IResearchView::link(
return nullptr;
}
PTR_NAMED(IResearchView, view, &vocbase, info, *feature, isNew);
PTR_NAMED(IResearchView, view, &vocbase, info, *feature, planVersion);
auto& impl = reinterpret_cast<IResearchView&>(*view);
auto& json = info.isObject() ? info : emptyObjectSlice(); // if no 'info' then assume defaults
auto props = json.get("properties");
@ -2120,7 +2088,7 @@ arangodb::Result IResearchView::updateProperties(
if (!meta.init(slice, error, initialMeta, &mask)) {
return arangodb::Result(TRI_ERROR_BAD_PARAMETER, std::move(error));
}
/*FIXME TODO remove?
// FIXME TODO remove once View::updateProperties(...) will be fixed to write
// the update delta into the WAL marker instead of the full persisted state
// below is a very dangerous hack as it allows multiple links from the same
@ -2184,7 +2152,7 @@ arangodb::Result IResearchView::updateProperties(
_meta._collections = std::move(collections);
}
}
*/
// reset non-updatable values to match current meta
meta._collections = _meta._collections;
@ -2299,7 +2267,7 @@ void IResearchView::FlushCallbackUnregisterer::operator()(IResearchView* view) c
}
void IResearchView::verifyKnownCollections() {
std::unordered_set<TRI_voc_cid_t> cids;
auto cids = _meta._collections;
{
static const arangodb::transaction::Options defaults;

View File

@ -188,15 +188,6 @@ class IResearchView final: public arangodb::DBServerLogicalView,
IResearchLinkMeta const& meta
);
////////////////////////////////////////////////////////////////////////////////
/// @brief link the specified 'cid' to the view using the specified 'link'
/// definition (!link.isObject() == remove only)
////////////////////////////////////////////////////////////////////////////////
arangodb::Result link(
TRI_voc_cid_t cid,
arangodb::velocypack::Slice const link
);
///////////////////////////////////////////////////////////////////////////////
/// @brief view factory
/// @returns initialized view object
@ -204,7 +195,7 @@ class IResearchView final: public arangodb::DBServerLogicalView,
static std::shared_ptr<LogicalView> make(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
uint64_t planVersion
);
////////////////////////////////////////////////////////////////////////////////
@ -335,13 +326,10 @@ class IResearchView final: public arangodb::DBServerLogicalView,
TRI_vocbase_t* vocbase,
arangodb::velocypack::Slice const& info,
arangodb::DatabasePathFeature const& dbPathFeature,
bool isNew
uint64_t planVersion
);
//////////////////////////////////////////////////////////////////////////////
/// @brief Called in post-recovery to remove any dangling documents old links
//////////////////////////////////////////////////////////////////////////////
void verifyKnownCollections();
MemoryStore& activeMemoryStore() const;
////////////////////////////////////////////////////////////////////////////////
/// @brief process a finished transaction and release resources held by it
@ -353,7 +341,10 @@ class IResearchView final: public arangodb::DBServerLogicalView,
////////////////////////////////////////////////////////////////////////////////
void registerFlushCallback();
MemoryStore& activeMemoryStore() const;
//////////////////////////////////////////////////////////////////////////////
/// @brief Called in post-recovery to remove any dangling documents old links
//////////////////////////////////////////////////////////////////////////////
void verifyKnownCollections();
std::condition_variable _asyncCondition; // trigger reload of timeout settings for async jobs
std::atomic<size_t> _asyncMetaRevision; // arbitrary meta modification id, async jobs should reload if different
@ -377,4 +368,5 @@ class IResearchView final: public arangodb::DBServerLogicalView,
NS_END // iresearch
NS_END // arangodb
#endif

View File

@ -1,3 +1,26 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2018 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Andrey Abramov
/// @author Vasiliy Nabatchikov
////////////////////////////////////////////////////////////////////////////////
#include "IResearchViewCoordinator.h"
namespace arangodb {
@ -6,12 +29,11 @@ namespace iresearch {
/*static*/ std::shared_ptr<LogicalView> IResearchViewCoordinator::make(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
uint64_t planVersion
) {
// FIXME implement
return nullptr;
}
} // iresearch
} // arangodb

View File

@ -43,7 +43,7 @@ class IResearchViewCoordinator final: public arangodb::LogicalView {
static std::shared_ptr<LogicalView> make(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
uint64_t planVersion
);
bool visitCollections(CollectionVisitor const& visitor) const override {

View File

@ -96,7 +96,8 @@ void InternalRestTraverserHandler::createEngine() {
"Expected an object with traverser information as body parameter");
return;
}
TraverserEngineID id = _registry->createNew(_vocbase, parsedBody->slice(), true);
TraverserEngineID id =
_registry->createNew(&_vocbase, parsedBody->slice(), true);
TRI_ASSERT(id != 0);
VPackBuilder resultBuilder;
resultBuilder.add(VPackValue(id));

View File

@ -2070,7 +2070,7 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
);
}
auto const view = LogicalView::create(*vocbase, it, false);
auto const view = LogicalView::create(*vocbase, it);
if (!view) {
auto const message = "failed to instantiate view '" + name + "'";
@ -3564,4 +3564,4 @@ WalAccess const* MMFilesEngine::walAccess() const {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -249,7 +249,8 @@ void MMFilesRestExportHandler::createCursor() {
// this may throw!
auto collectionExport =
std::make_unique<MMFilesCollectionExport>(_vocbase, name, _restrictions);
std::make_unique<MMFilesCollectionExport>(&_vocbase, name, _restrictions);
collectionExport->run(waitTime, limit);
size_t batchSize =
@ -259,23 +260,28 @@ void MMFilesRestExportHandler::createCursor() {
options, "ttl", 30);
bool count = arangodb::basics::VelocyPackHelper::getBooleanValue(
options, "count", false);
auto cursors = _vocbase->cursorRepository();
auto cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
Cursor* c = nullptr;
{
auto cursor = std::make_unique<MMFilesExportCursor>(_vocbase, TRI_NewTickServer(),
collectionExport.get(), batchSize, ttl, count);
auto cursor = std::make_unique<MMFilesExportCursor>(
&_vocbase,
TRI_NewTickServer(),
collectionExport.get(),
batchSize,
ttl,
count
);
collectionExport.release();
cursor->use();
c = cursors->addCursor(std::move(cursor));
}
TRI_ASSERT(c != nullptr);
TRI_DEFER(cursors->release(c));
resetResponse(rest::ResponseCode::CREATED);
VPackBuffer<uint8_t> buffer;
@ -304,8 +310,7 @@ void MMFilesRestExportHandler::modifyCursor() {
}
std::string const& id = suffixes[0];
auto cursors = _vocbase->cursorRepository();
auto cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
auto cursorId = static_cast<arangodb::CursorId>(
@ -353,8 +358,7 @@ void MMFilesRestExportHandler::deleteCursor() {
}
std::string const& id = suffixes[0];
CursorRepository* cursors = _vocbase->cursorRepository();
CursorRepository* cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
auto cursorId = static_cast<arangodb::CursorId>(

View File

@ -67,7 +67,9 @@ void MMFilesRestReplicationHandler::insertClient(
TRI_server_id_t serverId = static_cast<TRI_server_id_t>(StringUtils::uint64(value));
if (serverId > 0) {
_vocbase->updateReplicationClient(serverId, lastServedTick, InitialSyncer::defaultBatchTimeout);
_vocbase.updateReplicationClient(
serverId, lastServedTick, InitialSyncer::defaultBatchTimeout
);
}
}
}
@ -97,7 +99,7 @@ void MMFilesRestReplicationHandler::handleCommandBatch() {
TRI_voc_tick_t id;
MMFilesEngine* engine = static_cast<MMFilesEngine*>(EngineSelectorFeature::ENGINE);
int res = engine->insertCompactionBlocker(_vocbase, ttl, id);
int res = engine->insertCompactionBlocker(&_vocbase, ttl, id);
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
@ -131,7 +133,7 @@ void MMFilesRestReplicationHandler::handleCommandBatch() {
// now extend the blocker
MMFilesEngine* engine = static_cast<MMFilesEngine*>(EngineSelectorFeature::ENGINE);
int res = engine->extendCompactionBlocker(_vocbase, id, ttl);
int res = engine->extendCompactionBlocker(&_vocbase, id, ttl);
if (res == TRI_ERROR_NO_ERROR) {
resetResponse(rest::ResponseCode::NO_CONTENT);
@ -147,7 +149,7 @@ void MMFilesRestReplicationHandler::handleCommandBatch() {
static_cast<TRI_voc_tick_t>(StringUtils::uint64(suffixes[1]));
MMFilesEngine* engine = static_cast<MMFilesEngine*>(EngineSelectorFeature::ENGINE);
int res = engine->removeCompactionBlocker(_vocbase, id);
int res = engine->removeCompactionBlocker(&_vocbase, id);
if (res == TRI_ERROR_NO_ERROR) {
resetResponse(rest::ResponseCode::NO_CONTENT);
@ -201,10 +203,11 @@ void MMFilesRestReplicationHandler::handleCommandBarrier() {
return;
}
TRI_voc_tick_t id =
MMFilesLogfileManager::instance()->addLogfileBarrier(_vocbase->id(), minTick, ttl);
TRI_voc_tick_t id = MMFilesLogfileManager::instance()->addLogfileBarrier(
_vocbase.id(), minTick, ttl
);
VPackBuilder b;
b.add(VPackValue(VPackValueType::Object));
std::string const idString(std::to_string(id));
b.add("id", VPackValue(idString));
@ -372,7 +375,7 @@ void MMFilesRestReplicationHandler::handleCommandLoggerFollow() {
std::string const& value6 = _request->value("collection", found);
if (found) {
auto c = _vocbase->lookupCollection(value6);
auto c = _vocbase.lookupCollection(value6);
if (c == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
@ -389,7 +392,8 @@ void MMFilesRestReplicationHandler::handleCommandLoggerFollow() {
tickStart);
}
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
// initialize the dump container
MMFilesReplicationDumpContext dump(ctx,
static_cast<size_t>(determineChunkSize()),
@ -506,7 +510,8 @@ void MMFilesRestReplicationHandler::handleCommandDetermineOpenTransactions() {
return;
}
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
// initialize the dump container
MMFilesReplicationDumpContext dump(
ctx, static_cast<size_t>(determineChunkSize()), false, 0);
@ -601,14 +606,16 @@ void MMFilesRestReplicationHandler::handleCommandInventory() {
// collections and indexes
VPackBuilder inventoryBuilder;
if (global) {
DatabaseFeature::DATABASE->inventory(inventoryBuilder, tick, nameFilter);
} else {
_vocbase->inventory(inventoryBuilder, tick, nameFilter);
_vocbase.inventory(inventoryBuilder, tick, nameFilter);
}
VPackSlice const inventory = inventoryBuilder.slice();
VPackSlice const inventory = inventoryBuilder.slice();
VPackBuilder builder;
builder.openObject();
if (global) {
@ -661,7 +668,7 @@ void MMFilesRestReplicationHandler::handleCommandCreateKeys() {
tickEnd = static_cast<TRI_voc_tick_t>(StringUtils::uint64(value));
}
auto c = _vocbase->lookupCollection(collection);
auto c = _vocbase.lookupCollection(collection);
if (c == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
@ -670,7 +677,7 @@ void MMFilesRestReplicationHandler::handleCommandCreateKeys() {
}
auto guard =
std::make_unique<arangodb::CollectionGuard>(_vocbase, c->id(), false);
std::make_unique<arangodb::CollectionGuard>(&_vocbase, c->id(), false);
arangodb::LogicalCollection* col = guard->collection();
TRI_ASSERT(col != nullptr);
@ -678,22 +685,23 @@ void MMFilesRestReplicationHandler::handleCommandCreateKeys() {
// turn off the compaction for the collection
MMFilesEngine* engine = static_cast<MMFilesEngine*>(EngineSelectorFeature::ENGINE);
TRI_voc_tick_t id;
int res = engine->insertCompactionBlocker(_vocbase, 1200.0, id);
int res = engine->insertCompactionBlocker(&_vocbase, 1200.0, id);
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
// initialize a container with the keys
auto keys =
std::make_unique<MMFilesCollectionKeys>(_vocbase, std::move(guard), id, 300.0);
auto keys = std::make_unique<MMFilesCollectionKeys>(
&_vocbase, std::move(guard), id, 300.0
);
std::string const idString(std::to_string(keys->id()));
keys->create(tickEnd);
size_t const count = keys->count();
auto keysRepository = _vocbase->collectionKeys();
size_t const count = keys->count();
auto keysRepository = _vocbase.collectionKeys();
keysRepository->store(keys.get());
keys.release();
@ -734,7 +742,7 @@ void MMFilesRestReplicationHandler::handleCommandGetKeys() {
std::string const& id = suffixes[1];
auto keysRepository = _vocbase->collectionKeys();
auto keysRepository = _vocbase.collectionKeys();
TRI_ASSERT(keysRepository != nullptr);
auto collectionKeysId =
@ -843,12 +851,11 @@ void MMFilesRestReplicationHandler::handleCommandFetchKeys() {
std::string const& id = suffixes[1];
auto keysRepository = _vocbase->collectionKeys();
auto keysRepository = _vocbase.collectionKeys();
TRI_ASSERT(keysRepository != nullptr);
auto collectionKeysId =
static_cast<CollectionKeysId>(arangodb::basics::StringUtils::uint64(id));
auto collectionKeys = keysRepository->find(collectionKeysId);
if (collectionKeys == nullptr) {
@ -858,8 +865,9 @@ void MMFilesRestReplicationHandler::handleCommandFetchKeys() {
}
try {
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
VPackBuilder resultBuilder(ctx->getVPackOptions());
resultBuilder.openArray();
if (keys) {
@ -901,7 +909,7 @@ void MMFilesRestReplicationHandler::handleCommandRemoveKeys() {
std::string const& id = suffixes[1];
auto keys = _vocbase->collectionKeys();
auto keys = _vocbase.collectionKeys();
TRI_ASSERT(keys != nullptr);
auto collectionKeysId =
@ -991,7 +999,7 @@ void MMFilesRestReplicationHandler::handleCommandDump() {
withTicks = StringUtils::boolean(value7);
}
auto c = _vocbase->lookupCollection(collection);
auto c = _vocbase.lookupCollection(collection);
if (c == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
@ -1001,7 +1009,7 @@ void MMFilesRestReplicationHandler::handleCommandDump() {
ExecContext const* exec = ExecContext::CURRENT;
if (exec != nullptr &&
!exec->canUseCollection(_vocbase->name(), c->name(), auth::Level::RO)) {
!exec->canUseCollection(_vocbase.name(), c->name(), auth::Level::RO)) {
generateError(rest::ResponseCode::FORBIDDEN,
TRI_ERROR_FORBIDDEN);
return;
@ -1022,11 +1030,12 @@ void MMFilesRestReplicationHandler::handleCommandDump() {
}
}
arangodb::CollectionGuard guard(_vocbase, c->id(), false);
arangodb::CollectionGuard guard(&_vocbase, c->id(), false);
arangodb::LogicalCollection* col = guard.collection();
TRI_ASSERT(col != nullptr);
auto ctx = std::make_shared<transaction::StandaloneContext>(_vocbase);
auto ctx = std::make_shared<transaction::StandaloneContext>(&_vocbase);
// initialize the dump container
MMFilesReplicationDumpContext dump(ctx,
static_cast<size_t>(determineChunkSize()),

View File

@ -62,7 +62,7 @@ RestStatus RestAqlUserFunctionsHandler::execute() {
// call internal function that does the work
bool replacedExisting = false;
auto res = registerUserFunction(_vocbase, body, replacedExisting);
auto res = registerUserFunction(&_vocbase, body, replacedExisting);
if (res.ok()) {
auto code = (replacedExisting)? rest::ResponseCode::OK : rest::ResponseCode::CREATED;
@ -92,9 +92,9 @@ RestStatus RestAqlUserFunctionsHandler::execute() {
bool deleteGroup = extractBooleanParameter(StaticStrings::Group, false);
if (deleteGroup) {
res = unregisterUserFunctionsGroup(_vocbase, suffixes[0], deletedCount);
res = unregisterUserFunctionsGroup(&_vocbase, suffixes[0], deletedCount);
} else { // delete single
res = unregisterUserFunction(_vocbase,suffixes[0]);
res = unregisterUserFunction(&_vocbase, suffixes[0]);
++deletedCount;
}
@ -137,7 +137,8 @@ RestStatus RestAqlUserFunctionsHandler::execute() {
// internal get
VPackBuilder arrayOfFunctions;
auto res = toArrayUserFunctions(_vocbase, functionNamespace, arrayOfFunctions);
auto res =
toArrayUserFunctions(&_vocbase, functionNamespace, arrayOfFunctions);
// error handling
if (res.ok()) {

View File

@ -81,7 +81,7 @@ void RestCollectionHandler::handleCommandGet() {
bool excludeSystem = _request->parsedValue("excludeSystem", false);
builder.openArray();
methods::Collections::enumerate(_vocbase, [&](LogicalCollection* coll) {
methods::Collections::enumerate(&_vocbase, [&](LogicalCollection* coll) {
ExecContext const* exec = ExecContext::CURRENT;
bool canUse = exec == nullptr ||
exec->canUseCollection(coll->name(), auth::Level::RO);
@ -120,7 +120,9 @@ void RestCollectionHandler::handleCommandGet() {
std::string const& sub = suffixes[1];
bool skipGenerate = false;
Result found = methods::Collections::lookup(
_vocbase, name, [&](LogicalCollection* coll) {
&_vocbase,
name,
[&](LogicalCollection* coll) {
if (sub == "checksum") {
// /_api/collection/<identifier>/checksum
if (!coll->isLocal()) {
@ -161,7 +163,8 @@ void RestCollectionHandler::handleCommandGet() {
// /_api/collection/<identifier>/revision
TRI_voc_rid_t revisionId;
Result res =
methods::Collections::revisionId(_vocbase, coll, revisionId);
methods::Collections::revisionId(&_vocbase, coll, revisionId);
if (res.fail()) {
THROW_ARANGO_EXCEPTION(res);
}
@ -259,13 +262,19 @@ void RestCollectionHandler::handleCommandPost() {
std::string const& name = nameSlice.copyString();
VPackBuilder builder;
Result res = methods::Collections::create(
_vocbase, name, type, parameters, waitForSyncReplication, enforceReplicationFactor,
&_vocbase,
name,
type,
parameters,
waitForSyncReplication,
enforceReplicationFactor,
[&](LogicalCollection* coll) {
collectionRepresentation(builder, coll->name(), /*showProperties*/ true,
/*showFigures*/ false, /*showCount*/ false,
/*aggregateCount*/ false);
});
}
);
if (res.ok()) {
generateOk(rest::ResponseCode::OK, builder);
} else {
@ -296,9 +305,12 @@ void RestCollectionHandler::handleCommandPut() {
Result res;
VPackBuilder builder;
Result found = methods::Collections::lookup(
_vocbase, name, [&](LogicalCollection* coll) {
&_vocbase,
name,
[&](LogicalCollection* coll) {
if (sub == "load") {
res = methods::Collections::load(_vocbase, coll);
res = methods::Collections::load(&_vocbase, coll);
if (res.ok()) {
bool cc = VelocyPackHelper::getBooleanValue(body, "count", true);
collectionRepresentation(builder, name, /*showProperties*/ false,
@ -307,13 +319,15 @@ 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) {
EngineSelectorFeature::ENGINE->flushWal(false, false, false);
}
res = methods::Collections::unload(_vocbase, coll);
res = methods::Collections::unload(&_vocbase, coll);
if (res.ok()) {
collectionRepresentation(builder, name, /*showProperties*/ false,
/*showFigures*/ false, /*showCount*/ false,
@ -325,7 +339,7 @@ void RestCollectionHandler::handleCommandPut() {
opts.isSynchronousReplicationFrom =
_request->value("isSynchronousReplication");
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(
ctx, coll->id(), AccessMode::Type::EXCLUSIVE
);
@ -372,7 +386,7 @@ void RestCollectionHandler::handleCommandPut() {
}
} else if (sub == "rotate") {
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(
ctx, coll->id(), AccessMode::Type::WRITE
);
@ -387,15 +401,17 @@ 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);
obj->add("result", VPackValue(res.ok()));
} else {
res.reset(TRI_ERROR_HTTP_NOT_FOUND,
"expecting one of the actions 'load', 'unload', 'truncate',"
" 'properties', 'rename', 'loadIndexesIntoMemory'");
}
});
}
);
if (found.fail()) {
generateError(found);
@ -421,12 +437,16 @@ void RestCollectionHandler::handleCommandDelete() {
VPackBuilder builder;
Result res;
Result found = methods::Collections::lookup(
_vocbase, name, [&](LogicalCollection* coll) {
&_vocbase,
name,
[&](LogicalCollection* 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, allowDropSystem, -1.0);
}
);
if (found.fail()) {
generateError(found);
} else if (res.fail()) {
@ -445,10 +465,13 @@ void RestCollectionHandler::collectionRepresentation(
VPackBuilder& builder, std::string const& name, bool showProperties,
bool showFigures, bool showCount, bool aggregateCount) {
Result r = methods::Collections::lookup(
_vocbase, name, [&](LogicalCollection* coll) {
&_vocbase,
name,
[&](LogicalCollection* coll) {
collectionRepresentation(builder, coll, showProperties, showFigures,
showCount, aggregateCount);
});
}
);
if (r.fail()) {
THROW_ARANGO_EXCEPTION(r);
@ -474,6 +497,7 @@ void RestCollectionHandler::collectionRepresentation(
builder.add("globallyUniqueId", VPackValue(coll->globallyUniqueId()));
} else {
Result res = methods::Collections::properties(coll, builder);
if (res.fail()) {
THROW_ARANGO_EXCEPTION(res);
}
@ -485,17 +509,22 @@ void RestCollectionHandler::collectionRepresentation(
}
if (showCount) {
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, coll->id(), AccessMode::Type::READ);
Result res = trx.begin();
if (res.fail()) {
THROW_ARANGO_EXCEPTION(res);
}
OperationResult opRes = trx.count(coll->name(), aggregateCount);
trx.finish(opRes.result);
if (opRes.fail()) {
THROW_ARANGO_EXCEPTION(opRes.result);
}
builder.add("count", opRes.slice());
}

View File

@ -108,7 +108,7 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
auto options = std::make_shared<VPackBuilder>(buildOptions(slice));
VPackSlice opts = options->slice();
CursorRepository* cursors = _vocbase->cursorRepository();
CursorRepository* cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
bool stream = VelocyPackHelper::getBooleanValue(opts, "stream", false);
@ -133,9 +133,14 @@ void RestCursorHandler::processQuery(VPackSlice const& slice) {
char const* queryStr = querySlice.getString(l);
TRI_ASSERT(l > 0);
aql::Query query(false, _vocbase,
arangodb::aql::QueryString(queryStr, static_cast<size_t>(l)),
bindVarsBuilder, options, arangodb::aql::PART_MAIN);
aql::Query query(
false,
&_vocbase,
arangodb::aql::QueryString(queryStr, static_cast<size_t>(l)),
bindVarsBuilder,
options,
arangodb::aql::PART_MAIN
);
registerQuery(&query);
aql::QueryResult queryResult = query.execute(_queryRegistry);
@ -412,7 +417,7 @@ void RestCursorHandler::modifyQueryCursor() {
std::string const& id = suffixes[0];
auto cursors = _vocbase->cursorRepository();
auto cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
auto cursorId = static_cast<arangodb::CursorId>(
@ -450,7 +455,7 @@ void RestCursorHandler::deleteQueryCursor() {
std::string const& id = suffixes[0];
auto cursors = _vocbase->cursorRepository();
auto cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
auto cursorId = static_cast<arangodb::CursorId>(

View File

@ -44,9 +44,10 @@ RestStatus RestDatabaseHandler::execute() {
if (type == rest::RequestType::GET) {
return getDatabases();
} else if (type == rest::RequestType::POST) {
if (!_vocbase->isSystem()) {
if (!_vocbase.isSystem()) {
generateError(GeneralResponse::responseCode(TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE),
TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
return RestStatus::DONE;
}
return createDatabase();
@ -55,6 +56,7 @@ RestStatus RestDatabaseHandler::execute() {
} else {
generateError(rest::ResponseCode::METHOD_NOT_ALLOWED,
TRI_ERROR_HTTP_METHOD_NOT_ALLOWED);
return RestStatus::DONE;
}
}
@ -85,9 +87,11 @@ RestStatus RestDatabaseHandler::getDatabases() {
}
builder.close();
} else if (suffixes[0] == "current") {
Result res = methods::Databases::info(_vocbase, builder);
Result res = methods::Databases::info(&_vocbase, builder);
if (!res.ok()) {
generateError(rest::ResponseCode::BAD, res.errorNumber());
return RestStatus::DONE;
}
}
@ -140,9 +144,10 @@ RestStatus RestDatabaseHandler::createDatabase() {
// / @brief was docuBlock JSF_get_api_database_delete
// //////////////////////////////////////////////////////////////////////////////
RestStatus RestDatabaseHandler::deleteDatabase() {
if (!_vocbase->isSystem()) {
if (!_vocbase.isSystem()) {
generateError(GeneralResponse::responseCode(TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE),
TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
return RestStatus::DONE;
}
std::vector<std::string> const& suffixes = _request->suffixes();
@ -152,7 +157,8 @@ RestStatus RestDatabaseHandler::deleteDatabase() {
}
std::string const& dbName = suffixes[0];
Result res = methods::Databases::drop(_vocbase, dbName);
Result res = methods::Databases::drop(&_vocbase, dbName);
if (res.ok()) {
generateOk(rest::ResponseCode::OK, VPackSlice::trueSlice());
} else {

View File

@ -126,9 +126,10 @@ bool RestDocumentHandler::createDocument() {
opOptions.isSynchronousReplicationFrom);
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::WRITE);
bool const isMultiple = body.isArray();
if (!isMultiple) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
}
@ -231,7 +232,7 @@ bool RestDocumentHandler::readSingleDocument(bool generateBody) {
VPackSlice search = builder.slice();
// find and load collection given by name or identifier
auto ctx(transaction::StandaloneContext::Create(_vocbase));
auto ctx(transaction::StandaloneContext::Create(&_vocbase));
SingleCollectionTransaction trx(ctx, collection, AccessMode::Type::READ);
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
@ -421,7 +422,7 @@ bool RestDocumentHandler::modifyDocument(bool isPatch) {
}
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::WRITE);
if (!isArrayCase) {
trx.addHint(transaction::Hints::Hint::SINGLE_OPERATION);
@ -516,7 +517,7 @@ bool RestDocumentHandler::deleteDocument() {
extractStringParameter(StaticStrings::IsSynchronousReplicationString,
opOptions.isSynchronousReplicationFrom);
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
VPackBuilder builder;
VPackSlice search;
std::shared_ptr<VPackBuilder> builderPtr;
@ -604,7 +605,7 @@ bool RestDocumentHandler::readManyDocuments() {
opOptions.ignoreRevs =
extractBooleanParameter(StaticStrings::IgnoreRevsString, true);
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName,
AccessMode::Type::READ);

View File

@ -149,7 +149,7 @@ bool RestEdgesHandler::parseDirection(TRI_edge_direction_e& direction) {
}
bool RestEdgesHandler::validateCollection(std::string const& name) {
CollectionNameResolver resolver(_vocbase);
CollectionNameResolver resolver(&_vocbase);
auto collection = resolver.getCollection(name);
auto colType = collection ? collection->type() : TRI_COL_TYPE_UNKNOWN;
@ -207,8 +207,14 @@ bool RestEdgesHandler::readEdges() {
VPackBuilder resultDocument(buffer);
resultDocument.openObject();
int res = getFilteredEdgesOnCoordinator(
_vocbase->name(), collectionName, vertexString, direction,
responseCode, resultDocument);
_vocbase.name(),
collectionName,
vertexString,
direction,
responseCode,
resultDocument
);
if (res != TRI_ERROR_NO_ERROR) {
generateError(responseCode, res);
return false;
@ -224,7 +230,7 @@ bool RestEdgesHandler::readEdges() {
}
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::READ);
// .............................................................................
@ -345,21 +351,28 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() {
rest::ResponseCode responseCode;
VPackBuffer<uint8_t> buffer;
VPackBuilder resultDocument(buffer);
resultDocument.openObject();
for (auto const& it : VPackArrayIterator(body)) {
if (it.isString()) {
std::string vertexString(it.copyString());
int res = getFilteredEdgesOnCoordinator(
_vocbase->name(), collectionName, vertexString, direction,
responseCode, resultDocument);
_vocbase.name(),
collectionName,
vertexString,
direction,
responseCode,
resultDocument
);
if (res != TRI_ERROR_NO_ERROR) {
generateError(responseCode, res);
return false;
}
}
}
resultDocument.add(StaticStrings::Error, VPackValue(false));
resultDocument.add("code", VPackValue(200));
resultDocument.close();
@ -369,7 +382,7 @@ bool RestEdgesHandler::readEdgesForMultipleVertices() {
}
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::READ);
// .............................................................................

View File

@ -60,13 +60,7 @@ void RestEndpointHandler::retrieveEndpoints() {
application_features::ApplicationServer::getFeature<HttpEndpointProvider>(
"Endpoint");
if (_vocbase == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return;
}
if (!_vocbase->isSystem()) {
if (!_vocbase.isSystem()) {
generateError(rest::ResponseCode::FORBIDDEN,
TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
return;

View File

@ -64,18 +64,13 @@ void RestExplainHandler::explainQuery() {
return;
}
if (_vocbase == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return;
}
bool parseSuccess = true;
std::shared_ptr<VPackBuilder> parsedBody = parseVelocyPackBody(parseSuccess);
if (!parseSuccess) {
return;
}
VPackSlice body = parsedBody.get()->slice();
auto badParamError = [&](std::string const& msg) -> void {
@ -114,10 +109,14 @@ void RestExplainHandler::explainQuery() {
auto optionsBuilder = std::make_shared<VPackBuilder>();
optionsBuilder->add(optionsSlice);
arangodb::aql::Query query(false, _vocbase, aql::QueryString(queryString),
bindBuilder, optionsBuilder,
arangodb::aql::PART_MAIN);
arangodb::aql::Query query(
false,
&_vocbase,
aql::QueryString(queryString),
bindBuilder,
optionsBuilder,
arangodb::aql::PART_MAIN
);
auto queryResult = query.explain();
if (queryResult.code != TRI_ERROR_NO_ERROR) {

View File

@ -360,7 +360,7 @@ bool RestImportHandler::createFromJson(std::string const& type) {
}
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::WRITE);
// .............................................................................
@ -565,7 +565,7 @@ bool RestImportHandler::createFromVPack(std::string const& type) {
}
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::WRITE);
// .............................................................................
@ -746,7 +746,7 @@ bool RestImportHandler::createFromKeyValueList() {
current = next + 1;
// find and load collection given by name or identifier
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, collectionName, AccessMode::Type::WRITE);
// .............................................................................

View File

@ -62,12 +62,13 @@ LogicalCollection* RestIndexHandler::collection(
if (!cName.empty()) {
if (ServerState::instance()->isCoordinator()) {
try {
coll = ClusterInfo::instance()->getCollection(_vocbase->name(), cName);
coll = ClusterInfo::instance()->getCollection(_vocbase.name(), cName);
return coll.get();
} catch (...) {
}
} else {
return _vocbase->lookupCollection(cName).get();
return _vocbase.lookupCollection(cName).get();
}
}

View File

@ -74,7 +74,8 @@ RestStatus RestPregelHandler::execute() {
}
*/
} else if (suffix[0] == Utils::workerPrefix) {
PregelFeature::handleWorkerRequest(_vocbase, suffix[1], body, response);
PregelFeature::handleWorkerRequest(&_vocbase, suffix[1], body, response);
generateResult(rest::ResponseCode::OK, response.slice());
/* if (buffer.empty()) {
resetResponse(rest::ResponseCode::OK);

View File

@ -77,9 +77,9 @@ RestStatus RestQueryHandler::execute() {
}
bool RestQueryHandler::readQueryProperties() {
auto queryList = _vocbase->queryList();
auto queryList = _vocbase.queryList();
VPackBuilder result;
result.add(VPackValue(VPackValueType::Object));
result.add(StaticStrings::Error, VPackValue(false));
result.add(StaticStrings::Code, VPackValue((int)rest::ResponseCode::OK));
@ -99,10 +99,10 @@ bool RestQueryHandler::readQueryProperties() {
}
bool RestQueryHandler::readQuery(bool slow) {
auto queryList = _vocbase->queryList();
auto queryList = _vocbase.queryList();
auto queries = slow ? queryList->listSlow() : queryList->listCurrent();
VPackBuilder result;
result.add(VPackValue(VPackValueType::Array));
for (auto const& q : queries) {
@ -157,10 +157,11 @@ bool RestQueryHandler::readQuery() {
}
bool RestQueryHandler::deleteQuerySlow() {
auto queryList = _vocbase->queryList();
auto queryList = _vocbase.queryList();
queryList->clearSlow();
VPackBuilder result;
result.add(VPackValue(VPackValueType::Object));
result.add(StaticStrings::Error, VPackValue(false));
result.add(StaticStrings::Code, VPackValue((int)rest::ResponseCode::OK));
@ -173,7 +174,7 @@ bool RestQueryHandler::deleteQuerySlow() {
bool RestQueryHandler::deleteQuery(std::string const& name) {
auto id = StringUtils::uint64(name);
auto queryList = _vocbase->queryList();
auto queryList = _vocbase.queryList();
TRI_ASSERT(queryList != nullptr);
auto res = queryList->kill(id);
@ -238,8 +239,7 @@ bool RestQueryHandler::replaceProperties() {
"expecting a JSON object as body");
};
auto queryList = _vocbase->queryList();
auto queryList = _vocbase.queryList();
bool enabled = queryList->enabled();
bool trackSlowQueries = queryList->trackSlowQueries();
bool trackBindVars = queryList->trackBindVars();
@ -316,9 +316,14 @@ bool RestQueryHandler::parseQuery() {
std::string const queryString =
VelocyPackHelper::checkAndGetStringValue(body, "query");
Query query(false, _vocbase, QueryString(queryString),
nullptr, nullptr, PART_MAIN);
Query query(
false,
&_vocbase,
QueryString(queryString),
nullptr,
nullptr,
PART_MAIN
);
auto parseResult = query.parse();
if (parseResult.code != TRI_ERROR_NO_ERROR) {

View File

@ -165,10 +165,11 @@ RestReplicationHandler::~RestReplicationHandler() {}
////////////////////////////////////////////////////////////////////////////////
bool RestReplicationHandler::isCoordinatorError() {
if (_vocbase->type() == TRI_VOCBASE_TYPE_COORDINATOR) {
if (_vocbase.type() == TRI_VOCBASE_TYPE_COORDINATOR) {
generateError(rest::ResponseCode::NOT_IMPLEMENTED,
TRI_ERROR_CLUSTER_UNSUPPORTED,
"replication API is not supported on a coordinator");
return true;
}
@ -484,10 +485,11 @@ void RestReplicationHandler::handleCommandMakeSlave() {
}
std::string databaseName;
if (!isGlobal) {
databaseName = _vocbase->name();
databaseName = _vocbase.name();
}
ReplicationApplierConfiguration configuration = ReplicationApplierConfiguration::fromVelocyPack(parsedBody->slice(), databaseName);
configuration._skipCreateDrop = false;
@ -887,18 +889,19 @@ Result RestReplicationHandler::processRestoreCollection(
}
grantTemporaryRights();
auto* col = _vocbase->lookupCollection(name).get();
auto* col = _vocbase.lookupCollection(name).get();
// drop an existing collection if it exists
if (col != nullptr) {
if (dropExisting) {
Result res = _vocbase->dropCollection(col, true, -1.0);
Result res = _vocbase.dropCollection(col, true, -1.0);
if (res.errorNumber() == TRI_ERROR_FORBIDDEN) {
// some collections must not be dropped
// instead, truncate them
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(
ctx, col->id(), AccessMode::Type::EXCLUSIVE
);
@ -937,8 +940,10 @@ Result RestReplicationHandler::processRestoreCollection(
if (name[0] != '_' && exe != nullptr && !exe->isSuperuser() &&
ServerState::instance()->isSingleServer()) {
AuthenticationFeature* af = AuthenticationFeature::instance();
af->userManager()->updateUser(exe->user(), [&](auth::User& entry) {
entry.grantCollection(_vocbase->name(), col->name(), auth::Level::RW);
entry.grantCollection(_vocbase.name(), col->name(), auth::Level::RW);
return TRI_ERROR_NO_ERROR;
});
}
@ -977,8 +982,7 @@ Result RestReplicationHandler::processRestoreCollectionCoordinator(
return Result();
}
std::string dbName = _vocbase->name();
auto& dbName = _vocbase.name();
ClusterInfo* ci = ClusterInfo::instance();
try {
@ -1083,10 +1087,15 @@ Result RestReplicationHandler::processRestoreCollectionCoordinator(
// in the replication case enforcing the replication factor is absolutely
// not desired, so it is hardcoded to false
auto col = ClusterMethods::createCollectionOnCoordinator(
collectionType, _vocbase, merged, ignoreDistributeShardsLikeErrors,
createWaitsForSyncReplication, false);
collectionType,
&_vocbase,
merged,
ignoreDistributeShardsLikeErrors,
createWaitsForSyncReplication,
false
);
TRI_ASSERT(col != nullptr);
ExecContext const* exe = ExecContext::CURRENT;
if (name[0] != '_' && exe != nullptr && !exe->isSuperuser()) {
AuthenticationFeature* af = AuthenticationFeature::instance();
@ -1117,8 +1126,7 @@ Result RestReplicationHandler::processRestoreData(std::string const& colName) {
// We need to handle the _users in a special way
return processRestoreUsersBatch(colName);
}
auto ctx =
transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, colName, AccessMode::Type::WRITE);
trx.addHint(transaction::Hints::Hint::RECOVERY); // to turn off waitForSync!
@ -1262,9 +1270,14 @@ Result RestReplicationHandler::processRestoreUsersBatch(
bindVars->close(); // restored
bindVars->close(); // bindVars
arangodb::aql::Query query(false, _vocbase, arangodb::aql::QueryString(aql),
bindVars, nullptr, arangodb::aql::PART_MAIN);
arangodb::aql::Query query(
false,
&_vocbase,
arangodb::aql::QueryString(aql),
bindVars,
nullptr,
arangodb::aql::PART_MAIN
);
auto queryRegistry = QueryRegistryFeature::QUERY_REGISTRY;
TRI_ASSERT(queryRegistry != nullptr);
@ -1526,13 +1539,12 @@ int RestReplicationHandler::processRestoreIndexes(VPackSlice const& collection,
int res = TRI_ERROR_NO_ERROR;
grantTemporaryRights();
READ_LOCKER(readLocker, _vocbase->_inventoryLock);
READ_LOCKER(readLocker, _vocbase._inventoryLock);
// look up the collection
try {
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(ctx, name, AccessMode::Type::EXCLUSIVE);
Result res = trx.begin();
if (!res.ok()) {
@ -1639,19 +1651,21 @@ int RestReplicationHandler::processRestoreIndexesCoordinator(
return TRI_ERROR_NO_ERROR;
}
std::string dbName = _vocbase->name();
auto& dbName = _vocbase.name();
// in a cluster, we only look up by name:
ClusterInfo* ci = ClusterInfo::instance();
std::shared_ptr<LogicalCollection> col;
try {
col = ci->getCollection(dbName, name);
} catch (...) {
errorMsg = "could not find collection '" + name + "'";
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
}
TRI_ASSERT(col != nullptr);
auto cluster = application_features::ApplicationServer::getFeature<ClusterFeature>("Cluster");
int res = TRI_ERROR_NO_ERROR;
@ -1725,12 +1739,13 @@ void RestReplicationHandler::handleCommandSync() {
"<endpoint> must be a valid endpoint");
return;
}
std::string dbname = isGlobal ? "" : _vocbase->name();
std::string dbname = isGlobal ? "" : _vocbase.name();
auto config = ReplicationApplierConfiguration::fromVelocyPack(body, dbname);
// will throw if invalid
config.validate();
double waitForSyncTimeout = VelocyPackHelper::getNumericValue(body, "waitForSyncTimeout", 5.0);
// wait until all data in current logfile got synced
@ -1743,7 +1758,7 @@ void RestReplicationHandler::handleCommandSync() {
if (isGlobal) {
syncer.reset(new GlobalInitialSyncer(config));
} else {
syncer.reset(new DatabaseInitialSyncer(_vocbase, config));
syncer.reset(new DatabaseInitialSyncer(&_vocbase, config));
}
Result r = syncer->run(config._incremental);
@ -1820,17 +1835,18 @@ void RestReplicationHandler::handleCommandApplierSetConfig() {
// error already created
return;
}
std::string databaseName;
if (!isGlobal) {
databaseName = _vocbase->name();
databaseName = _vocbase.name();
}
auto config = ReplicationApplierConfiguration::fromVelocyPack(applier->configuration(),
parsedBody->slice(), databaseName);
// will throw if invalid
config.validate();
applier->reconfigure(config);
handleCommandApplierGetConfig();
}
@ -1945,7 +1961,7 @@ void RestReplicationHandler::handleCommandAddFollower() {
return;
}
auto col = _vocbase->lookupCollection(shard.copyString());
auto col = _vocbase.lookupCollection(shard.copyString());
if (col == nullptr) {
generateError(rest::ResponseCode::SERVER_ERROR,
@ -1956,7 +1972,7 @@ void RestReplicationHandler::handleCommandAddFollower() {
if (readLockId.isNone()) {
// Short cut for the case that the collection is empty
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
SingleCollectionTransaction trx(
ctx, col->id(), AccessMode::Type::EXCLUSIVE
);
@ -2074,7 +2090,7 @@ void RestReplicationHandler::handleCommandRemoveFollower() {
return;
}
auto col = _vocbase->lookupCollection(shard.copyString());
auto col = _vocbase.lookupCollection(shard.copyString());
if (col == nullptr) {
generateError(rest::ResponseCode::SERVER_ERROR,
@ -2100,29 +2116,34 @@ void RestReplicationHandler::handleCommandRemoveFollower() {
void RestReplicationHandler::handleCommandHoldReadLockCollection() {
bool success = false;
std::shared_ptr<VPackBuilder> parsedBody = parseVelocyPackBody(success);
if (!success) {
// error already created
return;
}
VPackSlice const body = parsedBody->slice();
if (!body.isObject()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"body needs to be an object with attributes 'collection', "
"'ttl' and 'id'");
return;
}
VPackSlice const collection = body.get("collection");
VPackSlice const ttlSlice = body.get("ttl");
VPackSlice const idSlice = body.get("id");
if (!collection.isString() || !ttlSlice.isNumber() || !idSlice.isString()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,
"'collection' must be a string and 'ttl' a number and "
"'id' a string");
return;
}
std::string id = idSlice.copyString();
auto col = _vocbase->lookupCollection(collection.copyString());
std::string id = idSlice.copyString();
auto col = _vocbase.lookupCollection(collection.copyString());
if (col == nullptr) {
generateError(rest::ResponseCode::SERVER_ERROR,
@ -2165,8 +2186,7 @@ void RestReplicationHandler::handleCommandHoldReadLockCollection() {
access = AccessMode::Type::EXCLUSIVE;
}
auto ctx =
transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
auto trx =
std::make_shared<SingleCollectionTransaction>(ctx, col->id(), access);
@ -2356,17 +2376,19 @@ void RestReplicationHandler::handleCommandGetIdForReadLockCollection() {
void RestReplicationHandler::handleCommandLoggerState() {
StorageEngine* engine = EngineSelectorFeature::ENGINE;
TRI_ASSERT(engine);
engine->waitForSyncTimeout(10.0); // only for mmfiles
VPackBuilder builder;
auto res = engine->createLoggerState(_vocbase, builder);
auto res = engine->createLoggerState(&_vocbase, builder);
if (res.fail()) {
LOG_TOPIC(DEBUG, Logger::REPLICATION) << "failed to create logger-state" << res.errorMessage();
generateError(rest::ResponseCode::BAD, res.errorNumber(),
res.errorMessage());
return;
}
generateResult(rest::ResponseCode::OK, builder.slice());
}
@ -2442,11 +2464,11 @@ int RestReplicationHandler::createCollection(VPackSlice slice,
arangodb::LogicalCollection* col = nullptr;
if (!uuid.empty()) {
col = _vocbase->lookupCollectionByUuid(uuid).get();
col = _vocbase.lookupCollectionByUuid(uuid).get();
}
if (col != nullptr) {
col = _vocbase->lookupCollection(name).get();
col = _vocbase.lookupCollection(name).get();
}
if (col != nullptr && col->type() == type) {
@ -2477,7 +2499,7 @@ int RestReplicationHandler::createCollection(VPackSlice slice,
/*mergeValues*/true, /*nullMeansRemove*/true);
slice = builder.slice();
col = _vocbase->createCollection(slice);
col = _vocbase.createCollection(slice);
if (col == nullptr) {
return TRI_ERROR_INTERNAL;
@ -2566,7 +2588,7 @@ ReplicationApplier* RestReplicationHandler::getApplier(bool& global) {
getFeature<ReplicationFeature>("Replication");
return replicationFeature->globalReplicationApplier();
} else {
return _vocbase->replicationApplier();
return _vocbase.replicationApplier();
}
}

View File

@ -167,7 +167,8 @@ void RestSimpleHandler::removeByKeys(VPackSlice const& slice) {
if (!collectionName.empty() && collectionName[0] >= '0' &&
collectionName[0] <= '9') {
// If we have a numeric name we probably have to translate it.
CollectionNameResolver resolver(_vocbase);
CollectionNameResolver resolver(&_vocbase);
collectionName = resolver.getCollectionName(collectionName);
}
}
@ -220,8 +221,14 @@ void RestSimpleHandler::removeByKeys(VPackSlice const& slice) {
}
}
arangodb::aql::Query query(false, _vocbase, arangodb::aql::QueryString(aql),
bindVars, nullptr, arangodb::aql::PART_MAIN);
arangodb::aql::Query query(
false,
&_vocbase,
arangodb::aql::QueryString(aql),
bindVars,
nullptr,
arangodb::aql::PART_MAIN
);
registerQuery(&query);
auto queryResult = query.execute(_queryRegistry);
@ -293,15 +300,17 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
std::string collectionName;
{
VPackSlice const value = slice.get("collection");
if (!value.isString()) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_TYPE_ERROR,
"expecting string for <collection>");
return;
}
collectionName = value.copyString();
if (!collectionName.empty()) {
auto col = _vocbase->lookupCollection(collectionName);
auto col = _vocbase.lookupCollection(collectionName);
if (col != nullptr && collectionName != col->name()) {
// user has probably passed in a numeric collection id.
@ -329,8 +338,14 @@ void RestSimpleHandler::lookupByKeys(VPackSlice const& slice) {
std::string const aql(
"FOR doc IN @@collection FILTER doc._key IN @keys RETURN doc");
arangodb::aql::Query query(false, _vocbase, aql::QueryString(aql),
bindVars, nullptr, arangodb::aql::PART_MAIN);
arangodb::aql::Query query(
false,
&_vocbase,
aql::QueryString(aql),
bindVars,
nullptr,
arangodb::aql::PART_MAIN
);
registerQuery(&query);
auto queryResult = query.execute(_queryRegistry);

View File

@ -103,7 +103,7 @@ void RestSimpleQueryHandler::allDocuments() {
return;
}
auto col = _vocbase->lookupCollection(collectionName);
auto col = _vocbase.lookupCollection(collectionName);
if (col != nullptr && collectionName != col->name()) {
// user has probably passed in a numeric collection id.
@ -198,7 +198,7 @@ void RestSimpleQueryHandler::allDocumentKeys() {
return;
}
auto col = _vocbase->lookupCollection(collectionName);
auto col = _vocbase.lookupCollection(collectionName);
if (col != nullptr && collectionName != col->name()) {
// user has probably passed in a numeric collection id.
@ -219,7 +219,7 @@ void RestSimpleQueryHandler::allDocumentKeys() {
} else if (returnType == "id") {
aql.append("doc._id");
} else {
aql.append(std::string("CONCAT('/_db/") + _vocbase->name() +
aql.append(std::string("CONCAT('/_db/") + _vocbase.name() +
"/_api/document/', doc._id)");
}
@ -309,7 +309,7 @@ void RestSimpleQueryHandler::byExample() {
return;
}
auto col = _vocbase->lookupCollection(cname);
auto col = _vocbase.lookupCollection(cname);
if (col != nullptr && cname != col->name()) {
// user has probably passed in a numeric collection id.

View File

@ -62,7 +62,9 @@ RestStatus RestTransactionHandler::execute() {
std::string portType = _request->connectionInfo().portType();
_v8Context = V8DealerFeature::DEALER->enterContext(_vocbase, true /*allow use database*/);
_v8Context =
V8DealerFeature::DEALER->enterContext(&_vocbase, true /*allow use database*/);
if (!_v8Context) {
generateError(Result(TRI_ERROR_INTERNAL, "could not acquire v8 context"));
return RestStatus::DONE;

View File

@ -120,7 +120,8 @@ void RestViewHandler::createView() {
TRI_voc_cid_t id = 0;
try {
std::shared_ptr<LogicalView> view = _vocbase->createView(body, id);
auto view = _vocbase.createView(body, id);
if (view != nullptr) {
VPackBuilder props;
props.openObject();
@ -158,7 +159,8 @@ void RestViewHandler::modifyView(bool partialUpdate) {
}
std::string const& name = suffixes[0];
std::shared_ptr<LogicalView> view = _vocbase->lookupView(name);
auto view = _vocbase.lookupView(name);
if (view == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
@ -184,7 +186,7 @@ void RestViewHandler::modifyView(bool partialUpdate) {
return;
}
int res = _vocbase->renameView(view, newName.copyString());
int res = _vocbase.renameView(view, newName.copyString());
if (res == TRI_ERROR_NO_ERROR) {
getSingleView(newName.copyString());
@ -230,7 +232,7 @@ void RestViewHandler::deleteView() {
std::string const& name = suffixes[0];
int res = _vocbase->dropView(name);
int res = _vocbase.dropView(name);
if (res == TRI_ERROR_NO_ERROR) {
generateOk(rest::ResponseCode::OK, VPackSlice::trueSlice());
@ -272,7 +274,8 @@ void RestViewHandler::getViews() {
}
void RestViewHandler::getListOfViews() {
std::vector<std::shared_ptr<LogicalView>> views = _vocbase->views();
auto views = _vocbase.views();
std::sort(views.begin(), views.end(),
[](std::shared_ptr<LogicalView> const& lhs,
std::shared_ptr<LogicalView> const& rhs) -> bool {
@ -294,7 +297,7 @@ void RestViewHandler::getListOfViews() {
}
void RestViewHandler::getSingleView(std::string const& name) {
std::shared_ptr<LogicalView> view = _vocbase->lookupView(name);
auto view = _vocbase.lookupView(name);
if (view.get() != nullptr) {
VPackBuilder props;
@ -309,7 +312,7 @@ void RestViewHandler::getSingleView(std::string const& name) {
}
void RestViewHandler::getViewProperties(std::string const& name) {
std::shared_ptr<LogicalView> view = _vocbase->lookupView(name);
auto view = _vocbase.lookupView(name);
if (view.get() != nullptr) {
VPackBuilder props;

View File

@ -208,12 +208,15 @@ std::string const RestVocbaseBaseHandler::VIEW_PATH = "/_api/view";
std::string const RestVocbaseBaseHandler::INTERNAL_TRAVERSER_PATH =
"/_internal/traverser";
RestVocbaseBaseHandler::RestVocbaseBaseHandler(GeneralRequest* request,
GeneralResponse* response)
: RestBaseHandler(request, response),
_context(static_cast<VocbaseContext*>(request->requestContext())),
_vocbase(_context->vocbase()),
_nolockHeaderSet(nullptr) {}
RestVocbaseBaseHandler::RestVocbaseBaseHandler(
GeneralRequest* request,
GeneralResponse* response
): RestBaseHandler(request, response),
_context(*static_cast<VocbaseContext*>(request->requestContext())),
_vocbase(_context.vocbase()),
_nolockHeaderSet(nullptr) {
TRI_ASSERT(request->requestContext());
}
RestVocbaseBaseHandler::~RestVocbaseBaseHandler() {}
@ -353,7 +356,8 @@ void RestVocbaseBaseHandler::generatePreconditionFailed(
}
}
auto ctx = transaction::StandaloneContext::Create(_vocbase);
auto ctx = transaction::StandaloneContext::Create(&_vocbase);
writeResult(builder.slice(), *(ctx->getVPackOptionsForDump()));
}

View File

@ -332,13 +332,13 @@ class RestVocbaseBaseHandler : public RestBaseHandler {
/// @brief request context
//////////////////////////////////////////////////////////////////////////////
VocbaseContext* _context;
VocbaseContext& _context;
//////////////////////////////////////////////////////////////////////////////
/// @brief the vocbase, managed by VocbaseContext do not release
//////////////////////////////////////////////////////////////////////////////
TRI_vocbase_t* _vocbase;
TRI_vocbase_t& _vocbase;
public:
bool isDirect() const override { return false; }
@ -346,26 +346,25 @@ class RestVocbaseBaseHandler : public RestBaseHandler {
//////////////////////////////////////////////////////////////////////////////
/// @brief prepareExecute, to react to X-Arango-Nolock header
//////////////////////////////////////////////////////////////////////////////
virtual void prepareExecute() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief finalizeExecute, to react to X-Arango-Nolock header
//////////////////////////////////////////////////////////////////////////////
virtual void finalizeExecute() override;
virtual bool cancel() override {
_context->cancel();
_context.cancel();
return RestBaseHandler::cancel();
}
//////////////////////////////////////////////////////////////////////////////
/// @brief _nolockHeaderSet
//////////////////////////////////////////////////////////////////////////////
std::unordered_set<std::string>* _nolockHeaderSet;
};
}
#endif
#endif

View File

@ -72,7 +72,7 @@ bool RestWalAccessHandler::parseFilter(WalAccess::Filter& filter) {
bool found = false;
std::string const& value1 = _request->value("global", found);
if (found && StringUtils::boolean(value1)) {
if (!_vocbase->isSystem()) {
if (!_vocbase.isSystem()) {
generateError(
rest::ResponseCode::FORBIDDEN, TRI_ERROR_FORBIDDEN,
"global tailing is only possible from within _system database");
@ -80,12 +80,12 @@ bool RestWalAccessHandler::parseFilter(WalAccess::Filter& filter) {
}
} else {
// filter for collection
filter.vocbase = _vocbase->id();
filter.vocbase = _vocbase.id();
// extract collection
std::string const& value2 = _request->value("collection", found);
if (found) {
auto c = _vocbase->lookupCollection(value2);
auto c = _vocbase.lookupCollection(value2);
if (c == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,

View File

@ -29,7 +29,7 @@
namespace {
std::string const FEATURE_NAME("ViewTypes");
arangodb::ViewFactory const INVALID{};
arangodb::ViewTypesFeature::ViewFactory const INVALID{};
} // namespace
@ -50,7 +50,7 @@ bool ViewTypesFeature::emplace(
return _factories.emplace(&type, creator).second;
}
ViewFactory const& ViewTypesFeature::factory(
ViewTypesFeature::ViewFactory const& ViewTypesFeature::factory(
LogicalDataSource::Type const& type
) const noexcept {
auto itr = _factories.find(&type);
@ -72,4 +72,4 @@ void ViewTypesFeature::unprepare() {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -24,16 +24,28 @@
#define ARANGODB_REST_SERVER_VIEW_TYPES_FEATURE_H 1
#include "ApplicationFeatures/ApplicationFeature.h"
#include "VocBase/LogicalDataSource.h"
#include "VocBase/LogicalView.h"
namespace arangodb {
class ViewTypesFeature final: public application_features::ApplicationFeature {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief typedef for a LogicalView factory function
/// This typedef is used when registering the factory function for any view
/// type. the creator function is called when a view is first created or
/// re-opened after a server restart. the VelocyPack Slice will contain all
/// information about the view's general and implementation-specific properties.
//////////////////////////////////////////////////////////////////////////////
typedef std::function<std::shared_ptr<LogicalView>(
TRI_vocbase_t& vocbase, // database
velocypack::Slice const& definition, // view definition
uint64_t planVersion // cluster plan version ('0' by default for non-cluster)
)> ViewFactory;
explicit ViewTypesFeature(application_features::ApplicationServer* server);
public:
/// @return 'factory' for 'type' was added successfully
bool emplace(LogicalDataSource::Type const& type, ViewFactory const& factory);
@ -47,9 +59,9 @@ class ViewTypesFeature final: public application_features::ApplicationFeature {
void unprepare() override final;
private:
std::unordered_map<LogicalDataSource::Type const*, arangodb::ViewFactory> _factories;
std::unordered_map<LogicalDataSource::Type const*, ViewFactory> _factories;
};
}
} // arangodb
#endif
#endif

View File

@ -26,20 +26,38 @@
#include "Logger/Logger.h"
#include "VocBase/vocbase.h"
using namespace arangodb;
using namespace arangodb::basics;
using namespace arangodb::rest;
namespace arangodb {
double VocbaseContext::ServerSessionTtl =
60.0 * 60.0 * 24 * 60; // 2 month session timeout
VocbaseContext* VocbaseContext::create(GeneralRequest* req,
TRI_vocbase_t* vocbase) {
TRI_ASSERT(vocbase != nullptr);
VocbaseContext::VocbaseContext(
GeneralRequest* req,
TRI_vocbase_t& vocbase,
bool isInternal,
auth::Level systemLevel,
auth::Level dbLevel
): ExecContext(isInternal, req->user(), req->databaseName(), systemLevel, dbLevel),
_vocbase(vocbase) {
// _vocbase has already been refcounted for us
TRI_ASSERT(!vocbase->isDangling());
TRI_ASSERT(!_vocbase.isDangling());
}
VocbaseContext::~VocbaseContext() {
TRI_ASSERT(!_vocbase.isDangling());
_vocbase.release();
}
/*static*/ VocbaseContext* VocbaseContext::create(
GeneralRequest* req, TRI_vocbase_t& vocbase
) {
// _vocbase has already been refcounted for us
TRI_ASSERT(!vocbase.isDangling());
AuthenticationFeature* auth = AuthenticationFeature::instance();
if (auth == nullptr) {
return nullptr;
}
@ -59,41 +77,31 @@ VocbaseContext* VocbaseContext::create(GeneralRequest* req,
LOG_TOPIC(WARN, Logger::AUTHENTICATION) << msg;
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, msg);
}
return new VocbaseContext(req, vocbase, /*isInternal*/ true,
/*sysLevel*/ auth::Level::RW,
/*dbLevel*/ auth::Level::RW);
}
auth::UserManager* um = auth->userManager();
TRI_ASSERT(um != nullptr);
auth::Level dbLvl = um->databaseAuthLevel(req->user(), req->databaseName());
auth::Level sysLvl = dbLvl;
if (req->databaseName() != TRI_VOC_SYSTEM_DATABASE) {
sysLvl = um->databaseAuthLevel(req->user(), TRI_VOC_SYSTEM_DATABASE);
}
return new VocbaseContext(req, vocbase, /*isInternal*/ false,
/*sysLevel*/ sysLvl,
/*dbLevel*/ dbLvl);
}
return new VocbaseContext(req, vocbase, /*isInternal*/ false,
/*sysLevel*/ auth::Level::NONE,
/*dbLevel*/ auth::Level::NONE);
}
VocbaseContext::VocbaseContext(GeneralRequest* req, TRI_vocbase_t* vocbase,
bool isInternal, auth::Level sys,
auth::Level dbl)
: ExecContext(isInternal, req->user(), req->databaseName(), sys, dbl),
_vocbase(vocbase) {
TRI_ASSERT(_vocbase != nullptr);
// _vocbase has already been refcounted for us
TRI_ASSERT(!_vocbase->isDangling());
}
VocbaseContext::~VocbaseContext() {
TRI_ASSERT(!_vocbase->isDangling());
_vocbase->release();
}
void VocbaseContext::forceSuperuser() {
TRI_ASSERT(!_internal || _user.empty());
_internal = true;
@ -107,3 +115,5 @@ void VocbaseContext::forceReadOnly() {
_systemDbAuthLevel = auth::Level::RO;
_databaseAuthLevel = auth::Level::RO;
}
} // arangodb

View File

@ -38,31 +38,34 @@ namespace arangodb {
/// @brief just also stores the context
class VocbaseContext : public arangodb::ExecContext {
private:
VocbaseContext(VocbaseContext const&) = delete;
VocbaseContext& operator=(VocbaseContext const&) = delete;
VocbaseContext(GeneralRequest*, TRI_vocbase_t*, bool isSuper,
auth::Level systemLevel, auth::Level dbLevel);
public:
static double ServerSessionTtl;
TEST_VIRTUAL ~VocbaseContext();
public:
static VocbaseContext* create(GeneralRequest*, TRI_vocbase_t*);
TEST_VIRTUAL TRI_vocbase_t* vocbase() const { return _vocbase; }
static VocbaseContext* create(GeneralRequest* req, TRI_vocbase_t& vocbase);
TEST_VIRTUAL TRI_vocbase_t& vocbase() const { return _vocbase; }
/// @brief upgrade to internal superuser
void forceSuperuser();
/// @brief upgrade to internal read-only user
void forceReadOnly();
private:
TRI_vocbase_t* _vocbase;
TRI_vocbase_t& _vocbase;
VocbaseContext(
GeneralRequest* req,
TRI_vocbase_t& vocbase,
bool isInternal,
auth::Level systemLevel,
auth::Level dbLevel
);
VocbaseContext(VocbaseContext const&) = delete;
VocbaseContext& operator=(VocbaseContext const&) = delete;
};
}
#endif
#endif

View File

@ -1694,7 +1694,7 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
TRI_ASSERT(!it.get("id").isNone());
auto const view = LogicalView::create(*vocbase, it, false);
auto const view = LogicalView::create(*vocbase, it);
if (!view) {
auto const message = "failed to instantiate view '" + name + "'";
@ -2052,4 +2052,4 @@ void RocksDBEngine::releaseTick(TRI_voc_tick_t tick) {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -232,14 +232,21 @@ void RocksDBRestExportHandler::createCursor() {
bool count = arangodb::basics::VelocyPackHelper::getBooleanValue(
options, "count", false);
auto cursors = _vocbase->cursorRepository();
auto cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
Cursor* c = nullptr;
{
auto cursor = std::make_unique<RocksDBExportCursor>(
_vocbase, name, _restrictions, TRI_NewTickServer(), limit, batchSize,
ttl, count);
&_vocbase,
name,
_restrictions,
TRI_NewTickServer(),
limit,
batchSize,
ttl,
count
);
cursor->use();
c = cursors->addCursor(std::move(cursor));
@ -276,7 +283,7 @@ void RocksDBRestExportHandler::modifyCursor() {
std::string const& id = suffixes[0];
auto cursors = _vocbase->cursorRepository();
auto cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
auto cursorId = static_cast<arangodb::CursorId>(
@ -322,7 +329,7 @@ void RocksDBRestExportHandler::deleteCursor() {
std::string const& id = suffixes[0];
CursorRepository* cursors = _vocbase->cursorRepository();
CursorRepository* cursors = _vocbase.cursorRepository();
TRI_ASSERT(cursors != nullptr);
auto cursorId = static_cast<arangodb::CursorId>(

View File

@ -84,9 +84,9 @@ void RocksDBRestReplicationHandler::handleCommandBatch() {
}
// create transaction+snapshot, ttl will be 300 if `ttl == 0``
RocksDBReplicationContext* ctx = _manager->createContext(_vocbase, ttl, serverId);
auto* ctx = _manager->createContext(&_vocbase, ttl, serverId);
RocksDBReplicationContextGuard guard(_manager, ctx);
ctx->bind(_vocbase);
ctx->bind(&_vocbase);
VPackBuilder b;
b.add(VPackValue(VPackValueType::Object));
@ -103,7 +103,7 @@ void RocksDBRestReplicationHandler::handleCommandBatch() {
// for initial synchronization. the inventory request and collection
// dump requests will all happen after the batch creation, so the
// current tick value here is good
_vocbase->updateReplicationClient(serverId, ctx->lastTick(), ttl);
_vocbase.updateReplicationClient(serverId, ctx->lastTick(), ttl);
generateResult(rest::ResponseCode::OK, b.slice());
return;
@ -154,7 +154,7 @@ void RocksDBRestReplicationHandler::handleCommandBatch() {
// last tick value in context should not have changed compared to the
// initial tick value used in the context (it's only updated on bind()
// call, which is only executed when a batch is initially created)
_vocbase->updateReplicationClient(serverId, ctx->lastTick(), ttl);
_vocbase.updateReplicationClient(serverId, ctx->lastTick(), ttl);
resetResponse(rest::ResponseCode::NO_CONTENT);
return;
@ -256,7 +256,7 @@ void RocksDBRestReplicationHandler::handleCommandLoggerFollow() {
TRI_voc_cid_t cid = 0;
std::string const& value6 = _request->value("collection", found);
if (found) {
auto c = _vocbase->lookupCollection(value6);
auto c = _vocbase.lookupCollection(value6);
if (c == nullptr) {
generateError(rest::ResponseCode::NOT_FOUND,
@ -267,12 +267,17 @@ void RocksDBRestReplicationHandler::handleCommandLoggerFollow() {
cid = c->id();
}
auto trxContext = transaction::StandaloneContext::Create(_vocbase);
auto trxContext = transaction::StandaloneContext::Create(&_vocbase);
VPackBuilder builder(trxContext->getVPackOptions());
builder.openArray();
auto result = tailWal(_vocbase, tickStart, tickEnd, chunkSize, includeSystem,
cid, builder);
auto result = tailWal(
&_vocbase, tickStart, tickEnd, chunkSize, includeSystem, cid, builder
);
builder.close();
auto data = builder.slice();
uint64_t const latest = latestSequenceNumber();
@ -344,7 +349,11 @@ void RocksDBRestReplicationHandler::handleCommandLoggerFollow() {
// note a higher tick than the slave will have received, which may
// lead to the master eventually deleting a WAL section that the
// slave will still request later
_vocbase->updateReplicationClient(serverId, tickStart == 0 ? 0 : tickStart - 1, InitialSyncer::defaultBatchTimeout);
_vocbase.updateReplicationClient(
serverId,
tickStart == 0 ? 0 : tickStart - 1,
InitialSyncer::defaultBatchTimeout
);
}
/// @brief run the command that determines which transactions were open at
@ -388,8 +397,9 @@ void RocksDBRestReplicationHandler::handleCommandInventory() {
getApplier(isGlobal);
VPackBuilder inventoryBuilder;
Result res = ctx->getInventory(this->_vocbase, includeSystem,
isGlobal, inventoryBuilder);
Result res =
ctx->getInventory(&_vocbase, includeSystem, isGlobal, inventoryBuilder);
if (res.fail()) {
generateError(rest::ResponseCode::BAD, res.errorNumber(),
"inventory could not be created");
@ -463,7 +473,8 @@ void RocksDBRestReplicationHandler::handleCommandCreateKeys() {
//}
// bind collection to context - will initialize iterator
int res = ctx->bindCollection(_vocbase, collection);
int res = ctx->bindCollection(&_vocbase, collection);
if (res != TRI_ERROR_NO_ERROR) {
generateError(rest::ResponseCode::NOT_FOUND,
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
@ -611,8 +622,7 @@ void RocksDBRestReplicationHandler::handleCommandFetchKeys() {
}
std::shared_ptr<transaction::Context> transactionContext =
transaction::StandaloneContext::Create(_vocbase);
transaction::StandaloneContext::Create(&_vocbase);
VPackBuffer<uint8_t> buffer;
VPackBuilder builder(buffer, transactionContext->getVPackOptions());
@ -701,7 +711,8 @@ void RocksDBRestReplicationHandler::handleCommandDump() {
}
if (!isBusy) {
int res = context->chooseDatabase(_vocbase);
int res = context->chooseDatabase(&_vocbase);
isBusy = (TRI_ERROR_CURSOR_BUSY == res);
}
@ -727,14 +738,18 @@ void RocksDBRestReplicationHandler::handleCommandDump() {
}
ExecContext const* exec = ExecContext::CURRENT;
if (exec != nullptr &&
!exec->canUseCollection(_vocbase->name(), collection, auth::Level::RO)) {
!exec->canUseCollection(_vocbase.name(), collection, auth::Level::RO)) {
generateError(rest::ResponseCode::FORBIDDEN,
TRI_ERROR_FORBIDDEN);
return;
}
// do the work!
auto result = context->dump(_vocbase, collection, dump, determineChunkSize());
auto result =
context->dump(&_vocbase, collection, dump, determineChunkSize());
if (result.fail()) {
if (result.is(TRI_ERROR_BAD_PARAMETER)) {
generateError(rest::ResponseCode::BAD, TRI_ERROR_HTTP_BAD_PARAMETER,

View File

@ -207,18 +207,21 @@ LogicalCollection::LogicalCollection(LogicalCollection const& other)
// The Slice contains the part of the plan that
// is relevant for this collection.
LogicalCollection::LogicalCollection(TRI_vocbase_t* vocbase,
VPackSlice const& info,
bool isAStub)
: LogicalDataSource(
category(),
ReadType(info, "type", TRI_COL_TYPE_UNKNOWN),
vocbase,
ReadCid(info),
ReadPlanId(info, 0),
ReadStringValue(info, "name", ""),
Helper::readBooleanValue(info, "deleted", false)
),
LogicalCollection::LogicalCollection(
TRI_vocbase_t* vocbase,
VPackSlice const& info,
bool isAStub,
uint64_t planVersion /*= 0*/
): LogicalDataSource(
category(),
ReadType(info, "type", TRI_COL_TYPE_UNKNOWN),
vocbase,
ReadCid(info),
ReadPlanId(info, 0),
ReadStringValue(info, "name", ""),
planVersion,
Helper::readBooleanValue(info, "deleted", false)
),
_internalVersion(0),
_isAStub(isAStub),
_type(Helper::readNumericValue<TRI_col_type_e, int>(
@ -783,7 +786,7 @@ void LogicalCollection::toVelocyPackForClusterInventory(VPackBuilder& result,
result.add(VPackValue("indexes"));
getIndexesVPack(result, false, false);
result.add("planVersion", VPackValue(getPlanVersion()));
result.add("planVersion", VPackValue(planVersion()));
result.add("isReady", VPackValue(isReady));
result.add("allInSync", VPackValue(allInSync));
result.close(); // CollectionInfo

View File

@ -77,7 +77,13 @@ class LogicalCollection: public LogicalDataSource {
friend struct ::TRI_vocbase_t;
public:
LogicalCollection(TRI_vocbase_t*, velocypack::Slice const&, bool isAStub);
LogicalCollection() = delete;
LogicalCollection(
TRI_vocbase_t* vocbase,
velocypack::Slice const& info,
bool isAStub,
uint64_t planVersion = 0
);
virtual ~LogicalCollection();
@ -90,7 +96,6 @@ class LogicalCollection: public LogicalDataSource {
LogicalCollection& operator=(LogicalCollection const&) = delete;
public:
LogicalCollection() = delete;
//////////////////////////////////////////////////////////////////////////////
/// @brief the category representing a logical collection

View File

@ -90,6 +90,7 @@ class LogicalDataSource {
TRI_voc_cid_t id,
TRI_voc_cid_t planId,
std::string&& name,
uint64_t planVersion,
bool deleted
) noexcept
: _name(std::move(name)),
@ -98,7 +99,7 @@ class LogicalDataSource {
_vocbase(vocbase),
_id(id),
_planId(planId ? planId : id),
_planVersion(0),
_planVersion(planVersion),
_deleted(deleted) {
}
@ -121,15 +122,11 @@ class LogicalDataSource {
TRI_voc_cid_t const& id() const noexcept { return _id; } // reference required for ShardDistributionReporterTest
std::string const& name() const noexcept { return _name; }
TRI_voc_cid_t planId() const noexcept { return _planId; }
uint64_t planVersion() const noexcept { return _planVersion; }
virtual Result rename(std::string&& newName, bool doSync) = 0;
Type const& type() const noexcept { return _type; }
TRI_vocbase_t* vocbase() const noexcept { return _vocbase; }
// Set and get _planVersion, this is only used if the object is used in
// ClusterInfo to represent a cluster wide collection in the agency.
void setPlanVersion(uint64_t v) noexcept { _planVersion = v; }
uint64_t getPlanVersion() const noexcept { return _planVersion; }
protected:
void deleted(bool deleted) noexcept { _deleted = deleted; }
void name(std::string&& name) noexcept { _name = std::move(name); }
@ -142,7 +139,7 @@ class LogicalDataSource {
TRI_vocbase_t* const _vocbase; // the database where the data-source resides TODO change to reference
TRI_voc_cid_t const _id; // local data-source id (current database node)
TRI_voc_cid_t const _planId; // global data-source id (cluster-wide)
uint64_t _planVersion; // Only set if setPlanVersion was called. This only
uint64_t const _planVersion; // Only set if setPlanVersion was called. This only
// happens in ClusterInfo when this object is used
// to represent a cluster wide collection. This is
// then the version in the agency Plan that underpins

View File

@ -34,7 +34,6 @@
#include "StorageEngine/StorageEngine.h"
#include "VocBase/ticks.h"
using namespace arangodb;
using Helper = arangodb::basics::VelocyPackHelper;
namespace {
@ -69,20 +68,25 @@ TRI_voc_cid_t ReadPlanId(VPackSlice info, TRI_voc_cid_t vid) {
// Somehow the id is now propagated to dbservers
TRI_voc_cid_t id = Helper::extractIdValue(info);
if (id == 0) {
if (ServerState::instance()->isDBServer()) {
id = ClusterInfo::instance()->uniqid(1);
} else if (ServerState::instance()->isCoordinator()) {
id = ClusterInfo::instance()->uniqid(1);
} else {
id = TRI_NewTickServer();
}
if (id) {
return id;
}
return id;
if (arangodb::ServerState::instance()->isDBServer()) {
return arangodb::ClusterInfo::instance()->uniqid(1);
}
if (arangodb::ServerState::instance()->isCoordinator()) {
return arangodb::ClusterInfo::instance()->uniqid(1);
}
return TRI_NewTickServer();
}
} // namespace
namespace arangodb {
// -----------------------------------------------------------------------------
// --SECTION-- LogicalView
// -----------------------------------------------------------------------------
@ -90,19 +94,23 @@ TRI_voc_cid_t ReadPlanId(VPackSlice info, TRI_voc_cid_t vid) {
// @brief Constructor used in coordinator case.
// The Slice contains the part of the plan that
// is relevant for this view
LogicalView::LogicalView(TRI_vocbase_t* vocbase, VPackSlice const& info)
: LogicalDataSource(
category(),
LogicalDataSource::Type::emplace(
arangodb::basics::VelocyPackHelper::getStringRef(info, "type", "")
),
vocbase,
ReadViewId(info),
ReadPlanId(info, 0),
arangodb::basics::VelocyPackHelper::getStringValue(info, "name", ""),
Helper::readBooleanValue(info, "deleted", false)
) {
if (!TRI_vocbase_t::IsAllowedName(info)) {
LogicalView::LogicalView(
TRI_vocbase_t* vocbase,
VPackSlice const& definition,
uint64_t planVersion
): LogicalDataSource(
category(),
LogicalDataSource::Type::emplace(
arangodb::basics::VelocyPackHelper::getStringRef(definition, "type", "")
),
vocbase,
ReadViewId(definition),
ReadPlanId(definition, 0),
arangodb::basics::VelocyPackHelper::getStringValue(definition, "name", ""),
planVersion,
Helper::readBooleanValue(definition, "deleted", false)
) {
if (!TRI_vocbase_t::IsAllowedName(definition)) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME);
}
@ -120,30 +128,33 @@ LogicalView::LogicalView(TRI_vocbase_t* vocbase, VPackSlice const& info)
/*static*/ std::shared_ptr<LogicalView> LogicalView::create(
TRI_vocbase_t& vocbase,
velocypack::Slice definition,
bool isNew
uint64_t planVersion /*= 0*/
) {
auto const* viewTypes = application_features::ApplicationServer::getFeature
<ViewTypesFeature>("ViewTypes");
TRI_ASSERT(viewTypes);
auto const* viewTypes =
application_features::ApplicationServer::getFeature<ViewTypesFeature>("ViewTypes");
auto const viewType = arangodb::basics::VelocyPackHelper::getStringRef(
definition, "type", ""
);
if (!viewTypes) {
LOG_TOPIC(ERR, Logger::VIEWS)
<< "Failure to get 'ViewTypes' feature while creating LogicalView";
auto const& dataSourceType = arangodb::LogicalDataSource::Type::emplace(
viewType
);
return nullptr;
}
auto const viewType =
basics::VelocyPackHelper::getStringRef(definition, "type", "");
auto const& dataSourceType =
arangodb::LogicalDataSource::Type::emplace(viewType);
auto const& viewFactory = viewTypes->factory(dataSourceType);
if (!viewFactory) {
LOG_TOPIC(ERR, Logger::VIEWS)
<< "Found view type for which there is no factory, type: "
<< viewType.toString();
return nullptr;
}
return viewFactory(vocbase, definition, isNew);
return viewFactory(vocbase, definition, planVersion);
}
/*static*/ LogicalDataSource::Category const& LogicalView::category() noexcept {
@ -158,10 +169,9 @@ LogicalView::LogicalView(TRI_vocbase_t* vocbase, VPackSlice const& info)
DBServerLogicalView::DBServerLogicalView(
TRI_vocbase_t* vocbase,
VPackSlice const& info,
bool isNew
) : LogicalView(vocbase, info),
_isNew(isNew) {
VPackSlice const& definition,
uint64_t planVersion
): LogicalView(vocbase, definition, planVersion) {
}
DBServerLogicalView::~DBServerLogicalView() {
@ -179,20 +189,6 @@ void DBServerLogicalView::drop() {
engine->dropView(vocbase(), this);
}
void DBServerLogicalView::open() {
// Coordinators are not allowed to have local views!
TRI_ASSERT(!ServerState::instance()->isCoordinator());
if (!_isNew) {
return;
}
StorageEngine* engine = EngineSelectorFeature::ENGINE;
TRI_ASSERT(engine);
engine->createView(vocbase(), id(), this);
_isNew = false;
}
Result DBServerLogicalView::rename(std::string&& newName, bool doSync) {
auto oldName = name();
@ -287,6 +283,8 @@ arangodb::Result DBServerLogicalView::updateProperties(
return {};
}
} // arangodb
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -52,7 +52,7 @@ class LogicalView : public LogicalDataSource {
static std::shared_ptr<LogicalView> create(
TRI_vocbase_t& vocbase,
velocypack::Slice definition,
bool isNew
uint64_t planVersion = 0
);
//////////////////////////////////////////////////////////////////////////////
@ -103,7 +103,11 @@ class LogicalView : public LogicalDataSource {
virtual bool visitCollections(CollectionVisitor const& visitor) const = 0;
protected:
LogicalView(TRI_vocbase_t* vocbase, velocypack::Slice const& definition);
LogicalView(
TRI_vocbase_t* vocbase,
velocypack::Slice const& definition,
uint64_t planVersion
);
private:
// FIXME seems to be ugly
@ -113,21 +117,6 @@ class LogicalView : public LogicalDataSource {
mutable basics::ReadWriteLock _lock;
}; // LogicalView
//////////////////////////////////////////////////////////////////////////////
/// @brief typedef for a LogicalView factory function
/// This typedef is used when registering the creator function for any view
/// type. the creator function is called when a view is first created or
/// re-opened after a server restart. the VelocyPack Slice will contain all
/// information about the view's general and implementation-specific properties.
/// the isNew flag will be true if the view is first created, and false if a
/// view is re-opened on a server restart.
//////////////////////////////////////////////////////////////////////////////
typedef std::function<std::shared_ptr<LogicalView>(
TRI_vocbase_t& vocbase, // database
arangodb::velocypack::Slice const& properties, // view properties
bool isNew
)> ViewFactory;
////////////////////////////////////////////////////////////////////////////////
/// @class DBServerLogicalView
////////////////////////////////////////////////////////////////////////////////
@ -137,8 +126,6 @@ class DBServerLogicalView : public LogicalView {
void drop() override;
void open() override;
Result rename(
std::string&& newName,
bool doSync
@ -160,7 +147,7 @@ class DBServerLogicalView : public LogicalView {
DBServerLogicalView(
TRI_vocbase_t* vocbase,
velocypack::Slice const& definition,
bool isNew
uint64_t planVersion
);
//////////////////////////////////////////////////////////////////////////////
@ -178,9 +165,6 @@ class DBServerLogicalView : public LogicalView {
velocypack::Slice const& slice,
bool partialUpdate
) = 0;
private:
bool _isNew;
}; // LogicalView
} // namespace arangodb

View File

@ -1586,17 +1586,18 @@ void TRI_vocbase_t::releaseCollection(arangodb::LogicalCollection* collection) {
/// @brief creates a new view, worker function
std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createViewWorker(
VPackSlice parameters, TRI_voc_cid_t& id) {
std::string name = arangodb::basics::VelocyPackHelper::getStringValue(
parameters, "name", "");
VPackSlice parameters, TRI_voc_cid_t& id
) {
// check that the name does not contain any strange characters
if (!IsAllowedName(parameters)) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME);
}
auto name =
arangodb::basics::VelocyPackHelper::getStringValue(parameters, "name", "");
// Try to create a new view. This is not registered yet
auto const view = LogicalView::create(*this, parameters, true);
auto const view = LogicalView::create(*this, parameters);
if (!view) {
auto const message = "failed to instantiate view '" + name + "'";
@ -1619,17 +1620,20 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createViewWorker(
StorageEngine* engine = EngineSelectorFeature::ENGINE;
TRI_ASSERT(engine);
arangodb::velocypack::Builder builder;
auto res = engine->getViews(this, builder);
TRI_ASSERT(TRI_ERROR_NO_ERROR == res);
auto slice = builder.slice();
TRI_ASSERT(slice.isArray());
auto viewId = std::to_string(view->id());
// We have not yet persisted this view
for (auto entry: arangodb::velocypack::ArrayIterator(slice)) {
TRI_ASSERT(arangodb::basics::VelocyPackHelper::getStringRef(entry, "id", arangodb::velocypack::StringRef()).compare(viewId));
}
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
arangodb::velocypack::Builder builder;
auto res = engine->getViews(this, builder);
TRI_ASSERT(TRI_ERROR_NO_ERROR == res);
auto slice = builder.slice();
TRI_ASSERT(slice.isArray());
auto viewId = std::to_string(view->id());
// We have not yet persisted this view
for (auto entry: arangodb::velocypack::ArrayIterator(slice)) {
TRI_ASSERT(arangodb::basics::VelocyPackHelper::getStringRef(entry, "id", arangodb::velocypack::StringRef()).compare(viewId));
}
#endif
registerView(basics::ConditionalLocking::DoNotLock, view);

View File

@ -234,66 +234,10 @@ SECTION("test_type") {
SECTION("test_defaults") {
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }");
// existing view definition with LogicalView (for persistence)
// view definition with LogicalView (for persistence)
{
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
CHECK(nullptr != view);
arangodb::iresearch::IResearchViewMeta expectedMeta;
arangodb::velocypack::Builder builder;
builder.openObject();
view->toVelocyPack(builder, true, true);
builder.close();
auto slice = builder.slice();
arangodb::iresearch::IResearchViewMeta meta;
std::string error;
CHECK(6 == slice.length());
CHECK(slice.get("name").copyString() == "testView");
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
CHECK(false == slice.get("deleted").getBool());
slice = slice.get("properties");
CHECK(slice.isObject());
CHECK((5U == slice.length()));
CHECK((!slice.hasKey("links"))); // for persistence so no links
CHECK((meta.init(slice, error) && expectedMeta == meta));
}
// existing view definition with LogicalView
{
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
CHECK((false == !view));
arangodb::iresearch::IResearchViewMeta expectedMeta;
arangodb::velocypack::Builder builder;
builder.openObject();
view->toVelocyPack(builder, true, false);
builder.close();
auto slice = builder.slice();
arangodb::iresearch::IResearchViewMeta meta;
std::string error;
CHECK(4 == slice.length());
CHECK(slice.get("name").copyString() == "testView");
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
CHECK((false == slice.hasKey("deleted")));
slice = slice.get("properties");
CHECK(slice.isObject());
CHECK((6U == slice.length()));
CHECK((slice.hasKey("links")));
CHECK((meta.init(slice, error) && expectedMeta == meta));
}
// new view definition with LogicalView (for persistence)
{
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), true);
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !view));
arangodb::iresearch::IResearchViewMeta expectedMeta;
@ -318,10 +262,10 @@ SECTION("test_defaults") {
CHECK((meta.init(slice, error) && expectedMeta == meta));
}
// new view definition with LogicalView
// view definition with LogicalView
{
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), true);
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !view));
arangodb::iresearch::IResearchViewMeta expectedMeta;
@ -441,7 +385,7 @@ SECTION("test_drop_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -492,7 +436,7 @@ SECTION("test_drop_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"properties\": { \"collections\": [ 42 ] } }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -544,7 +488,7 @@ SECTION("test_drop_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"collections\": [ 42 ] }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -612,7 +556,7 @@ SECTION("test_drop_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"properties\": { \"collections\": [ 42 ] } }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -675,7 +619,7 @@ SECTION("test_drop_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"properties\": { \"collections\": [ 42 ] } }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -756,7 +700,7 @@ SECTION("test_emplace_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"properties\": { \"collections\": [ 42 ] } }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -805,7 +749,7 @@ SECTION("test_emplace_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -855,7 +799,7 @@ SECTION("test_emplace_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -907,7 +851,7 @@ SECTION("test_emplace_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -954,7 +898,7 @@ SECTION("test_emplace_cid") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1028,7 +972,7 @@ SECTION("test_insert") {
StorageEngineMock::inRecoveryResult = true;
auto restore = irs::make_finally([&before]()->void { StorageEngineMock::inRecoveryResult = before; });
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1063,7 +1007,7 @@ SECTION("test_insert") {
StorageEngineMock::inRecoveryResult = true;
auto restore = irs::make_finally([&before]()->void { StorageEngineMock::inRecoveryResult = before; });
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1098,7 +1042,7 @@ SECTION("test_insert") {
{
StorageEngineMock::inRecoveryResult = false;
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1160,7 +1104,7 @@ SECTION("test_insert") {
{
StorageEngineMock::inRecoveryResult = false;
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1194,7 +1138,7 @@ SECTION("test_insert") {
{
StorageEngineMock::inRecoveryResult = false;
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1228,7 +1172,7 @@ SECTION("test_insert") {
{
StorageEngineMock::inRecoveryResult = false;
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto viewImpl = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !viewImpl));
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(viewImpl.get());
CHECK((nullptr != view));
@ -1260,238 +1204,6 @@ SECTION("test_insert") {
}
}
SECTION("test_link") {
auto collectionJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testCollection\", \"id\": 100 }");
auto viewJson = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }");
// drop invalid collection
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
}
{
CHECK((true == viewImpl->link(100, arangodb::velocypack::Slice::nullSlice()).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
}
}
// drop non-exiting
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
CHECK((nullptr != logicalCollection));
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
}
{
CHECK((true == viewImpl->link(logicalCollection->id(), arangodb::velocypack::Slice::nullSlice()).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
}
}
// drop exiting
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
CHECK((nullptr != logicalCollection));
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
auto links = arangodb::velocypack::Parser::fromJson("{ \
\"links\": { \"testCollection\": {} } \
}");
CHECK((true == logicalView->updateProperties(links->slice(), true, false).ok()));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((1 == cids.size()));
CHECK((1 == logicalCollection->getIndexes().size()));
}
{
CHECK((true == viewImpl->link(logicalCollection->id(), arangodb::velocypack::Slice::nullSlice()).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
CHECK((true == logicalCollection->getIndexes().empty()));
}
}
// drop invalid collection + recreate
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
}
{
CHECK((false == viewImpl->link(100, arangodb::iresearch::emptyObjectSlice()).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
}
}
// drop non-existing + recreate
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
CHECK((nullptr != logicalCollection));
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((0 == cids.size()));
CHECK((true == logicalCollection->getIndexes().empty()));
}
{
CHECK((true == viewImpl->link(logicalCollection->id(), arangodb::iresearch::emptyObjectSlice()).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
std::unordered_set<TRI_voc_cid_t> expected = { 100 };
for (auto& cid: expected) {
CHECK((1 == cids.erase(cid)));
}
CHECK((0 == cids.size()));
CHECK((1 == logicalCollection->getIndexes().size()));
}
}
// drop existing + recreate
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
CHECK((nullptr != logicalCollection));
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
auto links = arangodb::velocypack::Parser::fromJson("{ \
\"links\": { \"testCollection\": { \"includeAllFields\": true } } \
}");
CHECK((true == logicalView->updateProperties(links->slice(), true, false).ok()));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((1 == cids.size()));
CHECK((1 == logicalCollection->getIndexes().size()));
auto link = logicalCollection->getIndexes()[0]->toVelocyPack(true, false);
arangodb::iresearch::IResearchLinkMeta linkMeta;
std::string error;
CHECK((linkMeta.init(link->slice(), error) && true == linkMeta._includeAllFields));
}
{
CHECK((true == viewImpl->link(logicalCollection->id(), arangodb::iresearch::emptyObjectSlice()).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
std::unordered_set<TRI_voc_cid_t> expected = { 100 };
for (auto& cid: expected) {
CHECK((1 == cids.erase(cid)));
}
CHECK((0 == cids.size()));
CHECK((1 == logicalCollection->getIndexes().size()));
auto link = logicalCollection->getIndexes()[0]->toVelocyPack(true, false);
arangodb::iresearch::IResearchLinkMeta linkMeta;
std::string error;
CHECK((linkMeta.init(link->slice(), error) && false == linkMeta._includeAllFields));
}
}
// drop existing + recreate invalid
{
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
CHECK((nullptr != logicalCollection));
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
auto links = arangodb::velocypack::Parser::fromJson("{ \
\"links\": { \"testCollection\": { \"includeAllFields\": true } } \
}");
CHECK((true == logicalView->updateProperties(links->slice(), true, false).ok()));
{
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((1 == cids.size()));
CHECK((1 == logicalCollection->getIndexes().size()));
auto link = logicalCollection->getIndexes()[0]->toVelocyPack(true, false);
arangodb::iresearch::IResearchLinkMeta linkMeta;
std::string error;
CHECK((linkMeta.init(link->slice(), error) && true == linkMeta._includeAllFields));
}
{
arangodb::velocypack::Builder builder;
builder.openObject();
builder.add("includeAllFields", arangodb::velocypack::Value("abc"));
builder.close();
auto slice = builder.slice();
CHECK((false == viewImpl->link(logicalCollection->id(), slice).ok()));
std::set<TRI_voc_cid_t> cids;
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
std::unordered_set<TRI_voc_cid_t> expected = { 100 };
for (auto& cid: expected) {
CHECK((1 == cids.erase(cid)));
}
CHECK((0 == cids.size()));
CHECK((1 == logicalCollection->getIndexes().size()));
auto link = logicalCollection->getIndexes()[0]->toVelocyPack(true, false);
arangodb::iresearch::IResearchLinkMeta linkMeta;
std::string error;
CHECK((linkMeta.init(link->slice(), error) && true == linkMeta._includeAllFields));
}
}
}
SECTION("test_open") {
// default data path
{
@ -1500,7 +1212,7 @@ SECTION("test_open") {
auto json = arangodb::velocypack::Parser::fromJson("{ \"id\": 123, \"name\": \"testView\", \"type\": \"testType\" }");
CHECK((false == TRI_IsDirectory(dataPath.c_str())));
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !view));
CHECK((false == TRI_IsDirectory(dataPath.c_str())));
view->open();
@ -2119,7 +1831,7 @@ SECTION("test_unregister_link") {
auto updateJson = arangodb::velocypack::Parser::fromJson("{ \"links\": { \"testCollection\": {} } }");
auto logicalView = vocbase.createView(viewJson->slice(), 0);
REQUIRE((false == !logicalView));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());auto x0 = logicalView.use_count();
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
REQUIRE((nullptr != viewImpl));
CHECK((viewImpl->updateProperties(updateJson->slice(), true, false).ok()));
CHECK((false == logicalCollection->getIndexes().empty()));
@ -2135,7 +1847,7 @@ SECTION("test_unregister_link") {
// create a new view with same ID to validate links
{
auto json = arangodb::velocypack::Parser::fromJson("{}");
auto view = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), true);
auto view = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), 0);
REQUIRE((false == !view));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(view.get());
REQUIRE((nullptr != viewImpl));
@ -2163,7 +1875,7 @@ SECTION("test_self_token") {
{
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), false);
auto view = arangodb::iresearch::IResearchView::make(vocbase, json->slice(), 0);
CHECK((false == !view));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(view.get());
REQUIRE((nullptr != viewImpl));
@ -2184,7 +1896,7 @@ SECTION("test_tracked_cids") {
{
s.engine.views.clear();
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto view = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), true);
auto view = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), 0);
CHECK((nullptr != view));
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(view.get());
REQUIRE((nullptr != viewImpl));
@ -2201,7 +1913,7 @@ SECTION("test_tracked_cids") {
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
REQUIRE((nullptr != logicalCollection));
auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), true);
auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), 0);
REQUIRE((false == !logicalView));
StorageEngineMock().registerView(&vocbase, logicalView); // ensure link can find view
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
@ -2230,7 +1942,7 @@ SECTION("test_tracked_cids") {
Vocbase vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
REQUIRE((nullptr != logicalCollection));
auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), true);
auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), 0);
REQUIRE((false == !logicalView));
StorageEngineMock().registerView(&vocbase, logicalView); // ensure link can find view
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());

View File

@ -39,11 +39,14 @@ namespace {
std::unique_ptr<arangodb::LogicalView> makeTestView(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
uint64_t planVersion
) {
struct Impl: public arangodb::LogicalView{
Impl(TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& info)
: arangodb::LogicalView(&vocbase, info) {
Impl(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
uint64_t planVersion
): arangodb::LogicalView(&vocbase, info, planVersion) {
}
virtual void drop() override {
deleted(true);
@ -68,7 +71,7 @@ std::unique_ptr<arangodb::LogicalView> makeTestView(
}
};
return std::make_unique<Impl>(vocbase, info);
return std::make_unique<Impl>(vocbase, info, planVersion);
}
}
@ -266,4 +269,4 @@ SECTION("test_getDataSource") {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

View File

@ -70,7 +70,7 @@ SECTION("test_category") {
class LogicalViewImpl: public arangodb::LogicalView {
public:
LogicalViewImpl(TRI_vocbase_t* vocbase, arangodb::velocypack::Slice const& definition)
: LogicalView(vocbase, definition) {
: LogicalView(vocbase, definition, 0) {
}
virtual void drop() override {}
virtual void open() override {}

View File

@ -40,11 +40,14 @@ namespace {
std::unique_ptr<arangodb::LogicalView> makeTestView(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
uint64_t planVersion
) {
struct Impl: public arangodb::LogicalView{
Impl(TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& info)
: LogicalView(&vocbase, info) {
Impl(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
uint64_t planVersion
): LogicalView(&vocbase, info, planVersion) {
}
virtual void drop() override {
deleted(true);
@ -69,7 +72,7 @@ std::unique_ptr<arangodb::LogicalView> makeTestView(
}
};
return std::make_unique<Impl>(vocbase, info);
return std::make_unique<Impl>(vocbase, info, planVersion);
}
}
@ -373,4 +376,4 @@ SECTION("test_lookupDataSource") {
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------