1
0
Fork 0

moved path-related functionality into engine

This commit is contained in:
jsteemann 2016-08-05 14:09:58 +02:00
parent 6e47a19d37
commit 6b9a4a2e7f
8 changed files with 218 additions and 176 deletions

View File

@ -27,6 +27,7 @@
#include "Basics/VelocyPackHelper.h"
#include "Basics/WriteLocker.h"
#include "Basics/files.h"
#include "Random/RandomGenerator.h"
#include "RestServer/DatabaseFeature.h"
#include "RestServer/DatabasePathFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
@ -124,9 +125,9 @@ void MMFilesEngine::prepare() {
TRI_ASSERT(EngineSelectorFeature::ENGINE = this);
// get base path from DatabaseServerFeature
auto database = application_features::ApplicationServer::getFeature<DatabasePathFeature>("DatabasePath");
_basePath = database->directory();
_databasePath += database->subdirectoryName("databases") + TRI_DIR_SEPARATOR_CHAR;
auto databasePathFeature = application_features::ApplicationServer::getFeature<DatabasePathFeature>("DatabasePath");
_basePath = databasePathFeature->directory();
_databasePath += databasePathFeature->subdirectoryName("databases") + TRI_DIR_SEPARATOR_CHAR;
TRI_ASSERT(!_basePath.empty());
TRI_ASSERT(!_databasePath.empty());
@ -255,7 +256,7 @@ void MMFilesEngine::getDatabases(arangodb::velocypack::Builder& result) {
// a valid database directory
// now read data from parameter.json file
std::string const file = parametersFile(id);
std::string const file = databaseParametersFilename(id);
if (!TRI_ExistsFile(file.c_str())) {
// no parameter.json file
@ -474,6 +475,8 @@ int MMFilesEngine::prepareDropDatabase(TRI_vocbase_t* vocbase) {
// perform a physical deletion of the database
int MMFilesEngine::dropDatabase(TRI_vocbase_t* vocbase) {
_collectionPaths.erase(vocbase->id());
return dropDatabaseDirectory(databaseDirectory(vocbase->id()));
}
@ -516,8 +519,103 @@ int MMFilesEngine::waitUntilDeletion(TRI_voc_tick_t id, bool force) {
// 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
void MMFilesEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
std::string MMFilesEngine::createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::VocbaseCollectionInfo const& parameters) {
std::string const path = databasePath(vocbase);
// sanity check
if (sizeof(TRI_df_header_marker_t) + sizeof(TRI_df_footer_marker_t) > parameters.maximalSize()) {
LOG(ERR) << "cannot create datafile '" << parameters.name() << "' in '"
<< path << "', maximal size '"
<< parameters.maximalSize() << "' is too small";
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATAFILE_FULL);
}
if (!TRI_IsDirectory(path.c_str())) {
LOG(ERR) << "cannot create collection '" << path << "', path is not a directory";
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATADIR_INVALID);
}
std::string const dirname = createCollectionDirectoryName(path, id);
registerCollectionPath(vocbase->id(), id, dirname);
// directory must not exist
if (TRI_ExistsFile(dirname.c_str())) {
LOG(ERR) << "cannot create collection '" << parameters.name()
<< "' in directory '" << dirname << "': directory already exists";
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_DIRECTORY_ALREADY_EXISTS);
}
// use a temporary directory first. this saves us from leaving an empty
// directory behind, and the server refusing to start
std::string const tmpname = dirname + ".tmp";
// create directory
std::string errorMessage;
long systemError;
int res = TRI_CreateDirectory(tmpname.c_str(), systemError, errorMessage);
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create collection '" << parameters.name()
<< "' in directory '" << path << "': " << TRI_errno_string(res)
<< " - " << systemError << " - " << errorMessage;
THROW_ARANGO_EXCEPTION(res);
}
TRI_IF_FAILURE("CreateCollection::tempDirectory") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); }
// create a temporary file (.tmp)
std::string const tmpfile(
arangodb::basics::FileUtils::buildFilename(tmpname.c_str(), ".tmp"));
res = TRI_WriteFile(tmpfile.c_str(), "", 0);
// this file will be renamed to this filename later...
std::string const tmpfile2(
arangodb::basics::FileUtils::buildFilename(dirname.c_str(), ".tmp"));
TRI_IF_FAILURE("CreateCollection::tempFile") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); }
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create collection '" << parameters.name()
<< "' in directory '" << path << "': " << TRI_errno_string(res)
<< " - " << systemError << " - " << errorMessage;
TRI_RemoveDirectory(tmpname.c_str());
THROW_ARANGO_EXCEPTION(res);
}
TRI_IF_FAILURE("CreateCollection::renameDirectory") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); }
res = TRI_RenameFile(tmpname.c_str(), dirname.c_str());
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create collection '" << parameters.name()
<< "' in directory '" << path << "': " << TRI_errno_string(res)
<< " - " << systemError << " - " << errorMessage;
TRI_RemoveDirectory(tmpname.c_str());
THROW_ARANGO_EXCEPTION(res);
}
// now we have the collection directory in place with the correct name and a
// .tmp file in it
// delete .tmp file
TRI_UnlinkFile(tmpfile2.c_str());
// save the parameters file
auto doSync = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database")->forceSyncProperties();
res = parameters.saveToFile(dirname, doSync);
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot save collection parameters in directory '" << dirname << "': '" << TRI_last_error() << "'";
THROW_ARANGO_EXCEPTION(res);
}
/* TODO: is this necessary?
// remove the temporary file
std::string tmpfile = dirname + ".tmp";
TRI_UnlinkFile(tmpfile.c_str());
*/
return dirname;
}
// asks the storage engine to drop the specified collection and persist the
@ -530,6 +628,7 @@ void MMFilesEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id
// to "dropCollection" returns
void MMFilesEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
std::function<bool()> const& canRemovePhysically) {
unregisterCollectionPath(databaseId, id);
}
// asks the storage engine to rename the collection as specified in the VPack
@ -540,8 +639,19 @@ void MMFilesEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
void MMFilesEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
void MMFilesEngine::renameCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
std::string const& name) {
std::string const path = collectionDirectory(vocbase->id(), id);
arangodb::VocbaseCollectionInfo info =
arangodb::VocbaseCollectionInfo::fromFile(path, vocbase, name, true);
auto doSync = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database")->forceSyncProperties();
int res = info.saveToFile(path, doSync);
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
}
// asks the storage engine to change properties of the collection as specified in
@ -862,7 +972,7 @@ int MMFilesEngine::saveDatabaseParameters(TRI_voc_tick_t id,
TRI_ASSERT(!name.empty());
VPackBuilder builder = databaseToVelocyPack(id, name, deleted);
std::string const file = parametersFile(id);
std::string const file = databaseParametersFilename(id);
if (!arangodb::basics::VelocyPackHelper::velocyPackToFile(
file.c_str(), builder.slice(), true)) {
@ -893,10 +1003,25 @@ std::string MMFilesEngine::databaseDirectory(TRI_voc_tick_t id) const {
return _databasePath + "database-" + std::to_string(id);
}
std::string MMFilesEngine::parametersFile(TRI_voc_tick_t id) const {
std::string MMFilesEngine::databaseParametersFilename(TRI_voc_tick_t id) const {
return basics::FileUtils::buildFilename(databaseDirectory(id), TRI_VOC_PARAMETER_FILE);
}
std::string MMFilesEngine::collectionDirectory(TRI_voc_tick_t databaseId, TRI_voc_cid_t id) const {
auto it = _collectionPaths.find(databaseId);
if (it == _collectionPaths.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "trying to determine directory for unknown collection");
}
auto it2 = (*it).second.find(id);
if (it2 == (*it).second.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "trying to determine directory for unknown collection");
}
return (*it2).second;
}
/// @brief open an existing database. internal function
TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id, std::string const& name,
bool wasCleanShutdown, bool isUpgrade) {
@ -1007,3 +1132,31 @@ bool MMFilesEngine::findMaxTickInJournals(std::string const& path) {
return iterateFiles(structure.journals);
}
/// @brief create a full directory name for a collection
std::string MMFilesEngine::createCollectionDirectoryName(std::string const& basePath, TRI_voc_cid_t cid) {
std::string filename("collection-");
filename.append(std::to_string(cid));
filename.push_back('-');
filename.append(std::to_string(RandomGenerator::interval(UINT32_MAX)));
return arangodb::basics::FileUtils::buildFilename(basePath, filename);
}
void MMFilesEngine::registerCollectionPath(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, std::string const& path) {
auto it = _collectionPaths.find(databaseId);
if (it == _collectionPaths.end()) {
it = _collectionPaths.emplace(databaseId, std::unordered_map<TRI_voc_cid_t, std::string>()).first;
}
(*it).second[id] = path;
}
void MMFilesEngine::unregisterCollectionPath(TRI_voc_tick_t databaseId, TRI_voc_cid_t id) {
auto it = _collectionPaths.find(databaseId);
if (it == _collectionPaths.end()) {
return;
}
(*it).second.erase(id);
}

View File

@ -89,6 +89,9 @@ class MMFilesEngine final : public StorageEngine {
// return the path for a database
std::string databasePath(TRI_vocbase_t const* vocbase) const override { return databaseDirectory(vocbase->id()); }
// return the path for a collection
std::string collectionPath(TRI_vocbase_t const* vocbase, TRI_voc_cid_t id) const override { return collectionDirectory(vocbase->id(), id); }
TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade) override;
// database, collection and index management
@ -127,8 +130,8 @@ class MMFilesEngine final : public StorageEngine {
// 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
void createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::VocbaseCollectionInfo const& parameters) 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
@ -149,8 +152,8 @@ class MMFilesEngine final : public StorageEngine {
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
void renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
void renameCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
std::string const& name) override;
// asks the storage engine to change properties of the collection as specified in
// the VPack Slice object and persist them. If this operation fails
@ -223,7 +226,9 @@ class MMFilesEngine final : public StorageEngine {
bool deleted) const;
std::string databaseDirectory(TRI_voc_tick_t id) const;
std::string parametersFile(TRI_voc_tick_t id) const;
std::string databaseParametersFilename(TRI_voc_tick_t id) const;
std::string collectionDirectory(TRI_voc_tick_t id, TRI_voc_cid_t cid) const;
int openDatabases();
/// @brief open an existing database. internal function
@ -244,6 +249,12 @@ class MMFilesEngine final : public StorageEngine {
/// @brief find the maximum tick in a collection's journals
bool findMaxTickInJournals(std::string const& path);
/// @brief create a full directory name for a collection
std::string createCollectionDirectoryName(std::string const& basePath, TRI_voc_cid_t cid);
void registerCollectionPath(TRI_voc_tick_t databaseId, TRI_voc_cid_t id, std::string const& path);
void unregisterCollectionPath(TRI_voc_tick_t databaseId, TRI_voc_cid_t id);
public:
static std::string const EngineName;
@ -254,6 +265,8 @@ class MMFilesEngine final : public StorageEngine {
bool _isUpgrade;
TRI_voc_tick_t _maxTick;
std::vector<std::pair<std::string, std::string>> _deleted;
std::unordered_map<TRI_voc_tick_t, std::unordered_map<TRI_voc_cid_t, std::string>> _collectionPaths;
};
}

View File

@ -102,8 +102,9 @@ int OtherEngine::waitUntilDeletion(TRI_voc_tick_t id, bool force) {
// 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
void OtherEngine::createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
std::string OtherEngine::createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::VocbaseCollectionInfo const& parameters) {
return "test";
}
// asks the storage engine to drop the specified collection and persist the
@ -126,8 +127,8 @@ void OtherEngine::dropCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
void OtherEngine::renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) {
void OtherEngine::renameCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
std::string const& name) {
}
// asks the storage engine to change properties of the collection as specified in

