diff --git a/arangod/MMFiles/MMFilesEngine.cpp b/arangod/MMFiles/MMFilesEngine.cpp index 426345307d..0499a98ac3 100644 --- a/arangod/MMFiles/MMFilesEngine.cpp +++ b/arangod/MMFiles/MMFilesEngine.cpp @@ -152,7 +152,7 @@ MMFilesEngine::MMFilesEngine(application_features::ApplicationServer* server) MMFilesEngine::~MMFilesEngine() {} // perform a physical deletion of the database -void MMFilesEngine::dropDatabase(Database* database, int& status) { +Result MMFilesEngine::dropDatabase(Database* database) { // delete persistent indexes for this database MMFilesPersistentIndexFeature::dropDatabase(database->id()); @@ -180,7 +180,7 @@ void MMFilesEngine::dropDatabase(Database* database, int& status) { _collectionPaths.erase(database->id()); } - status = dropDatabaseDirectory(databaseDirectory(database->id())); + return dropDatabaseDirectory(databaseDirectory(database->id())); } // add the storage engine's specifc options to the global list of options diff --git a/arangod/MMFiles/MMFilesEngine.h b/arangod/MMFiles/MMFilesEngine.h index 1921cac73d..3f75938d16 100644 --- a/arangod/MMFiles/MMFilesEngine.h +++ b/arangod/MMFiles/MMFilesEngine.h @@ -143,7 +143,7 @@ class MMFilesEngine final : public StorageEngine { int writeCreateDatabaseMarker(TRI_voc_tick_t id, VPackSlice const& slice) override; void prepareDropDatabase(TRI_vocbase_t* vocbase, bool useWriteMarker, int& status) override; - void dropDatabase(Database* database, int& status) override; + Result dropDatabase(Database* database) override; void waitUntilDeletion(TRI_voc_tick_t id, bool force, int& status) override; // wal in recovery diff --git a/arangod/RocksDBEngine/RocksDBCommon.cpp b/arangod/RocksDBEngine/RocksDBCommon.cpp index 27c436610c..1b10552475 100644 --- a/arangod/RocksDBEngine/RocksDBCommon.cpp +++ b/arangod/RocksDBEngine/RocksDBCommon.cpp @@ -225,5 +225,34 @@ Result removeLargeRange(rocksdb::TransactionDB* db, RocksDBKeyBounds const& boun return TRI_ERROR_INTERNAL; } } + +std::vector collectionValues(TRI_voc_tick_t databaseId){ + std::vector rv; + RocksDBKeyBounds bounds = RocksDBKeyBounds::DatabaseCollections(databaseId); + rocksdb::Iterator* it = globalRocksDB()->NewIterator(rocksdb::ReadOptions()); + for (it->Seek(bounds.start()); it->Valid() && it->key() != bounds.end(); it->Next()) { + rv.emplace_back(RocksDBValue(RocksDBEntryType::Collection, it->value())); + } + return rv; +} +std::vector indexValues(TRI_voc_tick_t databaseId){ + std::vector rv; + RocksDBKeyBounds bounds = RocksDBKeyBounds::DatabaseIndexes(databaseId); + rocksdb::Iterator* it = globalRocksDB()->NewIterator(rocksdb::ReadOptions()); + for (it->Seek(bounds.start()); it->Valid() && it->key() != bounds.end(); it->Next()) { + rv.emplace_back(RocksDBValue(RocksDBEntryType::Index, it->value())); + } + return rv; +} +std::vector viewValues(TRI_voc_tick_t databaseId){ + std::vector rv; + RocksDBKeyBounds bounds = RocksDBKeyBounds::DatabaseViews(databaseId); + rocksdb::Iterator* it = globalRocksDB()->NewIterator(rocksdb::ReadOptions()); + for (it->Seek(bounds.start()); it->Valid() && it->key() != bounds.end(); it->Next()) { + rv.emplace_back(RocksDBValue(RocksDBEntryType::View, it->value())); + } + return rv; +} + } // namespace rocksutils } // namespace arangodb diff --git a/arangod/RocksDBEngine/RocksDBCommon.h b/arangod/RocksDBEngine/RocksDBCommon.h index 3423d8df1f..57e328e520 100644 --- a/arangod/RocksDBEngine/RocksDBCommon.h +++ b/arangod/RocksDBEngine/RocksDBCommon.h @@ -28,6 +28,7 @@ #include "Basics/Common.h" #include "Basics/Result.h" +#include "RocksDBEngine/RocksDBValue.h" #include #include @@ -75,6 +76,10 @@ std::size_t countKeyRange(rocksdb::DB*, rocksdb::ReadOptions const&, /// Should mainly be used to implement the drop() call Result removeLargeRange(rocksdb::TransactionDB* db, RocksDBKeyBounds const& bounds); +std::vector collectionValues(TRI_voc_tick_t databaseId); +std::vector indexValues(TRI_voc_tick_t databaseId); +std::vector viewValues(TRI_voc_tick_t databaseId); + } // namespace rocksutils } // namespace arangodb diff --git a/arangod/RocksDBEngine/RocksDBEngine.cpp b/arangod/RocksDBEngine/RocksDBEngine.cpp index 06e5881265..00b4e6f964 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.cpp +++ b/arangod/RocksDBEngine/RocksDBEngine.cpp @@ -424,9 +424,8 @@ void RocksDBEngine::prepareDropDatabase(TRI_vocbase_t* vocbase, THROW_ARANGO_NOT_YET_IMPLEMENTED(); } -void RocksDBEngine::dropDatabase(Database* database, int& status) { - // nothing to do here - status = TRI_ERROR_NO_ERROR; +Result RocksDBEngine::dropDatabase(Database* database) { + return dropDatabase(database->id()); } void RocksDBEngine::waitUntilDeletion(TRI_voc_tick_t /* id */, bool /* force */, @@ -712,16 +711,23 @@ void RocksDBEngine::addRestHandlers(rest::RestHandlerFactory*) { } Result RocksDBEngine::dropDatabase(TRI_voc_tick_t id) { + Result res; + rocksdb::WriteOptions options; // TODO: check which options would make sense + + auto collections = collectionValues(id); + auto indexes = indexValues(id); + auto views = viewValues(id); + + // TODO: remove collections of database // TODO: remove indexes of database // TODO: remove views of database // TODO: remove documents and index entries of database - rocksdb::WriteOptions options; // TODO: check which options would make sense auto key = RocksDBKey::Database(id); - - rocksdb::Status res = _db->Delete(options, key.string()); - return rocksutils::convertStatus(res); + rocksdb::Status status = _db->Delete(options, key.string()); + res = rocksutils::convertStatus(status); + return res; } bool RocksDBEngine::systemDatabaseExists() { diff --git a/arangod/RocksDBEngine/RocksDBEngine.h b/arangod/RocksDBEngine/RocksDBEngine.h index f63a5c0d48..d03511cdb9 100644 --- a/arangod/RocksDBEngine/RocksDBEngine.h +++ b/arangod/RocksDBEngine/RocksDBEngine.h @@ -127,7 +127,7 @@ class RocksDBEngine final : public StorageEngine { VPackSlice const& slice) override; void prepareDropDatabase(TRI_vocbase_t* vocbase, bool useWriteMarker, int& status) override; - void dropDatabase(Database* database, int& status) override; + Result dropDatabase(Database* database) override; void waitUntilDeletion(TRI_voc_tick_t id, bool force, int& status) override; // wal in recovery diff --git a/arangod/RocksDBEngine/RocksDBIndex.cpp b/arangod/RocksDBEngine/RocksDBIndex.cpp index 64213766db..8d0a29d266 100644 --- a/arangod/RocksDBEngine/RocksDBIndex.cpp +++ b/arangod/RocksDBEngine/RocksDBIndex.cpp @@ -56,6 +56,7 @@ RocksDBIndex::RocksDBIndex(TRI_idx_iid_t id, LogicalCollection* collection, RocksDBIndex::~RocksDBIndex() { if (_useCache && _cache != nullptr) { try { + TRI_ASSERT(_cacheManager != nullptr); _cacheManager->destroyCache(_cache); } catch (...) { } diff --git a/arangod/RocksDBEngine/RocksDBKeyBounds.cpp b/arangod/RocksDBEngine/RocksDBKeyBounds.cpp index 6ba9596bdd..33c08967cd 100644 --- a/arangod/RocksDBEngine/RocksDBKeyBounds.cpp +++ b/arangod/RocksDBEngine/RocksDBKeyBounds.cpp @@ -42,6 +42,10 @@ RocksDBKeyBounds RocksDBKeyBounds::DatabaseCollections( return RocksDBKeyBounds(RocksDBEntryType::Collection, databaseId); } +RocksDBKeyBounds RocksDBKeyBounds::DatabaseIndexes(TRI_voc_tick_t databaseId){ + return RocksDBKeyBounds(RocksDBEntryType::Index, databaseId); +} + RocksDBKeyBounds RocksDBKeyBounds::CollectionIndexes( TRI_voc_tick_t databaseId, TRI_voc_cid_t collectionId) { return RocksDBKeyBounds(RocksDBEntryType::Index, databaseId, collectionId); diff --git a/arangod/RocksDBEngine/RocksDBKeyBounds.h b/arangod/RocksDBEngine/RocksDBKeyBounds.h index 5447cbb872..3c95e1a7a6 100644 --- a/arangod/RocksDBEngine/RocksDBKeyBounds.h +++ b/arangod/RocksDBEngine/RocksDBKeyBounds.h @@ -50,6 +50,11 @@ class RocksDBKeyBounds { ////////////////////////////////////////////////////////////////////////////// static RocksDBKeyBounds DatabaseCollections(TRI_voc_tick_t databaseId); + ////////////////////////////////////////////////////////////////////////////// + /// @brief Bounds for all collections belonging to a specified database + ////////////////////////////////////////////////////////////////////////////// + static RocksDBKeyBounds DatabaseIndexes(TRI_voc_tick_t databaseId); + ////////////////////////////////////////////////////////////////////////////// /// @brief Bounds for all indexes belonging to a specified collection ////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/RocksDBEngine/RocksDBValue.h b/arangod/RocksDBEngine/RocksDBValue.h index b9d7d6ec6c..96211d146b 100644 --- a/arangod/RocksDBEngine/RocksDBValue.h +++ b/arangod/RocksDBEngine/RocksDBValue.h @@ -97,6 +97,8 @@ class RocksDBValue { std::string const& string() { return _buffer; } // to be used with put std::string* buffer() { return &_buffer; } // to be used with get + RocksDBValue(RocksDBEntryType type, rocksdb::Slice slice) + : _type(type), _buffer(slice.data(),slice.size()) {} private: RocksDBValue(); explicit RocksDBValue(RocksDBEntryType type); diff --git a/arangod/StorageEngine/StorageEngine.h b/arangod/StorageEngine/StorageEngine.h index 309a4f7392..9cdcab5d03 100644 --- a/arangod/StorageEngine/StorageEngine.h +++ b/arangod/StorageEngine/StorageEngine.h @@ -198,12 +198,7 @@ class StorageEngine : public application_features::ApplicationFeature { }; // perform a physical deletion of the database - virtual void dropDatabase(Database*, int& status) = 0; - void dropDatabase(Database* db){ - int status; - dropDatabase(db, status); - TRI_ASSERT(status == TRI_ERROR_NO_ERROR); - }; + virtual Result dropDatabase(Database*) = 0; /// @brief wait until a database directory disappears - not under lock in databaseFreature virtual void waitUntilDeletion(TRI_voc_tick_t id, bool force, int& status) = 0;