mirror of https://gitee.com/bigwinds/arangodb
moved database lookup functions into DatabaseFeature
This commit is contained in:
parent
b288d3e4dd
commit
33c94e5041
|
@ -470,6 +470,8 @@ void HeartbeatThread::removeDispatchedJob(DBServerAgencySyncResult result) {
|
||||||
|
|
||||||
static std::string const prefixPlanChangeCoordinator = "Plan/Databases";
|
static std::string const prefixPlanChangeCoordinator = "Plan/Databases";
|
||||||
bool HeartbeatThread::handlePlanChangeCoordinator(uint64_t currentPlanVersion) {
|
bool HeartbeatThread::handlePlanChangeCoordinator(uint64_t currentPlanVersion) {
|
||||||
|
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
|
||||||
LOG_TOPIC(TRACE, Logger::HEARTBEAT) << "found a plan update";
|
LOG_TOPIC(TRACE, Logger::HEARTBEAT) << "found a plan update";
|
||||||
AgencyCommResult result = _agency.getValues(prefixPlanChangeCoordinator);
|
AgencyCommResult result = _agency.getValues(prefixPlanChangeCoordinator);
|
||||||
|
|
||||||
|
@ -516,8 +518,7 @@ bool HeartbeatThread::handlePlanChangeCoordinator(uint64_t currentPlanVersion) {
|
||||||
ids.push_back(id);
|
ids.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase =
|
TRI_vocbase_t* vocbase = databaseFeature->useDatabaseCoordinator(name);
|
||||||
TRI_UseCoordinatorDatabaseServer(_server, name.c_str());
|
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
// database does not yet exist, create it now
|
// database does not yet exist, create it now
|
||||||
|
@ -528,7 +529,6 @@ bool HeartbeatThread::handlePlanChangeCoordinator(uint64_t currentPlanVersion) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a local database object...
|
// create a local database object...
|
||||||
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
|
||||||
int res = databaseFeature->createDatabaseCoordinator(id, name, vocbase);
|
int res = databaseFeature->createDatabaseCoordinator(id, name, vocbase);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
|
@ -542,15 +542,13 @@ bool HeartbeatThread::handlePlanChangeCoordinator(uint64_t currentPlanVersion) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the list of databases that we know about locally
|
// get the list of databases that we know about locally
|
||||||
std::vector<TRI_voc_tick_t> localIds =
|
std::vector<TRI_voc_tick_t> localIds = databaseFeature->getDatabaseIdsCoordinator(false);
|
||||||
TRI_GetIdsCoordinatorDatabaseServer(_server);
|
|
||||||
|
|
||||||
for (auto id : localIds) {
|
for (auto id : localIds) {
|
||||||
auto r = std::find(ids.begin(), ids.end(), id);
|
auto r = std::find(ids.begin(), ids.end(), id);
|
||||||
|
|
||||||
if (r == ids.end()) {
|
if (r == ids.end()) {
|
||||||
// local database not found in the plan...
|
// local database not found in the plan...
|
||||||
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
|
||||||
databaseFeature->dropDatabaseCoordinator(id, false);
|
databaseFeature->dropDatabaseCoordinator(id, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,31 +216,30 @@ void GeneralServerFeature::validateOptions(std::shared_ptr<ProgramOptions>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TRI_vocbase_t* LookupDatabaseFromRequest(GeneralRequest* request,
|
static TRI_vocbase_t* LookupDatabaseFromRequest(GeneralRequest* request) {
|
||||||
TRI_server_t* server) {
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
|
||||||
// get database name from request
|
// get database name from request
|
||||||
std::string const& dbName = request->databaseName();
|
std::string const& dbName = request->databaseName();
|
||||||
|
|
||||||
char const* p;
|
|
||||||
if (dbName.empty()) {
|
if (dbName.empty()) {
|
||||||
// if no databases was specified in the request, use system database name
|
// if no databases was specified in the request, use system database name
|
||||||
// as a fallback
|
// as a fallback
|
||||||
request->setDatabaseName(StaticStrings::SystemDatabase);
|
request->setDatabaseName(StaticStrings::SystemDatabase);
|
||||||
p = StaticStrings::SystemDatabase.c_str();
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
} else {
|
return databaseFeature->useDatabaseCoordinator(StaticStrings::SystemDatabase);
|
||||||
p = dbName.c_str();
|
}
|
||||||
|
return databaseFeature->useDatabase(StaticStrings::SystemDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ServerState::instance()->isCoordinator()) {
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
return TRI_UseCoordinatorDatabaseServer(server, p);
|
return databaseFeature->useDatabaseCoordinator(dbName);
|
||||||
}
|
}
|
||||||
|
return databaseFeature->useDatabase(dbName);
|
||||||
return TRI_UseDatabaseServer(server, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetRequestContext(GeneralRequest* request, void* data) {
|
static bool SetRequestContext(GeneralRequest* request, void* data) {
|
||||||
TRI_server_t* server = static_cast<TRI_server_t*>(data);
|
TRI_vocbase_t* vocbase = LookupDatabaseFromRequest(request);
|
||||||
TRI_vocbase_t* vocbase = LookupDatabaseFromRequest(request, server);
|
|
||||||
|
|
||||||
// invalid database name specified, database not found etc.
|
// invalid database name specified, database not found etc.
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
|
@ -284,8 +283,7 @@ void GeneralServerFeature::start() {
|
||||||
|
|
||||||
JOB_MANAGER = _jobManager.get();
|
JOB_MANAGER = _jobManager.get();
|
||||||
|
|
||||||
_handlerFactory.reset(new RestHandlerFactory(&SetRequestContext,
|
_handlerFactory.reset(new RestHandlerFactory(&SetRequestContext, nullptr));
|
||||||
DatabaseFeature::SERVER));
|
|
||||||
|
|
||||||
HANDLER_FACTORY = _handlerFactory.get();
|
HANDLER_FACTORY = _handlerFactory.get();
|
||||||
|
|
||||||
|
|
|
@ -68,10 +68,10 @@ class RestHandlerFactory {
|
||||||
RestHandler* createHandler(GeneralRequest*, GeneralResponse*);
|
RestHandler* createHandler(GeneralRequest*, GeneralResponse*);
|
||||||
|
|
||||||
// adds a path and constructor to the factory
|
// adds a path and constructor to the factory
|
||||||
void addHandler(std::string const& path, create_fptr, void* data = 0);
|
void addHandler(std::string const& path, create_fptr, void* data = nullptr);
|
||||||
|
|
||||||
// adds a prefix path and constructor to the factory
|
// adds a prefix path and constructor to the factory
|
||||||
void addPrefixHandler(std::string const& path, create_fptr, void* data = 0);
|
void addPrefixHandler(std::string const& path, create_fptr, void* data = nullptr);
|
||||||
|
|
||||||
// adds a path and constructor to the factory
|
// adds a path and constructor to the factory
|
||||||
void addNotFoundHandler(create_fptr);
|
void addNotFoundHandler(create_fptr);
|
||||||
|
|
|
@ -168,12 +168,11 @@ void BootstrapFeature::start() {
|
||||||
|
|
||||||
void BootstrapFeature::unprepare() {
|
void BootstrapFeature::unprepare() {
|
||||||
// notify all currently running queries about the shutdown
|
// notify all currently running queries about the shutdown
|
||||||
TRI_server_t* s = DatabaseFeature::SERVER;
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
|
||||||
if (ServerState::instance()->isCoordinator()) {
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
std::vector<TRI_voc_tick_t> ids =
|
for (auto& id : databaseFeature->getDatabaseIdsCoordinator(true)) {
|
||||||
TRI_GetIdsCoordinatorDatabaseServer(s, true);
|
TRI_vocbase_t* vocbase = databaseFeature->useDatabase(id);
|
||||||
for (auto& id : ids) {
|
|
||||||
TRI_vocbase_t* vocbase = TRI_UseByIdCoordinatorDatabaseServer(s, id);
|
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
vocbase->_queries->killAll(true);
|
vocbase->_queries->killAll(true);
|
||||||
|
@ -181,11 +180,9 @@ void BootstrapFeature::unprepare() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names = databaseFeature->getDatabaseNames();
|
||||||
int res = TRI_GetDatabaseNamesServer(s, names);
|
for (auto& name : databaseFeature->getDatabaseNames()) {
|
||||||
if (res == TRI_ERROR_NO_ERROR) {
|
TRI_vocbase_t* vocbase = databaseFeature->useDatabase(name);
|
||||||
for (auto& name : names) {
|
|
||||||
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer(s, name.c_str());
|
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
vocbase->_queries->killAll(true);
|
vocbase->_queries->killAll(true);
|
||||||
|
@ -193,5 +190,4 @@ void BootstrapFeature::unprepare() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "V8Server/V8DealerFeature.h"
|
#include "V8Server/V8DealerFeature.h"
|
||||||
#include "V8Server/v8-query.h"
|
#include "V8Server/v8-query.h"
|
||||||
#include "V8Server/v8-vocbase.h"
|
#include "V8Server/v8-vocbase.h"
|
||||||
|
#include "VocBase/AuthInfo.h"
|
||||||
#include "VocBase/KeyGenerator.h"
|
#include "VocBase/KeyGenerator.h"
|
||||||
#include "VocBase/replication-applier.h"
|
#include "VocBase/replication-applier.h"
|
||||||
#include "VocBase/server.h"
|
#include "VocBase/server.h"
|
||||||
|
@ -711,15 +712,144 @@ int DatabaseFeature::dropDatabase(TRI_voc_tick_t id, bool writeMarker, bool wait
|
||||||
return dropDatabase(name, writeMarker, waitForDeletion, removeAppsDirectory);
|
return dropDatabase(name, writeMarker, waitForDeletion, removeAppsDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<TRI_voc_tick_t> DatabaseFeature::getDatabaseIdsCoordinator(bool includeSystem) {
|
||||||
|
std::vector<TRI_voc_tick_t> ids;
|
||||||
|
{
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_coordinatorDatabases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
TRI_ASSERT(vocbase != nullptr);
|
||||||
|
|
||||||
|
if (includeSystem || std::string(vocbase->_name) != TRI_VOC_SYSTEM_DATABASE) {
|
||||||
|
ids.emplace_back(vocbase->_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TRI_voc_tick_t> DatabaseFeature::getDatabaseIds(bool includeSystem) {
|
||||||
|
std::vector<TRI_voc_tick_t> ids;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_databases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
TRI_ASSERT(vocbase != nullptr);
|
||||||
|
if (includeSystem || std::string(vocbase->_name) != TRI_VOC_SYSTEM_DATABASE) {
|
||||||
|
ids.emplace_back(vocbase->_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief return the list of all database names
|
||||||
|
std::vector<std::string> DatabaseFeature::getDatabaseNames() {
|
||||||
|
std::vector<std::string> names;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_databases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
TRI_ASSERT(vocbase != nullptr);
|
||||||
|
TRI_ASSERT(vocbase->_name != nullptr);
|
||||||
|
|
||||||
|
names.emplace_back(vocbase->_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(
|
||||||
|
names.begin(), names.end(),
|
||||||
|
[](std::string const& l, std::string const& r) -> bool { return l < r; });
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief return the list of all database names for a user
|
||||||
|
std::vector<std::string> DatabaseFeature::getDatabaseNamesForUser(std::string const& username) {
|
||||||
|
std::vector<std::string> names;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_databases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
TRI_ASSERT(vocbase != nullptr);
|
||||||
|
TRI_ASSERT(vocbase->_name != nullptr);
|
||||||
|
|
||||||
|
auto level =
|
||||||
|
GeneralServerFeature::AUTH_INFO.canUseDatabase(username, vocbase->_name);
|
||||||
|
|
||||||
|
if (level == AuthLevel::NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
names.emplace_back(vocbase->_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(
|
||||||
|
names.begin(), names.end(),
|
||||||
|
[](std::string const& l, std::string const& r) -> bool { return l < r; });
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseFeature::useSystemDatabase() {
|
void DatabaseFeature::useSystemDatabase() {
|
||||||
useDatabase(TRI_VOC_SYSTEM_DATABASE);
|
useDatabase(TRI_VOC_SYSTEM_DATABASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief get a coordinator database by its id
|
||||||
|
/// this will increase the reference-counter for the database
|
||||||
|
TRI_vocbase_t* DatabaseFeature::useDatabaseCoordinator(TRI_voc_tick_t id) {
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_coordinatorDatabases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
|
||||||
|
if (vocbase->_id == id) {
|
||||||
|
bool result TRI_UNUSED = TRI_UseVocBase(vocbase);
|
||||||
|
|
||||||
|
// if we got here, no one else can have deleted the database
|
||||||
|
TRI_ASSERT(result == true);
|
||||||
|
return vocbase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRI_vocbase_t* DatabaseFeature::useDatabaseCoordinator(std::string const& name) {
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
TRI_vocbase_t* vocbase = nullptr;
|
||||||
|
auto it = theLists->_coordinatorDatabases.find(name);
|
||||||
|
|
||||||
|
if (it != theLists->_coordinatorDatabases.end()) {
|
||||||
|
vocbase = it->second;
|
||||||
|
TRI_UseVocBase(vocbase);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vocbase;
|
||||||
|
}
|
||||||
|
|
||||||
TRI_vocbase_t* DatabaseFeature::useDatabase(std::string const& name) {
|
TRI_vocbase_t* DatabaseFeature::useDatabase(std::string const& name) {
|
||||||
auto unuser(_databasesProtector.use());
|
auto unuser(_databasesProtector.use());
|
||||||
auto theLists = _databasesLists.load();
|
auto theLists = _databasesLists.load();
|
||||||
auto it = theLists->_databases.find(name);
|
|
||||||
TRI_vocbase_t* vocbase = nullptr;
|
TRI_vocbase_t* vocbase = nullptr;
|
||||||
|
auto it = theLists->_databases.find(name);
|
||||||
|
|
||||||
if (it != theLists->_databases.end()) {
|
if (it != theLists->_databases.end()) {
|
||||||
vocbase = it->second;
|
vocbase = it->second;
|
||||||
|
@ -729,6 +859,44 @@ TRI_vocbase_t* DatabaseFeature::useDatabase(std::string const& name) {
|
||||||
return vocbase;
|
return vocbase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TRI_vocbase_t* DatabaseFeature::useDatabase(TRI_voc_tick_t id) {
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_databases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
|
||||||
|
if (vocbase->_id == id) {
|
||||||
|
TRI_UseVocBase(vocbase);
|
||||||
|
return vocbase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief release a previously used database
|
||||||
|
/// this will decrease the reference-counter for the database
|
||||||
|
void DatabaseFeature::releaseDatabase(TRI_vocbase_t* vocbase) {
|
||||||
|
TRI_ReleaseVocBase(vocbase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief lookup a database by its name
|
||||||
|
TRI_vocbase_t* DatabaseFeature::lookupDatabase(std::string const& name) {
|
||||||
|
auto unuser(_databasesProtector.use());
|
||||||
|
auto theLists = _databasesLists.load();
|
||||||
|
|
||||||
|
for (auto& p : theLists->_databases) {
|
||||||
|
TRI_vocbase_t* vocbase = p.second;
|
||||||
|
|
||||||
|
if (name == vocbase->_name) {
|
||||||
|
return vocbase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseFeature::updateContexts() {
|
void DatabaseFeature::updateContexts() {
|
||||||
TRI_ASSERT(_vocbase != nullptr);
|
TRI_ASSERT(_vocbase != nullptr);
|
||||||
|
|
||||||
|
|
|
@ -77,14 +77,27 @@ class DatabaseFeature final : public application_features::ApplicationFeature {
|
||||||
void unprepare() override final;
|
void unprepare() override final;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief get the ids of all local coordinator databases
|
||||||
|
std::vector<TRI_voc_tick_t> getDatabaseIdsCoordinator(bool includeSystem);
|
||||||
|
std::vector<TRI_voc_tick_t> getDatabaseIds(bool includeSystem);
|
||||||
|
std::vector<std::string> getDatabaseNames();
|
||||||
|
std::vector<std::string> getDatabaseNamesForUser(std::string const& user);
|
||||||
|
|
||||||
int createDatabaseCoordinator(TRI_voc_tick_t id, std::string const& name, TRI_vocbase_t*& result);
|
int createDatabaseCoordinator(TRI_voc_tick_t id, std::string const& name, TRI_vocbase_t*& result);
|
||||||
int createDatabase(TRI_voc_tick_t id, std::string const& name, bool writeMarker, TRI_vocbase_t*& result);
|
int createDatabase(TRI_voc_tick_t id, std::string const& name, bool writeMarker, TRI_vocbase_t*& result);
|
||||||
int dropDatabaseCoordinator(TRI_voc_tick_t id, bool force);
|
int dropDatabaseCoordinator(TRI_voc_tick_t id, bool force);
|
||||||
int dropDatabase(std::string const& name, bool writeMarker, bool waitForDeletion, bool removeAppsDirectory);
|
int dropDatabase(std::string const& name, bool writeMarker, bool waitForDeletion, bool removeAppsDirectory);
|
||||||
int dropDatabase(TRI_voc_tick_t id, bool writeMarker, bool waitForDeletion, bool removeAppsDirectory);
|
int dropDatabase(TRI_voc_tick_t id, bool writeMarker, bool waitForDeletion, bool removeAppsDirectory);
|
||||||
|
|
||||||
void useSystemDatabase();
|
TRI_vocbase_t* useDatabaseCoordinator(std::string const& name);
|
||||||
|
TRI_vocbase_t* useDatabaseCoordinator(TRI_voc_tick_t id);
|
||||||
TRI_vocbase_t* useDatabase(std::string const& name);
|
TRI_vocbase_t* useDatabase(std::string const& name);
|
||||||
|
TRI_vocbase_t* useDatabase(TRI_voc_tick_t id);
|
||||||
|
void releaseDatabase(TRI_vocbase_t* vocbase);
|
||||||
|
|
||||||
|
TRI_vocbase_t* lookupDatabase(std::string const& name);
|
||||||
|
|
||||||
|
void useSystemDatabase();
|
||||||
TRI_vocbase_t* systemDatabase() const { return _vocbase; }
|
TRI_vocbase_t* systemDatabase() const { return _vocbase; }
|
||||||
bool ignoreDatafileErrors() const { return _ignoreDatafileErrors; }
|
bool ignoreDatafileErrors() const { return _ignoreDatafileErrors; }
|
||||||
bool isInitiallyEmpty() const { return _isInitiallyEmpty; }
|
bool isInitiallyEmpty() const { return _isInitiallyEmpty; }
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
#ifndef ARANGOD_UTILS_DATABASE_GUARD_H
|
#ifndef ARANGOD_UTILS_DATABASE_GUARD_H
|
||||||
#define ARANGOD_UTILS_DATABASE_GUARD_H 1
|
#define ARANGOD_UTILS_DATABASE_GUARD_H 1
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "ApplicationFeatures/ApplicationServer.h"
|
||||||
#include "Basics/Exceptions.h"
|
#include "Basics/Exceptions.h"
|
||||||
|
#include "RestServer/DatabaseFeature.h"
|
||||||
#include "VocBase/server.h"
|
#include "VocBase/server.h"
|
||||||
|
|
||||||
struct TRI_vocbase_t;
|
struct TRI_vocbase_t;
|
||||||
|
@ -43,7 +44,9 @@ class DatabaseGuard {
|
||||||
|
|
||||||
DatabaseGuard(TRI_server_t* server, TRI_voc_tick_t id)
|
DatabaseGuard(TRI_server_t* server, TRI_voc_tick_t id)
|
||||||
: _server(server), _database(nullptr) {
|
: _server(server), _database(nullptr) {
|
||||||
_database = TRI_UseDatabaseByIdServer(server, id);
|
|
||||||
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
_database = databaseFeature->useDatabase(id);
|
||||||
|
|
||||||
if (_database == nullptr) {
|
if (_database == nullptr) {
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||||
|
@ -56,7 +59,9 @@ class DatabaseGuard {
|
||||||
|
|
||||||
DatabaseGuard(TRI_server_t* server, char const* name)
|
DatabaseGuard(TRI_server_t* server, char const* name)
|
||||||
: _server(server), _database(nullptr) {
|
: _server(server), _database(nullptr) {
|
||||||
_database = TRI_UseDatabaseServer(server, name);
|
|
||||||
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
_database = databaseFeature->useDatabase(name);
|
||||||
|
|
||||||
if (_database == nullptr) {
|
if (_database == nullptr) {
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||||
|
@ -69,7 +74,8 @@ class DatabaseGuard {
|
||||||
|
|
||||||
~DatabaseGuard() {
|
~DatabaseGuard() {
|
||||||
if (_database != nullptr) {
|
if (_database != nullptr) {
|
||||||
TRI_ReleaseDatabaseServer(_server, _database);
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
databaseFeature->releaseDatabase(_database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#ifndef ARANGOD_UTILS_REPLICATION_TRANSACTION_H
|
#ifndef ARANGOD_UTILS_REPLICATION_TRANSACTION_H
|
||||||
#define ARANGOD_UTILS_REPLICATION_TRANSACTION_H 1
|
#define ARANGOD_UTILS_REPLICATION_TRANSACTION_H 1
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "ApplicationFeatures/ApplicationServer.h"
|
||||||
#include "RestServer/DatabaseFeature.h"
|
#include "RestServer/DatabaseFeature.h"
|
||||||
#include "Utils/StandaloneTransactionContext.h"
|
#include "Utils/StandaloneTransactionContext.h"
|
||||||
#include "Utils/Transaction.h"
|
#include "Utils/Transaction.h"
|
||||||
|
@ -44,7 +44,8 @@ class ReplicationTransaction : public Transaction {
|
||||||
ReplicationTransaction(TRI_vocbase_t* vocbase)
|
ReplicationTransaction(TRI_vocbase_t* vocbase)
|
||||||
: Transaction(StandaloneTransactionContext::Create(vocbase)) {
|
: Transaction(StandaloneTransactionContext::Create(vocbase)) {
|
||||||
|
|
||||||
TRI_UseDatabaseServer(DatabaseFeature::SERVER, vocbase->_name);
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
databaseFeature->useDatabase(vocbase->_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -52,7 +53,8 @@ class ReplicationTransaction : public Transaction {
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
~ReplicationTransaction() {
|
~ReplicationTransaction() {
|
||||||
TRI_ReleaseDatabaseServer(DatabaseFeature::SERVER, vocbase());
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
databaseFeature->releaseDatabase(vocbase());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -2031,7 +2031,8 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
TRI_V8_THROW_EXCEPTION(TRI_ERROR_FORBIDDEN);
|
TRI_V8_THROW_EXCEPTION(TRI_ERROR_FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name = TRI_ObjectToString(args[0]);
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
std::string const name = TRI_ObjectToString(args[0]);
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
TRI_vocbase_t* vocbase = GetContextVocBase(isolate);
|
||||||
|
|
||||||
|
@ -2049,12 +2050,10 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ServerState::instance()->isCoordinator()) {
|
if (ServerState::instance()->isCoordinator()) {
|
||||||
vocbase = TRI_UseCoordinatorDatabaseServer(
|
vocbase = databaseFeature->useDatabaseCoordinator(name);
|
||||||
static_cast<TRI_server_t*>(v8g->_server), name.c_str());
|
|
||||||
} else {
|
} else {
|
||||||
// check if the other database exists, and increase its refcount
|
// check if the other database exists, and increase its refcount
|
||||||
vocbase = TRI_UseDatabaseServer(static_cast<TRI_server_t*>(v8g->_server),
|
vocbase = databaseFeature->useDatabase(name);
|
||||||
name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
|
@ -2067,8 +2066,7 @@ static void JS_UseDatabase(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
|
|
||||||
v8g->_vocbase = vocbase;
|
v8g->_vocbase = vocbase;
|
||||||
TRI_ASSERT(orig != vocbase);
|
TRI_ASSERT(orig != vocbase);
|
||||||
TRI_ReleaseDatabaseServer(static_cast<TRI_server_t*>(v8g->_server),
|
databaseFeature->releaseDatabase(static_cast<TRI_vocbase_t*>(orig));
|
||||||
static_cast<TRI_vocbase_t*>(orig));
|
|
||||||
|
|
||||||
TRI_V8_RETURN(WrapVocBase(isolate, vocbase));
|
TRI_V8_RETURN(WrapVocBase(isolate, vocbase));
|
||||||
}
|
}
|
||||||
|
@ -2171,26 +2169,15 @@ static void JS_Databases(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_GET_GLOBALS();
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
// return all databases
|
// return all databases
|
||||||
res = TRI_GetDatabaseNamesServer(static_cast<TRI_server_t*>(v8g->_server),
|
names = databaseFeature->getDatabaseNames();
|
||||||
names);
|
|
||||||
} else {
|
} else {
|
||||||
// return all databases for a specific user
|
// return all databases for a specific user
|
||||||
std::string&& username = TRI_ObjectToString(args[0]);
|
names = databaseFeature->getDatabaseNamesForUser(TRI_ObjectToString(args[0]));
|
||||||
|
|
||||||
res = TRI_GetUserDatabasesServer(static_cast<TRI_server_t*>(v8g->_server),
|
|
||||||
username.c_str(), names);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
|
||||||
TRI_V8_THROW_EXCEPTION(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Handle<v8::Array> result = v8::Array::New(isolate, (int)names.size());
|
v8::Handle<v8::Array> result = v8::Array::New(isolate, (int)names.size());
|
||||||
|
@ -2268,9 +2255,10 @@ static void CreateDatabaseCoordinator(
|
||||||
TRI_vocbase_t* vocbase = nullptr;
|
TRI_vocbase_t* vocbase = nullptr;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
|
|
||||||
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
|
||||||
while (++tries <= 6000) {
|
while (++tries <= 6000) {
|
||||||
vocbase = TRI_UseByIdCoordinatorDatabaseServer(
|
vocbase = databaseFeature->useDatabaseCoordinator(id);
|
||||||
static_cast<TRI_server_t*>(v8g->_server), id);
|
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
break;
|
break;
|
||||||
|
@ -2418,12 +2406,10 @@ static void DropDatabaseCoordinator(
|
||||||
v8::Isolate* isolate = args.GetIsolate();
|
v8::Isolate* isolate = args.GetIsolate();
|
||||||
v8::HandleScope scope(isolate);
|
v8::HandleScope scope(isolate);
|
||||||
|
|
||||||
TRI_GET_GLOBALS();
|
|
||||||
|
|
||||||
// Arguments are already checked, there is exactly one argument
|
// Arguments are already checked, there is exactly one argument
|
||||||
|
auto databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
std::string const name = TRI_ObjectToString(args[0]);
|
std::string const name = TRI_ObjectToString(args[0]);
|
||||||
TRI_vocbase_t* vocbase = TRI_UseCoordinatorDatabaseServer(
|
TRI_vocbase_t* vocbase = databaseFeature->useDatabaseCoordinator(name);
|
||||||
static_cast<TRI_server_t*>(v8g->_server), name.c_str());
|
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
// no such database
|
// no such database
|
||||||
|
@ -2446,8 +2432,7 @@ static void DropDatabaseCoordinator(
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
|
|
||||||
while (++tries <= 6000) {
|
while (++tries <= 6000) {
|
||||||
TRI_vocbase_t* vocbase = TRI_UseByIdCoordinatorDatabaseServer(
|
TRI_vocbase_t* vocbase = databaseFeature->useDatabaseCoordinator(id);
|
||||||
static_cast<TRI_server_t*>(v8g->_server), id);
|
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
// object has vanished
|
// object has vanished
|
||||||
|
|
|
@ -173,215 +173,6 @@ int TRI_InitDatabasesServer(TRI_server_t* server) {
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get the ids of all local coordinator databases
|
|
||||||
/// the caller is responsible for freeing the result
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::vector<TRI_voc_tick_t> TRI_GetIdsCoordinatorDatabaseServer(
|
|
||||||
TRI_server_t* server, bool includeSystem) {
|
|
||||||
std::vector<TRI_voc_tick_t> v;
|
|
||||||
{
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
|
|
||||||
for (auto& p : theLists->_coordinatorDatabases) {
|
|
||||||
TRI_vocbase_t* vocbase = p.second;
|
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
|
||||||
|
|
||||||
if (includeSystem ||
|
|
||||||
!TRI_EqualString(vocbase->_name, TRI_VOC_SYSTEM_DATABASE)) {
|
|
||||||
v.emplace_back(vocbase->_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get a coordinator database by its id
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseByIdCoordinatorDatabaseServer(TRI_server_t* server,
|
|
||||||
TRI_voc_tick_t id) {
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
|
|
||||||
for (auto& p : theLists->_coordinatorDatabases) {
|
|
||||||
TRI_vocbase_t* vocbase = p.second;
|
|
||||||
|
|
||||||
if (vocbase->_id == id) {
|
|
||||||
bool result TRI_UNUSED = TRI_UseVocBase(vocbase);
|
|
||||||
|
|
||||||
// if we got here, no one else can have deleted the database
|
|
||||||
TRI_ASSERT(result == true);
|
|
||||||
return vocbase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get a coordinator database by its name
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseCoordinatorDatabaseServer(TRI_server_t* server,
|
|
||||||
char const* name) {
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
auto it = theLists->_coordinatorDatabases.find(std::string(name));
|
|
||||||
TRI_vocbase_t* vocbase = nullptr;
|
|
||||||
|
|
||||||
if (it != theLists->_coordinatorDatabases.end()) {
|
|
||||||
vocbase = it->second;
|
|
||||||
TRI_UseVocBase(vocbase);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vocbase;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get a database by its name
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseDatabaseServer(TRI_server_t* server, char const* name) {
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
auto it = theLists->_databases.find(std::string(name));
|
|
||||||
TRI_vocbase_t* vocbase = nullptr;
|
|
||||||
|
|
||||||
if (it != theLists->_databases.end()) {
|
|
||||||
vocbase = it->second;
|
|
||||||
TRI_UseVocBase(vocbase);
|
|
||||||
}
|
|
||||||
|
|
||||||
return vocbase;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief lookup a database by its name
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_LookupDatabaseByNameServer(TRI_server_t* server,
|
|
||||||
char const* name) {
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
|
|
||||||
for (auto& p : theLists->_databases) {
|
|
||||||
TRI_vocbase_t* vocbase = p.second;
|
|
||||||
|
|
||||||
if (TRI_EqualString(vocbase->_name, name)) {
|
|
||||||
return vocbase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get a database by its id
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseDatabaseByIdServer(TRI_server_t* server,
|
|
||||||
TRI_voc_tick_t id) {
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
|
|
||||||
for (auto& p : theLists->_databases) {
|
|
||||||
TRI_vocbase_t* vocbase = p.second;
|
|
||||||
|
|
||||||
if (vocbase->_id == id) {
|
|
||||||
TRI_UseVocBase(vocbase);
|
|
||||||
return vocbase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief release a previously used database
|
|
||||||
/// this will decrease the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void TRI_ReleaseDatabaseServer(TRI_server_t* server, TRI_vocbase_t* vocbase) {
|
|
||||||
TRI_ReleaseVocBase(vocbase);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the list of all databases a user can see
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_GetUserDatabasesServer(TRI_server_t* server, char const* username,
|
|
||||||
std::vector<std::string>& names) {
|
|
||||||
int res = TRI_ERROR_NO_ERROR;
|
|
||||||
|
|
||||||
{
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
|
|
||||||
for (auto& p : theLists->_databases) {
|
|
||||||
char const* dbName = p.second->_name;
|
|
||||||
TRI_ASSERT(dbName != nullptr);
|
|
||||||
|
|
||||||
auto level =
|
|
||||||
GeneralServerFeature::AUTH_INFO.canUseDatabase(username, dbName);
|
|
||||||
|
|
||||||
if (level == AuthLevel::NONE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
names.emplace_back(dbName);
|
|
||||||
} catch (...) {
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(
|
|
||||||
names.begin(), names.end(),
|
|
||||||
[](std::string const& l, std::string const& r) -> bool { return l < r; });
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the list of all database names
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_GetDatabaseNamesServer(TRI_server_t* server,
|
|
||||||
std::vector<std::string>& names) {
|
|
||||||
int res = TRI_ERROR_NO_ERROR;
|
|
||||||
|
|
||||||
{
|
|
||||||
auto unuser(server->_databasesProtector.use());
|
|
||||||
auto theLists = server->_databasesLists.load();
|
|
||||||
|
|
||||||
for (auto& p : theLists->_databases) {
|
|
||||||
TRI_vocbase_t* vocbase = p.second;
|
|
||||||
TRI_ASSERT(vocbase != nullptr);
|
|
||||||
TRI_ASSERT(vocbase->_name != nullptr);
|
|
||||||
|
|
||||||
try {
|
|
||||||
names.emplace_back(vocbase->_name);
|
|
||||||
} catch (...) {
|
|
||||||
return TRI_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(
|
|
||||||
names.begin(), names.end(),
|
|
||||||
[](std::string const& l, std::string const& r) -> bool { return l < r; });
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief sets the current operation mode of the server
|
/// @brief sets the current operation mode of the server
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -69,68 +69,6 @@ struct TRI_server_t {
|
||||||
|
|
||||||
int TRI_InitDatabasesServer(TRI_server_t*);
|
int TRI_InitDatabasesServer(TRI_server_t*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get the ids of all local coordinator databases
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::vector<TRI_voc_tick_t> TRI_GetIdsCoordinatorDatabaseServer(TRI_server_t*,
|
|
||||||
bool includeSystem = false);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief get a coordinator database by its id
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseByIdCoordinatorDatabaseServer(TRI_server_t*,
|
|
||||||
TRI_voc_tick_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief use a coordinator database by its name
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseCoordinatorDatabaseServer(TRI_server_t*, char const*);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief use a database by its name
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseDatabaseServer(TRI_server_t*, char const*);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief lookup a database by its name
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_LookupDatabaseByNameServer(TRI_server_t*, char const*);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief use a database by its id
|
|
||||||
/// this will increase the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
TRI_vocbase_t* TRI_UseDatabaseByIdServer(TRI_server_t*, TRI_voc_tick_t);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief release a previously used database
|
|
||||||
/// this will decrease the reference-counter for the database
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void TRI_ReleaseDatabaseServer(TRI_server_t*, TRI_vocbase_t*);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the list of all databases a user can see
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_GetUserDatabasesServer(TRI_server_t*, char const*,
|
|
||||||
std::vector<std::string>&);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief return the list of all database names
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int TRI_GetDatabaseNamesServer(TRI_server_t*, std::vector<std::string>&);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief sets the current operation mode of the server
|
/// @brief sets the current operation mode of the server
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -303,7 +303,7 @@ void LogfileManager::start() {
|
||||||
|
|
||||||
// initialize some objects
|
// initialize some objects
|
||||||
_slots = new Slots(this, _numberOfSlots, 0);
|
_slots = new Slots(this, _numberOfSlots, 0);
|
||||||
_recoverState = new RecoverState(_server, _ignoreRecoveryErrors);
|
_recoverState = new RecoverState(_ignoreRecoveryErrors);
|
||||||
|
|
||||||
TRI_ASSERT(!_allowWrites);
|
TRI_ASSERT(!_allowWrites);
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,8 @@ static inline T NumericValue(VPackSlice const& slice, char const* attribute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief creates the recover state
|
/// @brief creates the recover state
|
||||||
RecoverState::RecoverState(TRI_server_t* server, bool ignoreRecoveryErrors)
|
RecoverState::RecoverState(bool ignoreRecoveryErrors)
|
||||||
: server(server),
|
: databaseFeature(nullptr),
|
||||||
failedTransactions(),
|
failedTransactions(),
|
||||||
lastTick(0),
|
lastTick(0),
|
||||||
logfilesToProcess(),
|
logfilesToProcess(),
|
||||||
|
@ -80,7 +80,10 @@ RecoverState::RecoverState(TRI_server_t* server, bool ignoreRecoveryErrors)
|
||||||
ignoreRecoveryErrors(ignoreRecoveryErrors),
|
ignoreRecoveryErrors(ignoreRecoveryErrors),
|
||||||
errorCount(0),
|
errorCount(0),
|
||||||
lastDatabaseId(0),
|
lastDatabaseId(0),
|
||||||
lastCollectionId(0) {}
|
lastCollectionId(0) {
|
||||||
|
|
||||||
|
databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief destroys the recover state
|
/// @brief destroys the recover state
|
||||||
RecoverState::~RecoverState() { releaseResources(); }
|
RecoverState::~RecoverState() { releaseResources(); }
|
||||||
|
@ -99,8 +102,7 @@ void RecoverState::releaseResources() {
|
||||||
|
|
||||||
// release all databases
|
// release all databases
|
||||||
for (auto it = openedDatabases.begin(); it != openedDatabases.end(); ++it) {
|
for (auto it = openedDatabases.begin(); it != openedDatabases.end(); ++it) {
|
||||||
TRI_vocbase_t* vocbase = (*it).second;
|
databaseFeature->releaseDatabase((*it).second);
|
||||||
TRI_ReleaseDatabaseServer(server, vocbase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openedDatabases.clear();
|
openedDatabases.clear();
|
||||||
|
@ -114,7 +116,7 @@ TRI_vocbase_t* RecoverState::useDatabase(TRI_voc_tick_t databaseId) {
|
||||||
return (*it).second;
|
return (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_vocbase_t* vocbase = TRI_UseDatabaseByIdServer(server, databaseId);
|
TRI_vocbase_t* vocbase = databaseFeature->useDatabase(databaseId);
|
||||||
|
|
||||||
if (vocbase == nullptr) {
|
if (vocbase == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -157,7 +159,7 @@ TRI_vocbase_t* RecoverState::releaseDatabase(TRI_voc_tick_t databaseId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRI_ReleaseDatabaseServer(server, vocbase);
|
databaseFeature->releaseDatabase(vocbase);
|
||||||
openedDatabases.erase(databaseId);
|
openedDatabases.erase(databaseId);
|
||||||
|
|
||||||
return vocbase;
|
return vocbase;
|
||||||
|
@ -818,11 +820,10 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
if (state->willBeDropped(collectionId)) {
|
if (state->willBeDropped(collectionId)) {
|
||||||
// in case we detect that this collection is going to be deleted anyway,
|
// in case we detect that this collection is going to be deleted anyway,
|
||||||
// set the sync properties to false temporarily
|
// set the sync properties to false temporarily
|
||||||
auto database = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
bool oldSync = state->databaseFeature->forceSyncProperties();
|
||||||
bool oldSync = database->forceSyncProperties();
|
state->databaseFeature->forceSyncProperties(false);
|
||||||
database->forceSyncProperties(false);
|
|
||||||
collection = TRI_CreateCollectionVocBase(vocbase, info, collectionId, false);
|
collection = TRI_CreateCollectionVocBase(vocbase, info, collectionId, false);
|
||||||
database->forceSyncProperties(oldSync);
|
state->databaseFeature->forceSyncProperties(oldSync);
|
||||||
} else {
|
} else {
|
||||||
// collection will be kept
|
// collection will be kept
|
||||||
collection =
|
collection =
|
||||||
|
@ -855,9 +856,8 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
// remove already existing database
|
// remove already existing database
|
||||||
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
|
||||||
// TODO: how to signal a dropDatabase failure here?
|
// TODO: how to signal a dropDatabase failure here?
|
||||||
databaseFeature->dropDatabase(databaseId, false, true, false);
|
state->databaseFeature->dropDatabase(databaseId, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
VPackSlice const nameSlice = payloadSlice.get("name");
|
VPackSlice const nameSlice = payloadSlice.get("name");
|
||||||
|
@ -871,16 +871,14 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
std::string nameString = nameSlice.copyString();
|
std::string nameString = nameSlice.copyString();
|
||||||
|
|
||||||
// remove already existing database with same name
|
// remove already existing database with same name
|
||||||
vocbase =
|
vocbase = state->databaseFeature->lookupDatabase(nameString);
|
||||||
TRI_LookupDatabaseByNameServer(state->server, nameString.c_str());
|
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
TRI_voc_tick_t otherId = vocbase->_id;
|
TRI_voc_tick_t otherId = vocbase->_id;
|
||||||
|
|
||||||
state->releaseDatabase(otherId);
|
state->releaseDatabase(otherId);
|
||||||
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
|
||||||
// TODO: how to signal a dropDatabase failure here?
|
// TODO: how to signal a dropDatabase failure here?
|
||||||
databaseFeature->dropDatabase(nameString, false, true, false);
|
state->databaseFeature->dropDatabase(nameString, false, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
vocbase = nullptr;
|
vocbase = nullptr;
|
||||||
|
@ -888,8 +886,7 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
WaitForDeletion(state->server, databaseId,
|
WaitForDeletion(state->server, databaseId,
|
||||||
TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
|
||||||
*/
|
*/
|
||||||
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
int res = state->databaseFeature->createDatabase(databaseId, nameString, false, vocbase);
|
||||||
int res = databaseFeature->createDatabase(databaseId, nameString, false, vocbase);
|
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
LOG(WARN) << "cannot create database " << databaseId << ": " << TRI_errno_string(res);
|
LOG(WARN) << "cannot create database " << databaseId << ": " << TRI_errno_string(res);
|
||||||
|
@ -1005,8 +1002,7 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
|
|
||||||
if (vocbase != nullptr) {
|
if (vocbase != nullptr) {
|
||||||
// ignore any potential error returned by this call
|
// ignore any potential error returned by this call
|
||||||
DatabaseFeature* databaseFeature = application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
state->databaseFeature->dropDatabase(databaseId, false, true, false);
|
||||||
databaseFeature->dropDatabase(databaseId, false, true, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ARANGODB_ENABLE_ROCKSDB
|
#ifdef ARANGODB_ENABLE_ROCKSDB
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "Wal/Marker.h"
|
#include "Wal/Marker.h"
|
||||||
|
|
||||||
namespace arangodb {
|
namespace arangodb {
|
||||||
|
class DatabaseFeature;
|
||||||
|
|
||||||
namespace wal {
|
namespace wal {
|
||||||
|
|
||||||
/// @brief state that is built up when scanning a WAL logfile during recovery
|
/// @brief state that is built up when scanning a WAL logfile during recovery
|
||||||
|
@ -43,7 +45,7 @@ struct RecoverState {
|
||||||
RecoverState& operator=(RecoverState const&) = delete;
|
RecoverState& operator=(RecoverState const&) = delete;
|
||||||
|
|
||||||
/// @brief creates the recover state
|
/// @brief creates the recover state
|
||||||
RecoverState(TRI_server_t*, bool);
|
explicit RecoverState(bool);
|
||||||
|
|
||||||
/// @brief destroys the recover state
|
/// @brief destroys the recover state
|
||||||
~RecoverState();
|
~RecoverState();
|
||||||
|
@ -152,7 +154,7 @@ struct RecoverState {
|
||||||
/// @brief fill the secondary indexes of all collections used in recovery
|
/// @brief fill the secondary indexes of all collections used in recovery
|
||||||
int fillIndexes();
|
int fillIndexes();
|
||||||
|
|
||||||
TRI_server_t* server;
|
DatabaseFeature* databaseFeature;
|
||||||
std::unordered_map<TRI_voc_tid_t, std::pair<TRI_voc_tick_t, bool>>
|
std::unordered_map<TRI_voc_tid_t, std::pair<TRI_voc_tick_t, bool>>
|
||||||
failedTransactions;
|
failedTransactions;
|
||||||
std::unordered_set<TRI_voc_cid_t> droppedCollections;
|
std::unordered_set<TRI_voc_cid_t> droppedCollections;
|
||||||
|
|
Loading…
Reference in New Issue