View File

@ -70,6 +70,9 @@ class OtherEngine final : public StorageEngine {
// return the path for a database
std::string databasePath(TRI_vocbase_t const*) const override { return "none"; }
// return the path for a collection
std::string collectionPath(TRI_vocbase_t const*, TRI_voc_cid_t) const override { return "none"; }
TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade) override {
return nullptr;
}
@ -110,8 +113,8 @@ class OtherEngine final : public StorageEngine {
// 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
void createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::VocbaseCollectionInfo const& parameters) 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
@ -132,8 +135,8 @@ class OtherEngine final : public StorageEngine {
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
void renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) override;
void renameCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
std::string const& name) override;
// asks the storage engine to change properties of the collection as specified in
// the VPack Slice object and persist them. If this operation fails

View File

@ -33,6 +33,7 @@
#include <velocypack/Slice.h>
namespace arangodb {
class VocbaseCollectionInfo;
class StorageEngine : public application_features::ApplicationFeature {
public:
@ -84,6 +85,9 @@ class StorageEngine : public application_features::ApplicationFeature {
// return the path for a database
virtual std::string databasePath(TRI_vocbase_t const* vocbase) const = 0;
// return the path for a collection
virtual std::string collectionPath(TRI_vocbase_t const* vocbase, TRI_voc_cid_t id) const = 0;
virtual TRI_vocbase_t* openDatabase(arangodb::velocypack::Slice const& parameters, bool isUpgrade) = 0;
@ -123,8 +127,8 @@ 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 void createCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) = 0;
virtual std::string createCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
arangodb::VocbaseCollectionInfo const& parameters) = 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
@ -145,8 +149,8 @@ class StorageEngine : public application_features::ApplicationFeature {
// and throw only then, so that subsequent collection creation/rename requests will
// not fail. the WAL entry for the rename will be written *after* the call
// to "renameCollection" returns
virtual void renameCollection(TRI_voc_tick_t databaseId, TRI_voc_cid_t id,
arangodb::velocypack::Slice const& data) = 0;
virtual void renameCollection(TRI_vocbase_t* vocbase, TRI_voc_cid_t id,
std::string const& name) = 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

View File

@ -47,7 +47,6 @@
#include "Indexes/PrimaryIndex.h"
#include "Indexes/SkiplistIndex.h"
#include "Logger/Logger.h"
#include "Random/RandomGenerator.h"
#include "RestServer/DatabaseFeature.h"
#include "StorageEngine/EngineSelectorFeature.h"
#include "StorageEngine/StorageEngine.h"
@ -1631,19 +1630,6 @@ bool TRI_collection_t::closeDataFiles(std::vector<TRI_datafile_t*> const& files)
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the full directory name for a collection
////////////////////////////////////////////////////////////////////////////////
static std::string GetCollectionDirectory(std::string const& path, TRI_voc_cid_t cid) {
std::string filename("collection-");
filename.append(std::to_string(cid));
filename.push_back('-');
filename.append(std::to_string(RandomGenerator::interval(UINT32_MAX)));
return arangodb::basics::FileUtils::buildFilename(path, filename);
}
VocbaseCollectionInfo::VocbaseCollectionInfo(CollectionInfo const& other)
: _version(TRI_COL_VERSION),
@ -2248,94 +2234,6 @@ int TRI_collection_t::close() {
return TRI_ERROR_NO_ERROR;
}
/// @brief creates a new collection, worker function
int TRI_collection_t::createWorker() {
StorageEngine* engine = EngineSelectorFeature::ENGINE;
std::string const path = engine->databasePath(_vocbase);
// sanity check
if (sizeof(TRI_df_header_marker_t) + sizeof(TRI_df_footer_marker_t) >
_info.maximalSize()) {
LOG(ERR) << "cannot create datafile '" << _info.name() << "' in '"
<< path << "', maximal size '"
<< (unsigned int)_info.maximalSize() << "' is too small";
return TRI_ERROR_ARANGO_DATAFILE_FULL;
}
if (!TRI_IsDirectory(path.c_str())) {
LOG(ERR) << "cannot create collection '" << path << "', path is not a directory";
return TRI_ERROR_ARANGO_DATADIR_INVALID;
}
std::string const dirname =
GetCollectionDirectory(path, _info.id());
// directory must not exist
if (TRI_ExistsFile(dirname.c_str())) {
LOG(ERR) << "cannot create collection '" << _info.name()
<< "' in directory '" << dirname << "': directory already exists";
return TRI_ERROR_ARANGO_COLLECTION_DIRECTORY_ALREADY_EXISTS;
}
// use a temporary directory first. this saves us from leaving an empty
// directory behind, and the server refusing to start
std::string const tmpname = dirname + ".tmp";
// create directory
std::string errorMessage;
long systemError;
int res = TRI_CreateDirectory(tmpname.c_str(), systemError, errorMessage);
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create collection '" << _info.name()
<< "' in directory '" << path << "': " << TRI_errno_string(res)
<< " - " << systemError << " - " << errorMessage;
return res;
}
TRI_IF_FAILURE("CreateCollection::tempDirectory") { return TRI_ERROR_DEBUG; }
// create a temporary file (.tmp)
std::string const tmpfile(
arangodb::basics::FileUtils::buildFilename(tmpname.c_str(), ".tmp"));
res = TRI_WriteFile(tmpfile.c_str(), "", 0);
// this file will be renamed to this filename later...
std::string const tmpfile2(
arangodb::basics::FileUtils::buildFilename(dirname.c_str(), ".tmp"));
TRI_IF_FAILURE("CreateCollection::tempFile") { return TRI_ERROR_DEBUG; }
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create collection '" << _info.name()
<< "' in directory '" << path << "': " << TRI_errno_string(res)
<< " - " << systemError << " - " << errorMessage;
TRI_RemoveDirectory(tmpname.c_str());
return res;
}
TRI_IF_FAILURE("CreateCollection::renameDirectory") { return TRI_ERROR_DEBUG; }
res = TRI_RenameFile(tmpname.c_str(), dirname.c_str());
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create collection '" << _info.name()
<< "' in directory '" << path << "': " << TRI_errno_string(res)
<< " - " << systemError << " - " << errorMessage;
TRI_RemoveDirectory(tmpname.c_str());
return res;
}
// now we have the collection directory in place with the correct name and a
// .tmp file in it
_path = dirname;
// delete .tmp file
TRI_UnlinkFile(tmpfile2.c_str());
return TRI_ERROR_NO_ERROR;
}
/// @brief garbage-collect a collection's indexes
int TRI_collection_t::cleanupIndexes() {
int res = TRI_ERROR_NO_ERROR;
@ -5436,37 +5334,21 @@ TRI_collection_t* TRI_collection_t::create(
}
parameters.setCollectionId(cid);
auto collection = std::make_unique<TRI_collection_t>(vocbase, parameters);
int res = collection->createWorker();
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot create document collection";
return nullptr;
}
// create document collection
res = collection->createInitialIndexes();
int res = collection->createInitialIndexes();
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot initialize document collection";
LOG(ERR) << "cannot initialize collection";
return nullptr;
}
// save the parameters block (within create, no need to lock)
bool doSync = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database")->forceSyncProperties();
res = parameters.saveToFile(collection->path(), doSync);
if (res != TRI_ERROR_NO_ERROR) {
LOG(ERR) << "cannot save collection parameters in directory '" << collection->path() << "': '" << TRI_last_error() << "'";
return nullptr;
}
// remove the temporary file
std::string tmpfile = collection->path() + ".tmp";
TRI_UnlinkFile(tmpfile.c_str());
StorageEngine* engine = EngineSelectorFeature::ENGINE;
std::string const path = engine->createCollection(vocbase, cid, parameters);
collection->setPath(path);
return collection.release();
}

