mirror of https://gitee.com/bigwinds/arangodb
issue 374.2: use a reference to vocbase instead of a pointer in StorageEngime LogicalDatasource related DDL operations, use vocbase from the found collection
This commit is contained in:
parent
fb84bb6f24
commit
d470371f7c
|
@ -153,17 +153,9 @@ void registerIndexFactory() {
|
|||
}
|
||||
|
||||
// ok to const-cast since this should only be called on startup
|
||||
auto* indexFactory =
|
||||
const_cast<arangodb::IndexFactory*>(engine->indexFactory());
|
||||
|
||||
if (!indexFactory) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_INTERNAL,
|
||||
std::string("failed to retieve index factory from feature '") + entry.first + "' while registering index type '" + indexType + "'"
|
||||
);
|
||||
}
|
||||
|
||||
auto res = indexFactory->emplaceFactory(indexType, entry.second);
|
||||
auto& indexFactory =
|
||||
const_cast<arangodb::IndexFactory&>(engine->indexFactory());
|
||||
auto res = indexFactory.emplaceFactory(indexType, entry.second);
|
||||
|
||||
if (!res.ok()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
|
@ -172,7 +164,7 @@ void registerIndexFactory() {
|
|||
);
|
||||
}
|
||||
|
||||
res = indexFactory->emplaceNormalizer(
|
||||
res = indexFactory.emplaceNormalizer(
|
||||
indexType, arangodb::iresearch::IResearchLink::normalize
|
||||
);
|
||||
|
||||
|
|
|
@ -45,20 +45,15 @@
|
|||
|
||||
namespace {
|
||||
|
||||
std::pair<TRI_vocbase_t*, arangodb::LogicalCollection*> lookupDatabaseAndCollection(
|
||||
std::shared_ptr<arangodb::LogicalCollection> lookupCollection(
|
||||
arangodb::DatabaseFeature& db,
|
||||
arangodb::RocksDBEngine& engine,
|
||||
uint64_t objectId
|
||||
) {
|
||||
auto pair = engine.mapObjectToCollection(objectId);
|
||||
|
||||
auto vocbase = db.useDatabase(pair.first);
|
||||
|
||||
if (vocbase == nullptr) {
|
||||
return std::make_pair(nullptr, nullptr);
|
||||
}
|
||||
|
||||
return std::make_pair(vocbase, vocbase->lookupCollection(pair.second).get());
|
||||
return vocbase ? vocbase->lookupCollection(pair.second) : nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<arangodb::Index>> lookupLinks(
|
||||
|
@ -344,9 +339,9 @@ void IResearchRocksDBRecoveryHelper::PutCF(uint32_t column_family_id,
|
|||
const rocksdb::Slice& key,
|
||||
const rocksdb::Slice& value) {
|
||||
if (column_family_id == _documentCF) {
|
||||
auto pair = lookupDatabaseAndCollection(*_dbFeature, *_engine, RocksDBKey::objectId(key));
|
||||
TRI_vocbase_t* vocbase = pair.first;
|
||||
LogicalCollection* coll = pair.second;
|
||||
auto coll =
|
||||
lookupCollection(*_dbFeature, *_engine, RocksDBKey::objectId(key));
|
||||
|
||||
if (coll == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -359,9 +354,9 @@ void IResearchRocksDBRecoveryHelper::PutCF(uint32_t column_family_id,
|
|||
|
||||
auto docId = RocksDBKey::documentId(RocksDBEntryType::Document, key);
|
||||
auto doc = RocksDBValue::data(value);
|
||||
|
||||
SingleCollectionTransaction trx(
|
||||
transaction::StandaloneContext::Create(vocbase), coll->id(),
|
||||
transaction::StandaloneContext::Create(&(coll->vocbase())),
|
||||
coll->id(),
|
||||
arangodb::AccessMode::Type::WRITE
|
||||
);
|
||||
|
||||
|
@ -387,9 +382,9 @@ void IResearchRocksDBRecoveryHelper::PutCF(uint32_t column_family_id,
|
|||
void IResearchRocksDBRecoveryHelper::DeleteCF(uint32_t column_family_id,
|
||||
const rocksdb::Slice& key) {
|
||||
if (column_family_id == _documentCF) {
|
||||
auto pair = lookupDatabaseAndCollection(*_dbFeature, *_engine, RocksDBKey::objectId(key));
|
||||
TRI_vocbase_t* vocbase = pair.first;
|
||||
LogicalCollection* coll = pair.second;
|
||||
auto coll =
|
||||
lookupCollection(*_dbFeature, *_engine, RocksDBKey::objectId(key));
|
||||
|
||||
if (coll == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -401,9 +396,9 @@ void IResearchRocksDBRecoveryHelper::DeleteCF(uint32_t column_family_id,
|
|||
}
|
||||
|
||||
auto docId = RocksDBKey::documentId(RocksDBEntryType::Document, key);
|
||||
|
||||
SingleCollectionTransaction trx(
|
||||
transaction::StandaloneContext::Create(vocbase), coll->id(),
|
||||
transaction::StandaloneContext::Create(&(coll->vocbase())),
|
||||
coll->id(),
|
||||
arangodb::AccessMode::Type::WRITE
|
||||
);
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ arangodb::Result persistProperties(
|
|||
if (!engine->inRecovery()) {
|
||||
// change view throws exception on error
|
||||
try {
|
||||
engine->changeView(&(view.vocbase()), view.id(), view, true);
|
||||
engine->changeView(view.vocbase(), view.id(), view, true);
|
||||
} catch (std::exception const& e) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_INTERNAL,
|
||||
|
@ -436,7 +436,7 @@ arangodb::Result persistProperties(
|
|||
|
||||
// change view throws exception on error
|
||||
try {
|
||||
engine->changeView(&(view.vocbase()), view.id(), view, true);
|
||||
engine->changeView(view.vocbase(), view.id(), view, true);
|
||||
} catch (std::exception const& e) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_INTERNAL,
|
||||
|
@ -1140,7 +1140,7 @@ IResearchView::~IResearchView() {
|
|||
if (deleted()) {
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
engine->destroyView(&vocbase(), this);
|
||||
engine->destroyView(vocbase(), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2229,7 +2229,8 @@ void IResearchView::verifyKnownCollections() {
|
|||
{
|
||||
static const arangodb::transaction::Options defaults;
|
||||
struct State final: public arangodb::TransactionState {
|
||||
State(): arangodb::TransactionState(nullptr, defaults) {}
|
||||
State(TRI_vocbase_t& vocbase)
|
||||
: arangodb::TransactionState(&vocbase, defaults) {}
|
||||
virtual arangodb::Result abortTransaction(
|
||||
arangodb::transaction::Methods*
|
||||
) override { return TRI_ERROR_NOT_IMPLEMENTED; }
|
||||
|
@ -2242,7 +2243,7 @@ void IResearchView::verifyKnownCollections() {
|
|||
virtual bool hasFailedOperations() const override { return false; }
|
||||
};
|
||||
|
||||
State state;
|
||||
State state(vocbase());
|
||||
|
||||
if (!appendKnownCollections(cids, *snapshot(state, true))) {
|
||||
LOG_TOPIC(ERR, IResearchFeature::IRESEARCH)
|
||||
|
|
|
@ -593,7 +593,7 @@ int MMFilesCollection::close() {
|
|||
"Database")
|
||||
->forceSyncProperties();
|
||||
engine->changeCollection(
|
||||
&(_logicalCollection->vocbase()),
|
||||
_logicalCollection->vocbase(),
|
||||
_logicalCollection->id(),
|
||||
_logicalCollection,
|
||||
doSync
|
||||
|
@ -1752,7 +1752,7 @@ void MMFilesCollection::open(bool ignoreErrors) {
|
|||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
auto& vocbase = _logicalCollection->vocbase();
|
||||
auto cid = _logicalCollection->id();
|
||||
engine->getCollectionInfo(&vocbase, cid, builder, true, 0);
|
||||
engine->getCollectionInfo(vocbase, cid, builder, true, 0);
|
||||
|
||||
VPackSlice initialCount =
|
||||
builder.slice().get(std::vector<std::string>({"parameters", "count"}));
|
||||
|
@ -1846,7 +1846,7 @@ void MMFilesCollection::open(bool ignoreErrors) {
|
|||
->forceSyncProperties();
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->changeCollection(
|
||||
&(_logicalCollection->vocbase()),
|
||||
_logicalCollection->vocbase(),
|
||||
_logicalCollection->id(),
|
||||
_logicalCollection,
|
||||
doSync
|
||||
|
@ -2052,8 +2052,7 @@ void MMFilesCollection::prepareIndexes(VPackSlice indexesSlice) {
|
|||
}
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
auto& idxFactory = engine->indexFactory();
|
||||
|
||||
for (auto const& v : VPackArrayIterator(indexesSlice)) {
|
||||
if (arangodb::basics::VelocyPackHelper::getBooleanValue(v, "error",
|
||||
|
@ -2064,7 +2063,7 @@ void MMFilesCollection::prepareIndexes(VPackSlice indexesSlice) {
|
|||
}
|
||||
|
||||
auto idx =
|
||||
idxFactory->prepareIndexFromSlice(v, false, _logicalCollection, true);
|
||||
idxFactory.prepareIndexFromSlice(v, false, _logicalCollection, true);
|
||||
|
||||
if (ServerState::instance()->isRunningInCluster()) {
|
||||
addIndexCoordinator(idx);
|
||||
|
@ -2117,10 +2116,9 @@ void MMFilesCollection::createInitialIndexes() {
|
|||
|
||||
std::vector<std::shared_ptr<arangodb::Index>> systemIndexes;
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
|
||||
idxFactory->fillSystemIndexes(_logicalCollection, systemIndexes);
|
||||
engine->indexFactory().fillSystemIndexes(_logicalCollection, systemIndexes);
|
||||
|
||||
for (auto const& it : systemIndexes) {
|
||||
addIndex(it);
|
||||
}
|
||||
|
@ -2165,16 +2163,16 @@ std::shared_ptr<Index> MMFilesCollection::createIndex(transaction::Methods* trx,
|
|||
}
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
|
||||
// We are sure that we do not have an index of this type.
|
||||
// We also hold the lock.
|
||||
// Create it
|
||||
|
||||
idx =
|
||||
idxFactory->prepareIndexFromSlice(info, true, _logicalCollection, false);
|
||||
idx = engine->indexFactory().prepareIndexFromSlice(
|
||||
info, true, _logicalCollection, false
|
||||
);
|
||||
TRI_ASSERT(idx != nullptr);
|
||||
|
||||
if (ServerState::instance()->isCoordinator()) {
|
||||
// In the coordinator case we do not fill the index
|
||||
// We only inform the others.
|
||||
|
@ -2248,7 +2246,7 @@ int MMFilesCollection::saveIndex(transaction::Methods* trx,
|
|||
VPackSlice data = builder->slice();
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->createIndex(&vocbase, collectionId, idx->id(), data);
|
||||
engine->createIndex(vocbase, collectionId, idx->id(), data);
|
||||
|
||||
if (!engine->inRecovery()) {
|
||||
// We need to write an index marker
|
||||
|
@ -2325,17 +2323,19 @@ int MMFilesCollection::restoreIndex(transaction::Methods* trx,
|
|||
// We create a new Index object to make sure that the index
|
||||
// is not handed out except for a successful case.
|
||||
std::shared_ptr<Index> newIdx;
|
||||
|
||||
try {
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
newIdx = idxFactory->prepareIndexFromSlice(info, false, _logicalCollection,
|
||||
false);
|
||||
|
||||
newIdx = engine->indexFactory().prepareIndexFromSlice(
|
||||
info, false, _logicalCollection, false
|
||||
);
|
||||
} catch (arangodb::basics::Exception const& e) {
|
||||
// Something with index creation went wrong.
|
||||
// Just report.
|
||||
return e.code();
|
||||
}
|
||||
|
||||
TRI_ASSERT(newIdx != nullptr);
|
||||
|
||||
TRI_UpdateTickServer(newIdx->id());
|
||||
|
@ -3199,7 +3199,7 @@ int MMFilesCollection::detectIndexes(transaction::Methods* trx) {
|
|||
VPackBuilder builder;
|
||||
|
||||
engine->getCollectionInfo(
|
||||
&(_logicalCollection->vocbase()),
|
||||
_logicalCollection->vocbase(),
|
||||
_logicalCollection->id(),
|
||||
builder,
|
||||
true,
|
||||
|
|
|
@ -480,11 +480,14 @@ void MMFilesEngine::getDatabases(arangodb::velocypack::Builder& result) {
|
|||
}
|
||||
|
||||
// fills the provided builder with information about the collection
|
||||
void MMFilesEngine::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::velocypack::Builder& builder,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick) {
|
||||
std::string const path = collectionDirectory(vocbase->id(), id);
|
||||
void MMFilesEngine::getCollectionInfo(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::velocypack::Builder& builder,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick
|
||||
) {
|
||||
auto path = collectionDirectory(vocbase.id(), id);
|
||||
|
||||
builder.openObject();
|
||||
|
||||
|
@ -544,11 +547,14 @@ void MMFilesEngine::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
|||
// indexes) that were detected by the storage engine. called at server start
|
||||
// only
|
||||
int MMFilesEngine::getCollectionsAndIndexes(
|
||||
TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown, bool isUpgrade) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade
|
||||
) {
|
||||
result.openArray();
|
||||
|
||||
std::string const path = databaseDirectory(vocbase->id());
|
||||
auto path = databaseDirectory(vocbase.id());
|
||||
std::vector<std::string> files = TRI_FilesDirectory(path.c_str());
|
||||
|
||||
for (auto const& name : files) {
|
||||
|
@ -593,7 +599,7 @@ int MMFilesEngine::getCollectionsAndIndexes(
|
|||
|
||||
try {
|
||||
LOG_TOPIC(TRACE, Logger::FIXME) << "loading collection info from directory '" << directory << "'";
|
||||
VPackBuilder builder = loadCollectionInfo(vocbase, directory);
|
||||
VPackBuilder builder = loadCollectionInfo(&vocbase, directory);
|
||||
VPackSlice info = builder.slice();
|
||||
|
||||
if (VelocyPackHelper::readBooleanValue(info, "deleted", false)) {
|
||||
|
@ -629,11 +635,12 @@ int MMFilesEngine::getCollectionsAndIndexes(
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int MMFilesEngine::getViews(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Builder& result) {
|
||||
int MMFilesEngine::getViews(
|
||||
TRI_vocbase_t& vocbase, arangodb::velocypack::Builder& result
|
||||
) {
|
||||
result.openArray();
|
||||
|
||||
std::string const path = databaseDirectory(vocbase->id());
|
||||
std::string const path = databaseDirectory(vocbase.id());
|
||||
std::vector<std::string> files = TRI_FilesDirectory(path.c_str());
|
||||
|
||||
for (auto const& name : files) {
|
||||
|
@ -668,7 +675,7 @@ int MMFilesEngine::getViews(TRI_vocbase_t* vocbase,
|
|||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
VPackBuilder builder = loadViewInfo(vocbase, directory);
|
||||
VPackBuilder builder = loadViewInfo(&vocbase, directory);
|
||||
VPackSlice info = builder.slice();
|
||||
|
||||
LOG_TOPIC(TRACE, Logger::FIXME) << "got view slice: " << info.toJson();
|
||||
|
@ -827,9 +834,11 @@ void MMFilesEngine::waitUntilDeletion(TRI_voc_tick_t id, bool force,
|
|||
// the WAL entry for the collection creation will be written *after* the call
|
||||
// to "createCollection" returns
|
||||
std::string MMFilesEngine::createCollection(
|
||||
TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters) {
|
||||
std::string const path = databasePath(vocbase);
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters
|
||||
) {
|
||||
auto path = databasePath(&vocbase);
|
||||
|
||||
// sanity check
|
||||
if (sizeof(MMFilesDatafileHeaderMarker) + sizeof(MMFilesDatafileFooterMarker) >
|
||||
|
@ -851,7 +860,7 @@ std::string MMFilesEngine::createCollection(
|
|||
TRI_ASSERT(id != 0);
|
||||
std::string const dirname = createCollectionDirectoryName(path, id);
|
||||
|
||||
registerCollectionPath(vocbase->id(), id, dirname);
|
||||
registerCollectionPath(vocbase.id(), id, dirname);
|
||||
|
||||
// directory must not exist
|
||||
if (TRI_ExistsFile(dirname.c_str())) {
|
||||
|
@ -931,7 +940,8 @@ std::string MMFilesEngine::createCollection(
|
|||
application_features::ApplicationServer::getFeature<DatabaseFeature>(
|
||||
"Database")
|
||||
->forceSyncProperties();
|
||||
saveCollectionInfo(vocbase, id, parameters, doSync);
|
||||
|
||||
saveCollectionInfo(&vocbase, id, parameters, doSync);
|
||||
|
||||
return dirname;
|
||||
}
|
||||
|
@ -940,9 +950,11 @@ std::string MMFilesEngine::createCollection(
|
|||
// After this call the collection is persisted over recovery.
|
||||
// This call will write wal markers.
|
||||
arangodb::Result MMFilesEngine::persistCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) {
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
|
||||
if (inRecovery()) {
|
||||
// Nothing to do. In recovery we do not write markers.
|
||||
return {};
|
||||
|
@ -958,9 +970,9 @@ arangodb::Result MMFilesEngine::persistCollection(
|
|||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
MMFilesCollectionMarker marker(TRI_DF_MARKER_VPACK_CREATE_COLLECTION,
|
||||
vocbase->id(), cid, slice);
|
||||
|
||||
MMFilesCollectionMarker marker(
|
||||
TRI_DF_MARKER_VPACK_CREATE_COLLECTION, vocbase.id(), cid, slice
|
||||
);
|
||||
MMFilesWalSlotInfoCopy slotInfo =
|
||||
MMFilesLogfileManager::instance()->allocateAndWrite(marker, false);
|
||||
|
||||
|
@ -988,7 +1000,9 @@ arangodb::Result MMFilesEngine::persistCollection(
|
|||
// still be readers of the collection's data.
|
||||
// This call will write the WAL entry for collection deletion
|
||||
arangodb::Result MMFilesEngine::dropCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
if (inRecovery()) {
|
||||
// nothing to do here
|
||||
return {};
|
||||
|
@ -1005,7 +1019,7 @@ arangodb::Result MMFilesEngine::dropCollection(
|
|||
|
||||
MMFilesCollectionMarker marker(
|
||||
TRI_DF_MARKER_VPACK_DROP_COLLECTION,
|
||||
vocbase->id(),
|
||||
vocbase.id(),
|
||||
collection->id(),
|
||||
builder.slice()
|
||||
);
|
||||
|
@ -1033,17 +1047,18 @@ arangodb::Result MMFilesEngine::dropCollection(
|
|||
// perform a physical deletion of the collection
|
||||
// After this call data of this collection is corrupted, only perform if
|
||||
// assured that no one is using the collection anymore
|
||||
void MMFilesEngine::destroyCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection* collection) {
|
||||
void MMFilesEngine::destroyCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
std::string const name(collection->name());
|
||||
auto physical = static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
unregisterCollectionPath(vocbase->id(), collection->id());
|
||||
|
||||
unregisterCollectionPath(vocbase.id(), collection->id());
|
||||
|
||||
// delete persistent indexes
|
||||
MMFilesPersistentIndexFeature::dropCollection(
|
||||
vocbase->id(), collection->id()
|
||||
);
|
||||
MMFilesPersistentIndexFeature::dropCollection(vocbase.id(), collection->id());
|
||||
|
||||
// rename collection directory
|
||||
if (physical->path().empty()) {
|
||||
|
@ -1138,21 +1153,28 @@ void MMFilesEngine::destroyCollection(TRI_vocbase_t* vocbase,
|
|||
// the WAL entry for the propery change will be written *after* the call
|
||||
// to "changeCollection" returns
|
||||
void MMFilesEngine::changeCollection(
|
||||
TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters, bool doSync) {
|
||||
saveCollectionInfo(vocbase, id, parameters, doSync);
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters,
|
||||
bool doSync
|
||||
) {
|
||||
saveCollectionInfo(&vocbase, id, parameters, doSync);
|
||||
}
|
||||
|
||||
// asks the storage engine to persist renaming of a collection
|
||||
// This will write a renameMarker if not in recovery
|
||||
Result MMFilesEngine::renameCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName
|
||||
) {
|
||||
if (inRecovery()) {
|
||||
// Nothing todo. Marker already there
|
||||
return {};
|
||||
}
|
||||
|
||||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
VPackBuilder builder;
|
||||
builder.openObject();
|
||||
|
@ -1163,7 +1185,7 @@ Result MMFilesEngine::renameCollection(
|
|||
|
||||
MMFilesCollectionMarker marker(
|
||||
TRI_DF_MARKER_VPACK_RENAME_COLLECTION,
|
||||
vocbase->id(),
|
||||
vocbase.id(),
|
||||
collection->id(),
|
||||
builder.slice()
|
||||
);
|
||||
|
@ -1192,7 +1214,7 @@ Result MMFilesEngine::renameCollection(
|
|||
// asks the storage engine to persist renaming of a view
|
||||
// This will write a renameMarker if not in recovery
|
||||
Result MMFilesEngine::renameView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view,
|
||||
std::string const& oldName
|
||||
) {
|
||||
|
@ -1213,7 +1235,7 @@ Result MMFilesEngine::renameView(
|
|||
builder.close();
|
||||
|
||||
MMFilesViewMarker marker(
|
||||
TRI_DF_MARKER_VPACK_RENAME_VIEW, vocbase->id(), view.id(), builder.slice()
|
||||
TRI_DF_MARKER_VPACK_RENAME_VIEW, vocbase.id(), view.id(), builder.slice()
|
||||
);
|
||||
MMFilesWalSlotInfoCopy slotInfo =
|
||||
MMFilesLogfileManager::instance()->allocateAndWrite(marker, false);
|
||||
|
@ -1239,11 +1261,11 @@ Result MMFilesEngine::renameView(
|
|||
}
|
||||
|
||||
void MMFilesEngine::createView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view
|
||||
) {
|
||||
std::string const path = databasePath(vocbase);
|
||||
std::string const path = databasePath(&vocbase);
|
||||
|
||||
if (!TRI_IsDirectory(path.c_str())) {
|
||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
|
||||
|
@ -1255,7 +1277,7 @@ void MMFilesEngine::createView(
|
|||
TRI_ASSERT(id != 0);
|
||||
std::string const dirname = createViewDirectoryName(path, id);
|
||||
|
||||
registerViewPath(vocbase->id(), id, dirname);
|
||||
registerViewPath(vocbase.id(), id, dirname);
|
||||
|
||||
// directory must not exist
|
||||
if (TRI_ExistsFile(dirname.c_str())) {
|
||||
|
@ -1337,24 +1359,22 @@ void MMFilesEngine::createView(
|
|||
"Database")
|
||||
->forceSyncProperties();
|
||||
|
||||
saveViewInfo(vocbase, id, &view, doSync);
|
||||
saveViewInfo(&vocbase, id, &view, doSync);
|
||||
}
|
||||
|
||||
void MMFilesEngine::getViewProperties(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const* view,
|
||||
VPackBuilder& result
|
||||
) {
|
||||
TRI_ASSERT(result.isOpenObject());
|
||||
result.add("path", VPackValue(viewDirectory(vocbase->id(), view->id())));
|
||||
result.add("path", VPackValue(viewDirectory(vocbase.id(), view->id())));
|
||||
}
|
||||
|
||||
arangodb::Result MMFilesEngine::persistView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view
|
||||
) {
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
|
||||
if (inRecovery()) {
|
||||
// Nothing to do. In recovery we do not write markers.
|
||||
return {};
|
||||
|
@ -1375,9 +1395,9 @@ arangodb::Result MMFilesEngine::persistView(
|
|||
int res = TRI_ERROR_NO_ERROR;
|
||||
|
||||
try {
|
||||
MMFilesViewMarker marker(TRI_DF_MARKER_VPACK_CREATE_VIEW, vocbase->id(), id,
|
||||
slice);
|
||||
|
||||
MMFilesViewMarker marker(
|
||||
TRI_DF_MARKER_VPACK_CREATE_VIEW, vocbase.id(), id, slice
|
||||
);
|
||||
MMFilesWalSlotInfoCopy slotInfo =
|
||||
MMFilesLogfileManager::instance()->allocateAndWrite(marker, false);
|
||||
|
||||
|
@ -1399,11 +1419,12 @@ arangodb::Result MMFilesEngine::persistView(
|
|||
}
|
||||
|
||||
arangodb::Result MMFilesEngine::dropView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view) {
|
||||
auto* db = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
|
||||
TRI_ASSERT(db);
|
||||
saveViewInfo(vocbase, view->id(), view, db->forceSyncProperties());
|
||||
saveViewInfo(&vocbase, view->id(), view, db->forceSyncProperties());
|
||||
|
||||
if (inRecovery()) {
|
||||
// nothing to do here
|
||||
|
@ -1418,9 +1439,9 @@ arangodb::Result MMFilesEngine::dropView(
|
|||
builder.add("name", VPackValue(view->name()));
|
||||
builder.close();
|
||||
|
||||
MMFilesViewMarker marker(TRI_DF_MARKER_VPACK_DROP_VIEW, vocbase->id(),
|
||||
view->id(), builder.slice());
|
||||
|
||||
MMFilesViewMarker marker(
|
||||
TRI_DF_MARKER_VPACK_DROP_VIEW, vocbase.id(), view->id(), builder.slice()
|
||||
);
|
||||
MMFilesWalSlotInfoCopy slotInfo =
|
||||
MMFilesLogfileManager::instance()->allocateAndWrite(marker, false);
|
||||
|
||||
|
@ -1442,10 +1463,10 @@ arangodb::Result MMFilesEngine::dropView(
|
|||
}
|
||||
|
||||
void MMFilesEngine::destroyView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view) noexcept {
|
||||
try {
|
||||
std::string const directory = viewDirectory(vocbase->id(), view->id());
|
||||
auto directory = viewDirectory(vocbase.id(), view->id());
|
||||
|
||||
if (directory.empty()) {
|
||||
return;
|
||||
|
@ -1489,7 +1510,7 @@ void MMFilesEngine::saveViewInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
|||
// the WAL entry for the propery change will be written *after* the call
|
||||
// to "changeView" returns
|
||||
void MMFilesEngine::changeView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view,
|
||||
bool doSync
|
||||
|
@ -1503,7 +1524,7 @@ void MMFilesEngine::changeView(
|
|||
infoBuilder.close();
|
||||
|
||||
MMFilesViewMarker marker(
|
||||
TRI_DF_MARKER_VPACK_CHANGE_VIEW, vocbase->id(), id, infoBuilder.slice()
|
||||
TRI_DF_MARKER_VPACK_CHANGE_VIEW, vocbase.id(), id, infoBuilder.slice()
|
||||
);
|
||||
|
||||
MMFilesWalSlotInfoCopy slotInfo =
|
||||
|
@ -1517,7 +1538,7 @@ void MMFilesEngine::changeView(
|
|||
}
|
||||
}
|
||||
|
||||
saveViewInfo(vocbase, id, &view, doSync);
|
||||
saveViewInfo(&vocbase, id, &view, doSync);
|
||||
}
|
||||
|
||||
// asks the storage engine to create an index as specified in the VPack
|
||||
|
@ -1530,11 +1551,14 @@ void MMFilesEngine::changeView(
|
|||
// creation requests will not fail.
|
||||
// the WAL entry for the index creation will be written *after* the call
|
||||
// to "createIndex" returns
|
||||
void MMFilesEngine::createIndex(TRI_vocbase_t* vocbase,
|
||||
TRI_voc_cid_t collectionId, TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data) {
|
||||
void MMFilesEngine::createIndex(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data
|
||||
) {
|
||||
// construct filename
|
||||
std::string const filename = indexFilename(vocbase->id(), collectionId, id);
|
||||
auto filename = indexFilename(vocbase.id(), collectionId, id);
|
||||
|
||||
// and save
|
||||
bool const doSync =
|
||||
|
@ -1638,15 +1662,17 @@ static bool UnloadCollectionCallback(LogicalCollection* collection) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void MMFilesEngine::unloadCollection(TRI_vocbase_t* vocbase,
|
||||
LogicalCollection* collection) {
|
||||
void MMFilesEngine::unloadCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
LogicalCollection* collection
|
||||
) {
|
||||
// add callback for unload
|
||||
arangodb::MMFilesCollection::toMMFilesCollection(collection)
|
||||
->ditches()
|
||||
->createMMFilesUnloadCollectionDitch(collection, UnloadCollectionCallback,
|
||||
__FILE__, __LINE__);
|
||||
|
||||
signalCleanup(vocbase);
|
||||
signalCleanup(&vocbase);
|
||||
}
|
||||
|
||||
void MMFilesEngine::signalCleanup(TRI_vocbase_t* vocbase) {
|
||||
|
@ -2059,7 +2085,7 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
// scan the database path for views
|
||||
try {
|
||||
VPackBuilder builder;
|
||||
int res = getViews(vocbase.get(), builder);
|
||||
int res = getViews(*vocbase, builder);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -2091,7 +2117,7 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message.c_str());
|
||||
}
|
||||
|
||||
StorageEngine::registerView(vocbase.get(), view);
|
||||
StorageEngine::registerView(*vocbase, view);
|
||||
|
||||
registerViewPath(vocbase->id(), view->id(), viewPath);
|
||||
|
||||
|
@ -2110,8 +2136,8 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
// scan the database path for collections
|
||||
try {
|
||||
VPackBuilder builder;
|
||||
int res = getCollectionsAndIndexes(vocbase.get(), builder, wasCleanShutdown,
|
||||
isUpgrade);
|
||||
int res =
|
||||
getCollectionsAndIndexes(*vocbase, builder, wasCleanShutdown, isUpgrade);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -2129,8 +2155,7 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
std::make_shared<arangodb::LogicalCollection>(*vocbase, it, false);
|
||||
auto collection = uniqCol.get();
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
StorageEngine::registerCollection(vocbase.get(), uniqCol);
|
||||
|
||||
StorageEngine::registerCollection(*vocbase, uniqCol);
|
||||
auto physical =
|
||||
static_cast<MMFilesCollection*>(collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
|
|
@ -134,21 +134,30 @@ class MMFilesEngine final : public StorageEngine {
|
|||
void getDatabases(arangodb::velocypack::Builder& result) override;
|
||||
|
||||
// fills the provided builder with information about the collection
|
||||
void getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes, TRI_voc_tick_t maxTick) override;
|
||||
void getCollectionInfo(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick
|
||||
) override;
|
||||
|
||||
// fill the Builder object with an array of collections (and their
|
||||
// corresponding
|
||||
// indexes) that were detected by the storage engine. called at server start
|
||||
// separately
|
||||
// for each database
|
||||
int getCollectionsAndIndexes(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown, bool isUpgrade) override;
|
||||
int getCollectionsAndIndexes(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade
|
||||
) override;
|
||||
|
||||
int getViews(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Builder& result) override;
|
||||
int getViews(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result
|
||||
) override;
|
||||
|
||||
// return the path for a collection
|
||||
std::string collectionPath(TRI_vocbase_t const* vocbase,
|
||||
|
@ -214,28 +223,37 @@ class MMFilesEngine final : public StorageEngine {
|
|||
// not fail.
|
||||
// the WAL entry for the collection creation will be written *after* the call
|
||||
// to "createCollection" returns
|
||||
std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const*) override;
|
||||
std::string createCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) override;
|
||||
|
||||
// asks the storage engine to persist the collection.
|
||||
// After this call the collection is persisted over recovery.
|
||||
// This call will write wal markers.
|
||||
arangodb::Result persistCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const*) override;
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) override;
|
||||
|
||||
// asks the storage engine to drop the specified collection and persist the
|
||||
// deletion info. Note that physical deletion of the collection data must not
|
||||
// be carried out by this call, as there may
|
||||
// still be readers of the collection's data.
|
||||
// This call will write the WAL entry for collection deletion
|
||||
arangodb::Result dropCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection*) override;
|
||||
arangodb::Result dropCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) override;
|
||||
|
||||
// perform a physical deletion of the collection
|
||||
// After this call data of this collection is corrupted, only perform if
|
||||
// assured that no one is using the collection anymore
|
||||
void destroyCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection*) override;
|
||||
void destroyCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) override;
|
||||
|
||||
// asks the storage engine to change properties of the collection as specified
|
||||
// in
|
||||
|
@ -245,15 +263,20 @@ class MMFilesEngine final : public StorageEngine {
|
|||
// not fail.
|
||||
// the WAL entry for the propery change will be written *after* the call
|
||||
// to "changeCollection" returns
|
||||
void changeCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const*,
|
||||
bool doSync) override;
|
||||
void changeCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
bool doSync
|
||||
) override;
|
||||
|
||||
// asks the storage engine to persist renaming of a collection
|
||||
// This will write a renameMarker if not in recovery
|
||||
arangodb::Result renameCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection const*,
|
||||
std::string const& oldName) override;
|
||||
arangodb::Result renameCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName
|
||||
) override;
|
||||
|
||||
// asks the storage engine to create an index as specified in the VPack
|
||||
// Slice object and persist the creation info. The database id, collection id
|
||||
|
@ -266,9 +289,12 @@ class MMFilesEngine final : public StorageEngine {
|
|||
// creation requests will not fail.
|
||||
// the WAL entry for the index creation will be written *after* the call
|
||||
// to "createIndex" returns
|
||||
void createIndex(TRI_vocbase_t* vocbase, TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data) override;
|
||||
void createIndex(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data
|
||||
) override;
|
||||
|
||||
// asks the storage engine to drop the specified index and persist the
|
||||
// deletion
|
||||
|
@ -287,44 +313,52 @@ class MMFilesEngine final : public StorageEngine {
|
|||
arangodb::velocypack::Slice const& data,
|
||||
bool writeMarker, int&);
|
||||
|
||||
void unloadCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection* collection) override;
|
||||
void unloadCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) override;
|
||||
|
||||
void changeView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const&,
|
||||
bool doSync
|
||||
) override;
|
||||
|
||||
void createView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view
|
||||
) override;
|
||||
|
||||
void getViewProperties(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const* view,
|
||||
VPackBuilder& builder
|
||||
) override;
|
||||
|
||||
arangodb::Result persistView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view
|
||||
) override;
|
||||
|
||||
// asks the storage engine to persist renaming of a view
|
||||
// This will write a renameMarker if not in recovery
|
||||
arangodb::Result renameView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view,
|
||||
std::string const& oldName
|
||||
) override;
|
||||
|
||||
arangodb::Result dropView(TRI_vocbase_t* vocbase, arangodb::LogicalView*) override;
|
||||
arangodb::Result dropView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) override;
|
||||
|
||||
void destroyView(TRI_vocbase_t* vocbase, arangodb::LogicalView*) noexcept override;
|
||||
void destroyView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) noexcept override;
|
||||
|
||||
std::string createViewDirectoryName(std::string const& basePath,
|
||||
TRI_voc_cid_t id);
|
||||
|
|
|
@ -302,10 +302,10 @@ void RocksDBCollection::prepareIndexes(
|
|||
}
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
auto& idxFactory = engine->indexFactory();
|
||||
bool splitEdgeIndex = false;
|
||||
TRI_idx_iid_t last = 0;
|
||||
|
||||
for (auto const& v : VPackArrayIterator(indexesSlice)) {
|
||||
if (arangodb::basics::VelocyPackHelper::getBooleanValue(v, "error",
|
||||
false)) {
|
||||
|
@ -359,8 +359,9 @@ void RocksDBCollection::prepareIndexes(
|
|||
}
|
||||
to.close();
|
||||
|
||||
auto idxFrom = idxFactory->prepareIndexFromSlice(
|
||||
from.slice(), false, _logicalCollection, true);
|
||||
auto idxFrom = idxFactory.prepareIndexFromSlice(
|
||||
from.slice(), false, _logicalCollection, true
|
||||
);
|
||||
|
||||
if (ServerState::instance()->isRunningInCluster()) {
|
||||
addIndexCoordinator(idxFrom);
|
||||
|
@ -368,8 +369,9 @@ void RocksDBCollection::prepareIndexes(
|
|||
addIndex(idxFrom);
|
||||
}
|
||||
|
||||
auto idxTo = idxFactory->prepareIndexFromSlice(
|
||||
to.slice(), false, _logicalCollection, true);
|
||||
auto idxTo = idxFactory.prepareIndexFromSlice(
|
||||
to.slice(), false, _logicalCollection, true
|
||||
);
|
||||
|
||||
if (ServerState::instance()->isRunningInCluster()) {
|
||||
addIndexCoordinator(idxTo);
|
||||
|
@ -394,8 +396,9 @@ void RocksDBCollection::prepareIndexes(
|
|||
}
|
||||
b.close();
|
||||
|
||||
auto idx = idxFactory->prepareIndexFromSlice(b.slice(), false,
|
||||
_logicalCollection, true);
|
||||
auto idx = idxFactory.prepareIndexFromSlice(
|
||||
b.slice(), false, _logicalCollection, true
|
||||
);
|
||||
|
||||
if (ServerState::instance()->isRunningInCluster()) {
|
||||
addIndexCoordinator(idx);
|
||||
|
@ -409,7 +412,7 @@ void RocksDBCollection::prepareIndexes(
|
|||
|
||||
if (!alreadyHandled) {
|
||||
auto idx =
|
||||
idxFactory->prepareIndexFromSlice(v, false, _logicalCollection, true);
|
||||
idxFactory.prepareIndexFromSlice(v, false, _logicalCollection, true);
|
||||
|
||||
if (ServerState::instance()->isRunningInCluster()) {
|
||||
addIndexCoordinator(idx);
|
||||
|
@ -491,16 +494,16 @@ std::shared_ptr<Index> RocksDBCollection::createIndex(
|
|||
}
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
|
||||
// We are sure that we do not have an index of this type.
|
||||
// We also hold the lock.
|
||||
// Create it
|
||||
|
||||
idx =
|
||||
idxFactory->prepareIndexFromSlice(info, true, _logicalCollection, false);
|
||||
idx = engine->indexFactory().prepareIndexFromSlice(
|
||||
info, true, _logicalCollection, false
|
||||
);
|
||||
TRI_ASSERT(idx != nullptr);
|
||||
|
||||
if (ServerState::instance()->isCoordinator()) {
|
||||
// In the coordinator case we do not fill the index
|
||||
// We only inform the others.
|
||||
|
@ -573,17 +576,19 @@ int RocksDBCollection::restoreIndex(transaction::Methods* trx,
|
|||
// We create a new Index object to make sure that the index
|
||||
// is not handed out except for a successful case.
|
||||
std::shared_ptr<Index> newIdx;
|
||||
|
||||
try {
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
newIdx = idxFactory->prepareIndexFromSlice(info, false, _logicalCollection,
|
||||
false);
|
||||
|
||||
newIdx = engine->indexFactory().prepareIndexFromSlice(
|
||||
info, false, _logicalCollection, false
|
||||
);
|
||||
} catch (arangodb::basics::Exception const& e) {
|
||||
// Something with index creation went wrong.
|
||||
// Just report.
|
||||
return e.code();
|
||||
}
|
||||
|
||||
TRI_ASSERT(newIdx != nullptr);
|
||||
|
||||
auto const id = newIdx->id();
|
||||
|
@ -1292,10 +1297,9 @@ void RocksDBCollection::createInitialIndexes() {
|
|||
|
||||
std::vector<std::shared_ptr<arangodb::Index>> systemIndexes;
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
TRI_ASSERT(idxFactory != nullptr);
|
||||
|
||||
idxFactory->fillSystemIndexes(_logicalCollection, systemIndexes);
|
||||
engine->indexFactory().fillSystemIndexes(_logicalCollection, systemIndexes);
|
||||
|
||||
for (auto const& it : systemIndexes) {
|
||||
addIndex(it);
|
||||
}
|
||||
|
@ -1363,7 +1367,7 @@ int RocksDBCollection::saveIndex(transaction::Methods* trx,
|
|||
VPackSlice data = builder->slice();
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->createIndex(&vocbase, collectionId, idx->id(), data);
|
||||
engine->createIndex(vocbase, collectionId, idx->id(), data);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
|
|
@ -738,15 +738,20 @@ void RocksDBEngine::getDatabases(arangodb::velocypack::Builder& result) {
|
|||
result.close();
|
||||
}
|
||||
|
||||
void RocksDBEngine::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& builder,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick) {
|
||||
void RocksDBEngine::getCollectionInfo(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& builder,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick
|
||||
) {
|
||||
builder.openObject();
|
||||
|
||||
// read collection info from database
|
||||
RocksDBKey key;
|
||||
key.constructCollection(vocbase->id(), cid);
|
||||
|
||||
key.constructCollection(vocbase.id(), cid);
|
||||
|
||||
rocksdb::PinnableSlice value;
|
||||
rocksdb::ReadOptions options;
|
||||
rocksdb::Status res = _db->Get(options, RocksDBColumnFamily::definitions(),
|
||||
|
@ -784,17 +789,22 @@ void RocksDBEngine::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
|||
}
|
||||
|
||||
int RocksDBEngine::getCollectionsAndIndexes(
|
||||
TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown, bool isUpgrade) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade
|
||||
) {
|
||||
rocksdb::ReadOptions readOptions;
|
||||
std::unique_ptr<rocksdb::Iterator> iter(
|
||||
_db->NewIterator(readOptions, RocksDBColumnFamily::definitions()));
|
||||
|
||||
result.openArray();
|
||||
|
||||
auto rSlice = rocksDBSlice(RocksDBEntryType::Collection);
|
||||
|
||||
for (iter->Seek(rSlice); iter->Valid() && iter->key().starts_with(rSlice);
|
||||
iter->Next()) {
|
||||
if (vocbase->id() != RocksDBKey::databaseId(iter->key())) {
|
||||
if (vocbase.id() != RocksDBKey::databaseId(iter->key())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -812,14 +822,17 @@ int RocksDBEngine::getCollectionsAndIndexes(
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int RocksDBEngine::getViews(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Builder& result) {
|
||||
int RocksDBEngine::getViews(
|
||||
TRI_vocbase_t& vocbase, arangodb::velocypack::Builder& result
|
||||
) {
|
||||
rocksdb::ReadOptions readOptions;
|
||||
std::unique_ptr<rocksdb::Iterator> iter(
|
||||
_db->NewIterator(readOptions, RocksDBColumnFamily::definitions()));
|
||||
|
||||
result.openArray();
|
||||
auto bounds = RocksDBKeyBounds::DatabaseViews(vocbase->id());
|
||||
|
||||
auto bounds = RocksDBKeyBounds::DatabaseViews(vocbase.id());
|
||||
|
||||
for (iter->Seek(bounds.start());
|
||||
iter->Valid() && iter->key().compare(bounds.end()) < 0; iter->Next()) {
|
||||
auto slice = VPackSlice(iter->value().data());
|
||||
|
@ -830,6 +843,7 @@ int RocksDBEngine::getViews(TRI_vocbase_t* vocbase,
|
|||
false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.add(slice);
|
||||
}
|
||||
|
||||
|
@ -1026,8 +1040,10 @@ void RocksDBEngine::recoveryDone(TRI_vocbase_t* vocbase) {
|
|||
}
|
||||
|
||||
std::string RocksDBEngine::createCollection(
|
||||
TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
||||
arangodb::LogicalCollection const* collection) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) {
|
||||
VPackBuilder builder = collection->toVelocyPackIgnore(
|
||||
{"path", "statusString"}, /*translate cid*/ true,
|
||||
/*for persistence*/ true);
|
||||
|
@ -1036,8 +1052,11 @@ std::string RocksDBEngine::createCollection(
|
|||
TRI_UpdateTickServer(static_cast<TRI_voc_tick_t>(cid));
|
||||
|
||||
int res = writeCreateCollectionMarker(
|
||||
vocbase->id(), cid, builder.slice(),
|
||||
RocksDBLogValue::CollectionCreate(vocbase->id(), cid));
|
||||
vocbase.id(),
|
||||
cid,
|
||||
builder.slice(),
|
||||
RocksDBLogValue::CollectionCreate(vocbase.id(), cid)
|
||||
);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -1052,12 +1071,16 @@ std::string RocksDBEngine::createCollection(
|
|||
}
|
||||
|
||||
arangodb::Result RocksDBEngine::persistCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) {
|
||||
return {};
|
||||
}
|
||||
|
||||
arangodb::Result RocksDBEngine::dropCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
RocksDBCollection* coll = toRocksDBCollection(collection->getPhysical());
|
||||
uint64_t const numberDocuments = coll->numberDocuments();
|
||||
|
||||
|
@ -1084,13 +1107,15 @@ arangodb::Result RocksDBEngine::dropCollection(
|
|||
|
||||
// Prepare collection remove batch
|
||||
RocksDBLogValue logValue = RocksDBLogValue::CollectionDrop(
|
||||
vocbase->id(), collection->id(), StringRef(collection->globallyUniqueId())
|
||||
vocbase.id(), collection->id(), StringRef(collection->globallyUniqueId())
|
||||
);
|
||||
rocksdb::WriteBatch batch;
|
||||
batch.PutLogData(logValue.slice());
|
||||
RocksDBKey key;
|
||||
key.constructCollection(vocbase->id(), collection->id());
|
||||
|
||||
key.constructCollection(vocbase.id(), collection->id());
|
||||
batch.Delete(RocksDBColumnFamily::definitions(), key.string());
|
||||
|
||||
rocksdb::Status res = _db->Write(wo, &batch);
|
||||
|
||||
// TODO FAILURE Simulate !res.ok()
|
||||
|
@ -1166,21 +1191,29 @@ arangodb::Result RocksDBEngine::dropCollection(
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void RocksDBEngine::destroyCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection*) {
|
||||
void RocksDBEngine::destroyCollection(
|
||||
TRI_vocbase_t& /*vocbase*/,
|
||||
arangodb::LogicalCollection* /*collection*/
|
||||
) {
|
||||
// not required
|
||||
}
|
||||
|
||||
void RocksDBEngine::changeCollection(
|
||||
TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters, bool doSync) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters,
|
||||
bool doSync
|
||||
) {
|
||||
VPackBuilder builder = parameters->toVelocyPackIgnore(
|
||||
{"path", "statusString"}, /*translate cid*/ true,
|
||||
/*for persistence*/ true);
|
||||
|
||||
int res = writeCreateCollectionMarker(
|
||||
vocbase->id(), id, builder.slice(),
|
||||
RocksDBLogValue::CollectionChange(vocbase->id(), id));
|
||||
vocbase.id(),
|
||||
id,
|
||||
builder.slice(),
|
||||
RocksDBLogValue::CollectionChange(vocbase.id(), id)
|
||||
);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -1188,43 +1221,52 @@ void RocksDBEngine::changeCollection(
|
|||
}
|
||||
|
||||
arangodb::Result RocksDBEngine::renameCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName) {
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName
|
||||
) {
|
||||
VPackBuilder builder =
|
||||
collection->toVelocyPackIgnore({"path", "statusString"}, true, true);
|
||||
int res = writeCreateCollectionMarker(
|
||||
vocbase->id(),
|
||||
vocbase.id(),
|
||||
collection->id(),
|
||||
builder.slice(),
|
||||
RocksDBLogValue::CollectionRename(
|
||||
vocbase->id(), collection->id(), StringRef(oldName)
|
||||
vocbase.id(), collection->id(), StringRef(oldName)
|
||||
)
|
||||
);
|
||||
|
||||
return arangodb::Result(res);
|
||||
}
|
||||
|
||||
void RocksDBEngine::createIndex(TRI_vocbase_t* vocbase,
|
||||
TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t indexId,
|
||||
arangodb::velocypack::Slice const& data) {}
|
||||
void RocksDBEngine::createIndex(
|
||||
TRI_vocbase_t& /*vocbase*/,
|
||||
TRI_voc_cid_t /*collectionId*/,
|
||||
TRI_idx_iid_t /*indexId*/,
|
||||
arangodb::velocypack::Slice const& /*data*/
|
||||
) {
|
||||
}
|
||||
|
||||
void RocksDBEngine::unloadCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection* collection) {
|
||||
void RocksDBEngine::unloadCollection(
|
||||
TRI_vocbase_t& /*vocbase*/,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
collection->setStatus(TRI_VOC_COL_STATUS_UNLOADED);
|
||||
}
|
||||
|
||||
void RocksDBEngine::createView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& /*view*/
|
||||
) {
|
||||
rocksdb::WriteBatch batch;
|
||||
rocksdb::WriteOptions wo;
|
||||
|
||||
RocksDBLogValue logValue = RocksDBLogValue::ViewCreate(vocbase->id(), id);
|
||||
RocksDBLogValue logValue = RocksDBLogValue::ViewCreate(vocbase.id(), id);
|
||||
RocksDBKey key;
|
||||
key.constructView(vocbase->id(), id);
|
||||
|
||||
key.constructView(vocbase.id(), id);
|
||||
|
||||
auto value = RocksDBValue::View(VPackSlice::emptyObjectSlice());
|
||||
|
||||
// Write marker + key into RocksDB inside one batch
|
||||
|
@ -1241,7 +1283,7 @@ void RocksDBEngine::createView(
|
|||
// asks the storage engine to persist renaming of a view
|
||||
// This will write a renameMarker if not in recovery
|
||||
Result RocksDBEngine::renameView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view,
|
||||
std::string const& /*oldName*/
|
||||
) {
|
||||
|
@ -1249,13 +1291,13 @@ Result RocksDBEngine::renameView(
|
|||
}
|
||||
|
||||
arangodb::Result RocksDBEngine::persistView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view
|
||||
) {
|
||||
auto db = rocksutils::globalRocksDB();
|
||||
RocksDBKey key;
|
||||
|
||||
key.constructView(vocbase->id(), view.id());
|
||||
key.constructView(vocbase.id(), view.id());
|
||||
|
||||
VPackBuilder infoBuilder;
|
||||
|
||||
|
@ -1275,18 +1317,19 @@ arangodb::Result RocksDBEngine::persistView(
|
|||
}
|
||||
|
||||
arangodb::Result RocksDBEngine::dropView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view) {
|
||||
VPackBuilder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->toVelocyPack(builder, true, true);
|
||||
builder.close();
|
||||
RocksDBLogValue logValue = RocksDBLogValue::ViewDrop(
|
||||
vocbase->id(), view->id(), builder.slice()
|
||||
);
|
||||
|
||||
auto logValue =
|
||||
RocksDBLogValue::ViewDrop(vocbase.id(), view->id(), builder.slice());
|
||||
RocksDBKey key;
|
||||
key.constructView(vocbase->id(), view->id());
|
||||
|
||||
key.constructView(vocbase.id(), view->id());
|
||||
|
||||
rocksdb::WriteBatch batch;
|
||||
rocksdb::WriteOptions wo; // TODO: check which options would make sense
|
||||
|
@ -1299,13 +1342,13 @@ arangodb::Result RocksDBEngine::dropView(
|
|||
}
|
||||
|
||||
void RocksDBEngine::destroyView(
|
||||
TRI_vocbase_t* /*vocbase*/,
|
||||
TRI_vocbase_t& /*vocbase*/,
|
||||
arangodb::LogicalView* /*view*/) noexcept {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
void RocksDBEngine::changeView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t /*id*/,
|
||||
arangodb::LogicalView const& view,
|
||||
bool /*doSync*/
|
||||
|
@ -1689,7 +1732,7 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
// scan the database path for views
|
||||
try {
|
||||
VPackBuilder builder;
|
||||
int res = getViews(vocbase.get(), builder);
|
||||
int res = getViews(*vocbase, builder);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -1711,7 +1754,7 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message.c_str());
|
||||
}
|
||||
|
||||
StorageEngine::registerView(vocbase.get(), view);
|
||||
StorageEngine::registerView(*vocbase, view);
|
||||
|
||||
view->open();
|
||||
}
|
||||
|
@ -1728,8 +1771,8 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
// scan the database path for collections
|
||||
try {
|
||||
VPackBuilder builder;
|
||||
int res = getCollectionsAndIndexes(vocbase.get(), builder, wasCleanShutdown,
|
||||
isUpgrade);
|
||||
int res =
|
||||
getCollectionsAndIndexes(*vocbase, builder, wasCleanShutdown, isUpgrade);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
|
@ -1745,8 +1788,7 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
std::make_shared<arangodb::LogicalCollection>(*vocbase, it, false);
|
||||
auto collection = uniqCol.get();
|
||||
TRI_ASSERT(collection != nullptr);
|
||||
StorageEngine::registerCollection(vocbase.get(), uniqCol);
|
||||
|
||||
StorageEngine::registerCollection(*vocbase, uniqCol);
|
||||
auto physical =
|
||||
static_cast<RocksDBCollection*>(collection->getPhysical());
|
||||
TRI_ASSERT(physical != nullptr);
|
||||
|
|
|
@ -115,15 +115,26 @@ public:
|
|||
// -----------------------
|
||||
|
||||
void getDatabases(arangodb::velocypack::Builder& result) override;
|
||||
void getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes, TRI_voc_tick_t maxTick) override;
|
||||
int getCollectionsAndIndexes(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown, bool isUpgrade) override;
|
||||
|
||||
int getViews(TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Builder& result) override;
|
||||
void getCollectionInfo(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick
|
||||
) override;
|
||||
|
||||
int getCollectionsAndIndexes(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade
|
||||
) override;
|
||||
|
||||
int getViews(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result
|
||||
) override;
|
||||
|
||||
std::string versionFilename(TRI_voc_tick_t id) const override;
|
||||
std::string databasePath(TRI_vocbase_t const* vocbase) const override {
|
||||
|
@ -185,42 +196,67 @@ public:
|
|||
void recoveryDone(TRI_vocbase_t* vocbase) override;
|
||||
|
||||
public:
|
||||
std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const*) override;
|
||||
std::string createCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) override;
|
||||
|
||||
arangodb::Result persistCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const*) override;
|
||||
arangodb::Result dropCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection*) override;
|
||||
void destroyCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection*) override;
|
||||
void changeCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const*,
|
||||
bool doSync) override;
|
||||
arangodb::Result renameCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection const*,
|
||||
std::string const& oldName) override;
|
||||
void createIndex(TRI_vocbase_t* vocbase, TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data) override;
|
||||
void unloadCollection(TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection* collection) override;
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) override;
|
||||
|
||||
arangodb::Result dropCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) override;
|
||||
|
||||
void destroyCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) override;
|
||||
|
||||
void changeCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
bool doSync
|
||||
) override;
|
||||
|
||||
arangodb::Result renameCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName
|
||||
) override;
|
||||
|
||||
void createIndex(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data
|
||||
) override;
|
||||
|
||||
void unloadCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) override;
|
||||
|
||||
void changeView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view,
|
||||
bool doSync
|
||||
) override;
|
||||
|
||||
void createView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view
|
||||
) override;
|
||||
|
||||
virtual void getViewProperties(
|
||||
TRI_vocbase_t* /*vocbase*/,
|
||||
TRI_vocbase_t& /*vocbase*/,
|
||||
arangodb::LogicalView const* /*view*/,
|
||||
VPackBuilder& /*builder*/
|
||||
) override {
|
||||
|
@ -228,20 +264,28 @@ public:
|
|||
}
|
||||
|
||||
arangodb::Result persistView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view
|
||||
) override;
|
||||
|
||||
// asks the storage engine to persist renaming of a view
|
||||
// This will write a renameMarker if not in recovery
|
||||
arangodb::Result renameView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view,
|
||||
std::string const& oldName
|
||||
) override;
|
||||
|
||||
arangodb::Result dropView(TRI_vocbase_t* vocbase, arangodb::LogicalView*) override;
|
||||
void destroyView(TRI_vocbase_t* vocbase, arangodb::LogicalView*) noexcept override;
|
||||
arangodb::Result dropView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) override;
|
||||
|
||||
void destroyView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) noexcept override;
|
||||
|
||||
void signalCleanup(TRI_vocbase_t* vocbase) override;
|
||||
|
||||
int shutdownDatabase(TRI_vocbase_t* vocbase) override;
|
||||
|
|
|
@ -124,17 +124,28 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
virtual void getDatabases(arangodb::velocypack::Builder& result) = 0;
|
||||
|
||||
// fills the provided builder with information about the collection
|
||||
virtual void getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes, TRI_voc_tick_t maxTick) = 0;
|
||||
virtual void getCollectionInfo(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick
|
||||
) = 0;
|
||||
|
||||
// fill the Builder object with an array of collections (and their corresponding
|
||||
// indexes) that were detected by the storage engine. called at server start separately
|
||||
// for each database
|
||||
virtual int getCollectionsAndIndexes(TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown, bool isUpgrade) = 0;
|
||||
virtual int getCollectionsAndIndexes(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade
|
||||
) = 0;
|
||||
|
||||
virtual int getViews(TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result) = 0;
|
||||
virtual int getViews(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result
|
||||
) = 0;
|
||||
|
||||
// return the absolute path for the VERSION file of a database
|
||||
virtual std::string versionFilename(TRI_voc_tick_t id) const = 0;
|
||||
|
@ -231,14 +242,18 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// and throw only then, so that subsequent collection creation requests will not fail.
|
||||
// the WAL entry for the collection creation will be written *after* the call
|
||||
// to "createCollection" returns
|
||||
virtual std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const*) = 0;
|
||||
virtual std::string createCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) = 0;
|
||||
|
||||
// asks the storage engine to persist the collection.
|
||||
// After this call the collection is persisted over recovery.
|
||||
virtual arangodb::Result persistCollection(
|
||||
TRI_vocbase_t* vocbase,
|
||||
arangodb::LogicalCollection const* collection) = 0;
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) = 0;
|
||||
|
||||
// asks the storage engine to drop the specified collection and persist the
|
||||
// deletion info. Note that physical deletion of the collection data must not
|
||||
|
@ -248,12 +263,18 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// the actual deletion.
|
||||
// the WAL entry for collection deletion will be written *after* the call
|
||||
// to "dropCollection" returns
|
||||
virtual arangodb::Result dropCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) = 0;
|
||||
virtual arangodb::Result dropCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) = 0;
|
||||
|
||||
// perform a physical deletion of the collection
|
||||
// After this call data of this collection is corrupted, only perform if
|
||||
// assured that no one is using the collection anymore
|
||||
virtual void destroyCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) = 0;
|
||||
virtual void destroyCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) = 0;
|
||||
|
||||
// asks the storage engine to change properties of the collection as specified in
|
||||
// the VPack Slice object and persist them. If this operation fails
|
||||
|
@ -261,14 +282,19 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// property changes and throw only then, so that subsequent operations will not fail.
|
||||
// the WAL entry for the propery change will be written *after* the call
|
||||
// to "changeCollection" returns
|
||||
virtual void changeCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters,
|
||||
bool doSync) = 0;
|
||||
virtual void changeCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
bool doSync
|
||||
) = 0;
|
||||
|
||||
// asks the storage engine to persist renaming of a collection
|
||||
virtual arangodb::Result renameCollection(
|
||||
TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName) = 0;
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName
|
||||
) = 0;
|
||||
|
||||
// asks the storage engine to change properties of the view as specified in
|
||||
// the VPack Slice object and persist them. If this operation fails
|
||||
|
@ -277,7 +303,7 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// the WAL entry for the propery change will be written *after* the call
|
||||
// to "changeView" returns
|
||||
virtual void changeView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view,
|
||||
bool doSync
|
||||
|
@ -293,7 +319,7 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// the WAL entry for the view creation will be written *after* the call
|
||||
// to "createCview" returns
|
||||
virtual void createView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view
|
||||
) = 0;
|
||||
|
@ -301,7 +327,7 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// asks storage engine to put some view
|
||||
// specific properties into a specified builder
|
||||
virtual void getViewProperties(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const* view,
|
||||
VPackBuilder& builder
|
||||
) = 0;
|
||||
|
@ -309,13 +335,13 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// asks the storage engine to persist the view.
|
||||
// After this call the view is persisted over recovery.
|
||||
virtual arangodb::Result persistView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view
|
||||
) = 0;
|
||||
|
||||
// asks the storage engine to persist renaming of a view
|
||||
virtual arangodb::Result renameView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view,
|
||||
std::string const& oldName
|
||||
) = 0;
|
||||
|
@ -328,13 +354,19 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// the actual deletion.
|
||||
// the WAL entry for view deletion will be written *after* the call
|
||||
// to "dropView" returns
|
||||
virtual arangodb::Result dropView(TRI_vocbase_t* vocbase, arangodb::LogicalView*) = 0;
|
||||
virtual arangodb::Result dropView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) = 0;
|
||||
|
||||
// perform a physical deletion of the view
|
||||
// After this call data of this view is corrupted, only perform if
|
||||
// assured that no one is using the view anymore
|
||||
// 'noexcept' becuase it may be used in destructor
|
||||
virtual void destroyView(TRI_vocbase_t* vocbase, arangodb::LogicalView*) noexcept = 0;
|
||||
virtual void destroyView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) noexcept = 0;
|
||||
|
||||
// asks the storage engine to create an index as specified in the VPack
|
||||
// Slice object and persist the creation info. The database id, collection id
|
||||
|
@ -345,20 +377,27 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
// creation requests will not fail.
|
||||
// the WAL entry for the index creation will be written *after* the call
|
||||
// to "createIndex" returns
|
||||
virtual void createIndex(TRI_vocbase_t* vocbase, TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) = 0;
|
||||
virtual void createIndex(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data
|
||||
) = 0;
|
||||
|
||||
// Returns the StorageEngine-specific implementation
|
||||
// of the IndexFactory. This is used to validate
|
||||
// information about indexes.
|
||||
IndexFactory const* indexFactory() const {
|
||||
IndexFactory const& indexFactory() const {
|
||||
// The factory has to be created by the implementation
|
||||
// and shall never be deleted
|
||||
TRI_ASSERT(_indexFactory.get() != nullptr);
|
||||
return _indexFactory.get();
|
||||
return *_indexFactory;
|
||||
}
|
||||
|
||||
virtual void unloadCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) = 0;
|
||||
virtual void unloadCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) = 0;
|
||||
|
||||
virtual void signalCleanup(TRI_vocbase_t* vocbase) = 0;
|
||||
|
||||
|
@ -414,7 +453,7 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
builder.add("dfdb", velocypack::Value(supportsDfdb()));
|
||||
builder.add("indexes", velocypack::Value(VPackValueType::Array));
|
||||
|
||||
for (auto const& it : indexFactory()->supportedIndexes()) {
|
||||
for (auto& it: indexFactory().supportedIndexes()) {
|
||||
builder.add(velocypack::Value(it));
|
||||
}
|
||||
|
||||
|
@ -435,17 +474,17 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
|
||||
protected:
|
||||
void registerCollection(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
std::shared_ptr<arangodb::LogicalCollection> const& collection
|
||||
) {
|
||||
vocbase->registerCollection(true, collection);
|
||||
vocbase.registerCollection(true, collection);
|
||||
}
|
||||
|
||||
void registerView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
std::shared_ptr<arangodb::LogicalView> const& view
|
||||
TRI_vocbase_t& vocbase,
|
||||
std::shared_ptr<arangodb::LogicalView> const& view
|
||||
) {
|
||||
vocbase->registerView(true, view);
|
||||
vocbase.registerView(true, view);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -455,4 +494,4 @@ class StorageEngine : public application_features::ApplicationFeature {
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -707,7 +707,7 @@ Result LogicalCollection::rename(std::string&& newName, bool doSync) {
|
|||
TRI_ASSERT(engine != nullptr);
|
||||
|
||||
name(std::move(newName));
|
||||
engine->changeCollection(&vocbase(), id(), this, doSync);
|
||||
engine->changeCollection(vocbase(), id(), this, doSync);
|
||||
} catch (basics::Exception const& ex) {
|
||||
// Engine Rename somehow failed. Reset to old name
|
||||
name(std::move(oldName));
|
||||
|
@ -746,7 +746,7 @@ arangodb::Result LogicalCollection::drop() {
|
|||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
|
||||
engine->destroyCollection(&vocbase(), this);
|
||||
engine->destroyCollection(vocbase(), this);
|
||||
deleted(true);
|
||||
_physical->drop();
|
||||
|
||||
|
@ -1002,7 +1002,7 @@ arangodb::Result LogicalCollection::updateProperties(VPackSlice const& slice,
|
|||
}
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->changeCollection(&vocbase(), id(), this, doSync);
|
||||
engine->changeCollection(vocbase(), id(), this, doSync);
|
||||
|
||||
if (DatabaseFeature::DATABASE != nullptr &&
|
||||
DatabaseFeature::DATABASE->versionTracker() != nullptr) {
|
||||
|
@ -1095,7 +1095,7 @@ void LogicalCollection::persistPhysicalCollection() {
|
|||
// We have not yet persisted this collection!
|
||||
TRI_ASSERT(getPhysical()->path().empty());
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
auto path = engine->createCollection(&vocbase(), id(), this);
|
||||
auto path = engine->createCollection(vocbase(), id(), this);
|
||||
|
||||
getPhysical()->setPath(path);
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ DBServerLogicalView::~DBServerLogicalView() {
|
|||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
|
||||
engine->destroyView(&vocbase(), this);
|
||||
engine->destroyView(vocbase(), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ DBServerLogicalView::~DBServerLogicalView() {
|
|||
// during recovery entry is being played back from the engine
|
||||
if (!engine->inRecovery()) {
|
||||
arangodb::velocypack::Builder builder;
|
||||
auto res = engine->getViews(&(view.vocbase()), builder);
|
||||
auto res = engine->getViews(view.vocbase(), builder);
|
||||
TRI_ASSERT(TRI_ERROR_NO_ERROR == res);
|
||||
auto slice = builder.slice();
|
||||
TRI_ASSERT(slice.isArray());
|
||||
|
@ -227,9 +227,9 @@ DBServerLogicalView::~DBServerLogicalView() {
|
|||
}
|
||||
#endif
|
||||
|
||||
engine->createView(&(view.vocbase()), view.id(), view);
|
||||
engine->createView(view.vocbase(), view.id(), view);
|
||||
|
||||
return engine->persistView(&(view.vocbase()), view);
|
||||
return engine->persistView(view.vocbase(), view);
|
||||
} catch (std::exception const& e) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_INTERNAL,
|
||||
|
@ -251,7 +251,7 @@ arangodb::Result DBServerLogicalView::drop() {
|
|||
|
||||
if (res.ok()) {
|
||||
deleted(true);
|
||||
engine->dropView(&vocbase(), this);
|
||||
engine->dropView(vocbase(), this);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -269,7 +269,7 @@ Result DBServerLogicalView::rename(std::string&& newName, bool doSync) {
|
|||
|
||||
// store new view definition to disk
|
||||
if (!engine->inRecovery()) {
|
||||
engine->changeView(&vocbase(), id(), *this, doSync);
|
||||
engine->changeView(vocbase(), id(), *this, doSync);
|
||||
}
|
||||
} catch (basics::Exception const& ex) {
|
||||
name(std::move(oldName));
|
||||
|
@ -282,7 +282,7 @@ Result DBServerLogicalView::rename(std::string&& newName, bool doSync) {
|
|||
}
|
||||
|
||||
// write WAL 'rename' marker
|
||||
return engine->renameView(&vocbase(), *this, oldName);
|
||||
return engine->renameView(vocbase(), *this, oldName);
|
||||
}
|
||||
|
||||
void DBServerLogicalView::toVelocyPack(
|
||||
|
@ -310,7 +310,7 @@ void DBServerLogicalView::toVelocyPack(
|
|||
// storage engine related properties
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
engine->getViewProperties(&vocbase(), this, result);
|
||||
engine->getViewProperties(vocbase(), this, result);
|
||||
}
|
||||
|
||||
if (includeProperties) {
|
||||
|
@ -348,7 +348,7 @@ arangodb::Result DBServerLogicalView::updateProperties(
|
|||
}
|
||||
|
||||
try {
|
||||
engine->changeView(&vocbase(), id(), *this, doSync);
|
||||
engine->changeView(vocbase(), id(), *this, doSync);
|
||||
} catch (arangodb::basics::Exception const& e) {
|
||||
return { e.code() };
|
||||
} catch (...) {
|
||||
|
|
|
@ -339,8 +339,7 @@ Result Indexes::ensureIndex(LogicalCollection* collection,
|
|||
|
||||
VPackBuilder defBuilder;
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
IndexFactory const* idxFactory = engine->indexFactory();
|
||||
int res = idxFactory->enhanceIndexDefinition(
|
||||
int res = engine->indexFactory().enhanceIndexDefinition(
|
||||
definition, defBuilder, create, ServerState::instance()->isCoordinator()
|
||||
).errorNumber();
|
||||
|
||||
|
|
|
@ -760,7 +760,7 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
|
|||
if (!collection->deleted()) {
|
||||
collection->deleted(true);
|
||||
try {
|
||||
engine->changeCollection(this, collection->id(), collection, doSync);
|
||||
engine->changeCollection(*this, collection->id(), collection, doSync);
|
||||
} catch (arangodb::basics::Exception const& ex) {
|
||||
collection->deleted(false);
|
||||
events::DropCollection(colName, ex.code());
|
||||
|
@ -780,7 +780,7 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
|
|||
writeLocker.unlock();
|
||||
|
||||
TRI_ASSERT(engine != nullptr);
|
||||
engine->dropCollection(this, collection);
|
||||
engine->dropCollection(*this, collection);
|
||||
|
||||
DropCollectionCallback(collection);
|
||||
break;
|
||||
|
@ -798,7 +798,7 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
|
|||
->forceSyncProperties();
|
||||
|
||||
VPackBuilder builder;
|
||||
engine->getCollectionInfo(this, collection->id(), builder, false, 0);
|
||||
engine->getCollectionInfo(*this, collection->id(), builder, false, 0);
|
||||
arangodb::Result res = collection->updateProperties(
|
||||
builder.slice().get("parameters"), doSync);
|
||||
|
||||
|
@ -812,7 +812,7 @@ int TRI_vocbase_t::dropCollectionWorker(arangodb::LogicalCollection* collection,
|
|||
locker.unlock();
|
||||
writeLocker.unlock();
|
||||
|
||||
engine->dropCollection(this, collection);
|
||||
engine->dropCollection(*this, collection);
|
||||
state = DROP_PERFORM;
|
||||
break;
|
||||
}
|
||||
|
@ -1179,7 +1179,7 @@ arangodb::LogicalCollection* TRI_vocbase_t::createCollection(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
arangodb::Result res2 = engine->persistCollection(this, collection.get());
|
||||
auto res2 = engine->persistCollection(*this, collection.get());
|
||||
// API compatibility, we always return the collection, even if creation
|
||||
// failed.
|
||||
|
||||
|
@ -1254,7 +1254,7 @@ int TRI_vocbase_t::unloadCollection(arangodb::LogicalCollection* collection,
|
|||
|
||||
// wake up the cleanup thread
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->unloadCollection(this, collection);
|
||||
engine->unloadCollection(*this, collection);
|
||||
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
@ -1485,7 +1485,7 @@ int TRI_vocbase_t::renameCollection(
|
|||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine != nullptr);
|
||||
arangodb::Result res2 =
|
||||
engine->renameCollection(this, collection, oldName);
|
||||
engine->renameCollection(*this, collection, oldName);
|
||||
|
||||
return res2.errorNumber();
|
||||
}
|
||||
|
|
|
@ -1913,7 +1913,7 @@ SECTION("test_tracked_cids") {
|
|||
REQUIRE((nullptr != logicalCollection));
|
||||
auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
StorageEngineMock().registerView(&vocbase, logicalView); // ensure link can find view
|
||||
StorageEngineMock().registerView(vocbase, logicalView); // ensure link can find view
|
||||
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
|
||||
REQUIRE((nullptr != viewImpl));
|
||||
|
||||
|
@ -1941,7 +1941,7 @@ SECTION("test_tracked_cids") {
|
|||
REQUIRE((nullptr != logicalCollection));
|
||||
auto logicalView = arangodb::iresearch::IResearchView::make(vocbase, viewJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
StorageEngineMock().registerView(&vocbase, logicalView); // ensure link can find view
|
||||
StorageEngineMock().registerView(vocbase, logicalView); // ensure link can find view
|
||||
auto* viewImpl = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
|
||||
REQUIRE((nullptr != viewImpl));
|
||||
|
||||
|
|
|
@ -972,25 +972,29 @@ void StorageEngineMock::addV8Functions() {
|
|||
TRI_ASSERT(false);
|
||||
}
|
||||
|
||||
void StorageEngineMock::changeCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id, arangodb::LogicalCollection const* parameters, bool doSync) {
|
||||
void StorageEngineMock::changeCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* parameters,
|
||||
bool doSync
|
||||
) {
|
||||
// NOOP, assume physical collection changed OK
|
||||
}
|
||||
|
||||
void StorageEngineMock::changeView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view,
|
||||
bool doSync
|
||||
) {
|
||||
before();
|
||||
TRI_ASSERT(vocbase);
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase->id(), view.id())) != views.end());
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase.id(), view.id())) != views.end());
|
||||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view.toVelocyPack(builder, true, true);
|
||||
builder.close();
|
||||
views[std::make_pair(vocbase->id(), view.id())] = std::move(builder);
|
||||
views[std::make_pair(vocbase.id(), view.id())] = std::move(builder);
|
||||
}
|
||||
|
||||
std::string StorageEngineMock::collectionPath(TRI_vocbase_t const* vocbase, TRI_voc_cid_t id) const {
|
||||
|
@ -998,7 +1002,11 @@ std::string StorageEngineMock::collectionPath(TRI_vocbase_t const* vocbase, TRI_
|
|||
return "<invalid>";
|
||||
}
|
||||
|
||||
std::string StorageEngineMock::createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id, arangodb::LogicalCollection const*) {
|
||||
std::string StorageEngineMock::createCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) {
|
||||
return "<invalid>"; // physical path of the new collection
|
||||
}
|
||||
|
||||
|
@ -1007,7 +1015,12 @@ TRI_vocbase_t* StorageEngineMock::createDatabase(TRI_voc_tick_t id, arangodb::ve
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void StorageEngineMock::createIndex(TRI_vocbase_t* vocbase, TRI_voc_cid_t collectionId, TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) {
|
||||
void StorageEngineMock::createIndex(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t collectionId,
|
||||
TRI_idx_iid_t id,
|
||||
arangodb::velocypack::Slice const& data
|
||||
) {
|
||||
TRI_ASSERT(false);
|
||||
}
|
||||
|
||||
|
@ -1045,7 +1058,7 @@ arangodb::TransactionState* StorageEngineMock::createTransactionState(TRI_vocbas
|
|||
}
|
||||
|
||||
void StorageEngineMock::createView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t id,
|
||||
arangodb::LogicalView const& view
|
||||
) {
|
||||
|
@ -1053,7 +1066,11 @@ void StorageEngineMock::createView(
|
|||
// NOOP, assume physical view created OK
|
||||
}
|
||||
|
||||
void StorageEngineMock::getViewProperties(TRI_vocbase_t* vocbase, arangodb::LogicalView const* view, VPackBuilder& builder) {
|
||||
void StorageEngineMock::getViewProperties(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const* view,
|
||||
VPackBuilder& builder
|
||||
) {
|
||||
before();
|
||||
// NOOP
|
||||
}
|
||||
|
@ -1068,16 +1085,25 @@ std::string StorageEngineMock::databasePath(TRI_vocbase_t const* vocbase) const
|
|||
return ""; // no valid path filesystem persisted, return empty string
|
||||
}
|
||||
|
||||
void StorageEngineMock::destroyCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) {
|
||||
void StorageEngineMock::destroyCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
// NOOP, assume physical collection destroyed OK
|
||||
}
|
||||
|
||||
void StorageEngineMock::destroyView(TRI_vocbase_t* vocbase, arangodb::LogicalView* view) noexcept {
|
||||
void StorageEngineMock::destroyView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) noexcept {
|
||||
before();
|
||||
// NOOP, assume physical view destroyed OK
|
||||
}
|
||||
|
||||
arangodb::Result StorageEngineMock::dropCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) {
|
||||
arangodb::Result StorageEngineMock::dropCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
return arangodb::Result(TRI_ERROR_NO_ERROR); // assume physical collection dropped OK
|
||||
}
|
||||
|
||||
|
@ -1086,12 +1112,14 @@ arangodb::Result StorageEngineMock::dropDatabase(TRI_vocbase_t*) {
|
|||
return arangodb::Result();
|
||||
}
|
||||
|
||||
arangodb::Result StorageEngineMock::dropView(TRI_vocbase_t* vocbase, arangodb::LogicalView* view) {
|
||||
arangodb::Result StorageEngineMock::dropView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView* view
|
||||
) {
|
||||
before();
|
||||
TRI_ASSERT(vocbase);
|
||||
TRI_ASSERT(view);
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase->id(), view->id())) != views.end());
|
||||
views.erase(std::make_pair(vocbase->id(), view->id()));
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase.id(), view->id())) != views.end());
|
||||
views.erase(std::make_pair(vocbase.id(), view->id()));
|
||||
|
||||
return arangodb::Result(TRI_ERROR_NO_ERROR); // assume mock view dropped OK
|
||||
}
|
||||
|
@ -1101,7 +1129,13 @@ arangodb::Result StorageEngineMock::firstTick(uint64_t&) {
|
|||
return arangodb::Result(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
void StorageEngineMock::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid, arangodb::velocypack::Builder& result, bool includeIndexes, TRI_voc_tick_t maxTick) {
|
||||
void StorageEngineMock::getCollectionInfo(
|
||||
TRI_vocbase_t& vocbase,
|
||||
TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeIndexes,
|
||||
TRI_voc_tick_t maxTick
|
||||
) {
|
||||
arangodb::velocypack::Builder parameters;
|
||||
|
||||
parameters.openObject();
|
||||
|
@ -1114,7 +1148,12 @@ void StorageEngineMock::getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t
|
|||
// nothing more required, assume info used for PhysicalCollectionMock
|
||||
}
|
||||
|
||||
int StorageEngineMock::getCollectionsAndIndexes(TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result, bool wasCleanShutdown, bool isUpgrade) {
|
||||
int StorageEngineMock::getCollectionsAndIndexes(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade
|
||||
) {
|
||||
TRI_ASSERT(false);
|
||||
return TRI_ERROR_INTERNAL;
|
||||
}
|
||||
|
@ -1147,7 +1186,10 @@ arangodb::velocypack::Builder StorageEngineMock::getReplicationApplierConfigurat
|
|||
return arangodb::velocypack::Builder();
|
||||
}
|
||||
|
||||
int StorageEngineMock::getViews(TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result) {
|
||||
int StorageEngineMock::getViews(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Builder& result
|
||||
) {
|
||||
result.openArray();
|
||||
|
||||
for (auto& entry: views) {
|
||||
|
@ -1193,24 +1235,26 @@ TRI_vocbase_t* StorageEngineMock::openDatabase(arangodb::velocypack::Slice const
|
|||
return vocbases.back().get();
|
||||
}
|
||||
|
||||
arangodb::Result StorageEngineMock::persistCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection) {
|
||||
arangodb::Result StorageEngineMock::persistCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection
|
||||
) {
|
||||
before();
|
||||
return arangodb::Result(TRI_ERROR_NO_ERROR); // assume mock collection persisted OK
|
||||
}
|
||||
|
||||
arangodb::Result StorageEngineMock::persistView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view
|
||||
) {
|
||||
before();
|
||||
TRI_ASSERT(vocbase);
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase->id(), view.id())) == views.end()); // called after createView()
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase.id(), view.id())) == views.end()); // called after createView()
|
||||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view.toVelocyPack(builder, true, true);
|
||||
builder.close();
|
||||
views[std::make_pair(vocbase->id(), view.id())] = std::move(builder);
|
||||
views[std::make_pair(vocbase.id(), view.id())] = std::move(builder);
|
||||
|
||||
return arangodb::Result(TRI_ERROR_NO_ERROR); // assume mock view persisted OK
|
||||
}
|
||||
|
@ -1239,25 +1283,28 @@ int StorageEngineMock::removeReplicationApplierConfiguration() {
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
arangodb::Result StorageEngineMock::renameCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection, std::string const& oldName) {
|
||||
arangodb::Result StorageEngineMock::renameCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection const* collection,
|
||||
std::string const& oldName
|
||||
) {
|
||||
TRI_ASSERT(false);
|
||||
return arangodb::Result(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
arangodb::Result StorageEngineMock::renameView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalView const& view,
|
||||
std::string const& newName
|
||||
) {
|
||||
before();
|
||||
TRI_ASSERT(vocbase);
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase->id(), view.id())) != views.end());
|
||||
TRI_ASSERT(views.find(std::make_pair(vocbase.id(), view.id())) != views.end());
|
||||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view.toVelocyPack(builder, true, true);
|
||||
builder.close();
|
||||
views[std::make_pair(vocbase->id(), view.id())] = std::move(builder);
|
||||
views[std::make_pair(vocbase.id(), view.id())] = std::move(builder);
|
||||
|
||||
return arangodb::Result(TRI_ERROR_NO_ERROR); // assume mock view renames OK
|
||||
}
|
||||
|
@ -1287,7 +1334,10 @@ bool StorageEngineMock::supportsDfdb() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
void StorageEngineMock::unloadCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) {
|
||||
void StorageEngineMock::unloadCollection(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::LogicalCollection* collection
|
||||
) {
|
||||
before();
|
||||
// NOOP assume collection unloaded OK
|
||||
}
|
||||
|
|
|
@ -144,12 +144,12 @@ class StorageEngineMock: public arangodb::StorageEngine {
|
|||
virtual void addOptimizerRules() override;
|
||||
virtual void addRestHandlers(arangodb::rest::RestHandlerFactory*) override;
|
||||
virtual void addV8Functions() override;
|
||||
virtual void changeCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id, arangodb::LogicalCollection const* parameters, bool doSync) override;
|
||||
virtual void changeView(TRI_vocbase_t* vocbase, TRI_voc_cid_t id, arangodb::LogicalView const&, bool doSync) override;
|
||||
virtual void changeCollection(TRI_vocbase_t& vocbase, TRI_voc_cid_t id, arangodb::LogicalCollection const* parameters, bool doSync) override;
|
||||
virtual void changeView(TRI_vocbase_t& vocbase, TRI_voc_cid_t id, arangodb::LogicalView const& view, bool doSync) override;
|
||||
virtual std::string collectionPath(TRI_vocbase_t const* vocbase, TRI_voc_cid_t id) const override;
|
||||
virtual std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id, arangodb::LogicalCollection const*) override;
|
||||
virtual std::string createCollection(TRI_vocbase_t& vocbase, TRI_voc_cid_t id, arangodb::LogicalCollection const* collection) override;
|
||||
virtual TRI_vocbase_t* createDatabase(TRI_voc_tick_t id, arangodb::velocypack::Slice const& args, int& status) override;
|
||||
virtual void createIndex(TRI_vocbase_t* vocbase, TRI_voc_cid_t collectionId, TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) override;
|
||||
virtual void createIndex(TRI_vocbase_t& vocbase, TRI_voc_cid_t collectionId, TRI_idx_iid_t id, arangodb::velocypack::Slice const& data) override;
|
||||
virtual arangodb::Result createLoggerState(TRI_vocbase_t*, VPackBuilder&) override;
|
||||
virtual arangodb::PhysicalCollection* createPhysicalCollection(arangodb::LogicalCollection* collection, VPackSlice const& info) override;
|
||||
virtual arangodb::Result createTickRanges(VPackBuilder&) override;
|
||||
|
@ -157,30 +157,30 @@ class StorageEngineMock: public arangodb::StorageEngine {
|
|||
virtual arangodb::transaction::ContextData* createTransactionContextData() override;
|
||||
virtual arangodb::TransactionManager* createTransactionManager() override;
|
||||
virtual arangodb::TransactionState* createTransactionState(TRI_vocbase_t* vocbase, arangodb::transaction::Options const& options) override;
|
||||
virtual void createView(TRI_vocbase_t* vocbase, TRI_voc_cid_t id, arangodb::LogicalView const& view) override;
|
||||
virtual void getViewProperties(TRI_vocbase_t* vocbase, arangodb::LogicalView const* view, VPackBuilder& builder) override;
|
||||
virtual void createView(TRI_vocbase_t& vocbase, TRI_voc_cid_t id, arangodb::LogicalView const& view) override;
|
||||
virtual void getViewProperties(TRI_vocbase_t& vocbase, arangodb::LogicalView const* view, VPackBuilder& builder) override;
|
||||
virtual TRI_voc_tick_t currentTick() const override;
|
||||
virtual std::string databasePath(TRI_vocbase_t const* vocbase) const override;
|
||||
virtual void destroyCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) override;
|
||||
virtual void destroyView(TRI_vocbase_t* vocbase, arangodb::LogicalView* view) noexcept override;
|
||||
virtual arangodb::Result dropCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) override;
|
||||
virtual void destroyCollection(TRI_vocbase_t& vocbase, arangodb::LogicalCollection* collection) override;
|
||||
virtual void destroyView(TRI_vocbase_t& vocbase, arangodb::LogicalView* view) noexcept override;
|
||||
virtual arangodb::Result dropCollection(TRI_vocbase_t& vocbase, arangodb::LogicalCollection* collection) override;
|
||||
virtual arangodb::Result dropDatabase(TRI_vocbase_t*) override;
|
||||
virtual arangodb::Result dropView(TRI_vocbase_t*, arangodb::LogicalView*) override;
|
||||
virtual arangodb::Result dropView(TRI_vocbase_t& vocbase, arangodb::LogicalView* view) override;
|
||||
virtual arangodb::Result firstTick(uint64_t&) override;
|
||||
virtual arangodb::Result flushWal(bool waitForSync, bool waitForCollector, bool writeShutdownFile) override;
|
||||
virtual void getCollectionInfo(TRI_vocbase_t* vocbase, TRI_voc_cid_t cid, arangodb::velocypack::Builder& result, bool includeIndexes, TRI_voc_tick_t maxTick) override;
|
||||
virtual int getCollectionsAndIndexes(TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result, bool wasCleanShutdown, bool isUpgrade) override;
|
||||
virtual void getCollectionInfo(TRI_vocbase_t& vocbase, TRI_voc_cid_t cid, arangodb::velocypack::Builder& result, bool includeIndexes, TRI_voc_tick_t maxTick) override;
|
||||
virtual int getCollectionsAndIndexes(TRI_vocbase_t& vocbase, arangodb::velocypack::Builder& result, bool wasCleanShutdown, bool isUpgrade) override;
|
||||
virtual void getDatabases(arangodb::velocypack::Builder& result) override;
|
||||
virtual arangodb::velocypack::Builder getReplicationApplierConfiguration(TRI_vocbase_t* vocbase, int& result) override;
|
||||
virtual arangodb::velocypack::Builder getReplicationApplierConfiguration(int& result) override;
|
||||
virtual int getViews(TRI_vocbase_t* vocbase, arangodb::velocypack::Builder& result) override;
|
||||
virtual int getViews(TRI_vocbase_t& vocbase, arangodb::velocypack::Builder& result) override;
|
||||
virtual arangodb::Result handleSyncKeys(arangodb::DatabaseInitialSyncer&, arangodb::LogicalCollection*, std::string const& keysId) override;
|
||||
virtual bool inRecovery() override;
|
||||
virtual arangodb::Result lastLogger(TRI_vocbase_t*, std::shared_ptr<arangodb::transaction::Context>, uint64_t, uint64_t, std::shared_ptr<VPackBuilder>&) override;
|
||||
virtual double minimumSyncReplicationTimeout() const override { return 1.0; }
|
||||
virtual TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& args, bool isUpgrade, int& status) override;
|
||||
virtual arangodb::Result persistCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection) override;
|
||||
virtual arangodb::Result persistView(TRI_vocbase_t* vocbase, arangodb::LogicalView const& view) override;
|
||||
virtual arangodb::Result persistCollection(TRI_vocbase_t& vocbase, arangodb::LogicalCollection const* collection) override;
|
||||
virtual arangodb::Result persistView(TRI_vocbase_t& vocbase, arangodb::LogicalView const& view) override;
|
||||
virtual void prepareDropDatabase(TRI_vocbase_t* vocbase, bool useWriteMarker, int& status) override;
|
||||
using StorageEngine::registerCollection;
|
||||
using StorageEngine::registerView;
|
||||
|
@ -188,14 +188,14 @@ class StorageEngineMock: public arangodb::StorageEngine {
|
|||
virtual void releaseTick(TRI_voc_tick_t) override;
|
||||
virtual int removeReplicationApplierConfiguration(TRI_vocbase_t*) override;
|
||||
virtual int removeReplicationApplierConfiguration() override;
|
||||
virtual arangodb::Result renameCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection const* collection, std::string const& oldName) override;
|
||||
virtual arangodb::Result renameView(TRI_vocbase_t* vocbase, arangodb::LogicalView const& view, std::string const& oldName) override;
|
||||
virtual arangodb::Result renameCollection(TRI_vocbase_t& vocbase, arangodb::LogicalCollection const* collection, std::string const& oldName) override;
|
||||
virtual arangodb::Result renameView(TRI_vocbase_t& vocbase, arangodb::LogicalView const& view, std::string const& oldName) override;
|
||||
virtual int saveReplicationApplierConfiguration(TRI_vocbase_t*, arangodb::velocypack::Slice, bool) override;
|
||||
virtual int saveReplicationApplierConfiguration(arangodb::velocypack::Slice, bool) override;
|
||||
virtual int shutdownDatabase(TRI_vocbase_t* vocbase) override;
|
||||
virtual void signalCleanup(TRI_vocbase_t* vocbase) override;
|
||||
virtual bool supportsDfdb() const override;
|
||||
virtual void unloadCollection(TRI_vocbase_t* vocbase, arangodb::LogicalCollection* collection) override;
|
||||
virtual void unloadCollection(TRI_vocbase_t& vocbase, arangodb::LogicalCollection* collection) override;
|
||||
virtual bool useRawDocumentPointers() override { return false; }
|
||||
virtual std::string versionFilename(TRI_voc_tick_t) const override;
|
||||
virtual void waitForEstimatorSync(std::chrono::milliseconds maxWaitTime) override;
|
||||
|
|
Loading…
Reference in New Issue