View File

@ -366,6 +366,8 @@ struct TRI_collection_t {
inline bool useSecondaryIndexes() const { return _useSecondaryIndexes; }
void useSecondaryIndexes(bool value) { _useSecondaryIndexes = value; }
void setPath(std::string const& path) { _path = path; }
/// @brief renames a collection
int rename(std::string const& name);
@ -493,9 +495,6 @@ struct TRI_collection_t {
TRI_voc_size_t journalSize,
bool isCompactor);
// worker function for creating a collection
int createWorker();
/// @brief creates the initial indexes for the collection
int createInitialIndexes();

View File

@ -492,12 +492,12 @@ int TRI_vocbase_t::renameCollectionWorker(TRI_vocbase_col_t* collection,
std::string const& newName) {
// cannot rename a corrupted collection
if (collection->status() == TRI_VOC_COL_STATUS_CORRUPTED) {
return TRI_set_errno(TRI_ERROR_ARANGO_CORRUPTED_COLLECTION);
return TRI_ERROR_ARANGO_CORRUPTED_COLLECTION;
}
// cannot rename a deleted collection
if (collection->status() == TRI_VOC_COL_STATUS_DELETED) {
return TRI_set_errno(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
return TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
}
{
@ -507,28 +507,15 @@ int TRI_vocbase_t::renameCollectionWorker(TRI_vocbase_col_t* collection,
auto it = _collectionsByName.find(newName);
if (it != _collectionsByName.end()) {
return TRI_set_errno(TRI_ERROR_ARANGO_DUPLICATE_NAME);
return TRI_ERROR_ARANGO_DUPLICATE_NAME;
}
if (collection->status() == TRI_VOC_COL_STATUS_UNLOADED) {
// collection is unloaded
collection->setName(newName);
try {
arangodb::VocbaseCollectionInfo info =
arangodb::VocbaseCollectionInfo::fromFile(collection->path(),
this, newName, true);
bool doSync = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database")->forceSyncProperties();
int res = info.saveToFile(collection->path(), doSync);
if (res != TRI_ERROR_NO_ERROR) {
return TRI_set_errno(res);
}
} catch (arangodb::basics::Exception const& e) {
return TRI_set_errno(e.code());
}
StorageEngine* engine = EngineSelectorFeature::ENGINE;
engine->renameCollection(this, collection->cid(), newName);
// fall-through intentional
}
else if (collection->status() == TRI_VOC_COL_STATUS_LOADED ||
@ -538,13 +525,13 @@ int TRI_vocbase_t::renameCollectionWorker(TRI_vocbase_col_t* collection,
int res = collection->_collection->rename(newName);
if (res != TRI_ERROR_NO_ERROR) {
return TRI_set_errno(res);
return res;
}
// fall-through intentional
}
else {
// unknown status
return TRI_set_errno(TRI_ERROR_INTERNAL);
return TRI_ERROR_INTERNAL;
}
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE