1
0
Fork 0

creating/dropping

This commit is contained in:
Jan Steemann 2013-09-11 17:16:43 +02:00
parent 85362b3c18
commit 3a6cabfe44
32 changed files with 436 additions and 490 deletions

View File

@ -49,8 +49,9 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestActionHandler::RestActionHandler (HttpRequest* request, action_options_t* data)
: RestVocbaseBaseHandler(request, data->_vocbase),
RestActionHandler::RestActionHandler (HttpRequest* request,
action_options_t* data)
: RestVocbaseBaseHandler(request),
_action(0),
_queue(),
_allowed(false) {

View File

@ -98,7 +98,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestActionHandler (rest::HttpRequest*, action_options_t*);
RestActionHandler (rest::HttpRequest*,
action_options_t*);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -32,6 +32,7 @@
#include "Ahuacatl/ahuacatl-parser-functions.h"
#include "Ahuacatl/ahuacatl-scope.h"
#include "Ahuacatl/ahuacatl-variable.h"
#include "VocBase/collection.h"
// -----------------------------------------------------------------------------
// --SECTION-- private macros
@ -481,7 +482,7 @@ TRI_aql_node_t* TRI_CreateNodeCollectionAql (TRI_aql_context_t* const context,
return NULL;
}
else {
if (! TRI_IsAllowedCollectionName(true, name)) {
if (! TRI_IsAllowedNameCollection(true, name)) {
TRI_SetErrorContextAql(context, TRI_ERROR_ARANGO_ILLEGAL_NAME, name);
return NULL;

View File

@ -50,9 +50,8 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestBatchHandler::RestBatchHandler (HttpRequest* request,
TRI_vocbase_t* vocbase)
: RestVocbaseBaseHandler(request, vocbase),
RestBatchHandler::RestBatchHandler (HttpRequest* request)
: RestVocbaseBaseHandler(request),
_partContentType(HttpRequest::getPartContentType()) {
}
@ -185,7 +184,7 @@ Handler::status_e RestBatchHandler::execute() {
}
// inject the request context from the framing (batch) request
this->_server->setRequestContext(request);
this->_server->setRequestContext(request, false);
if (bodyLength > 0) {
LOGGER_TRACE("part body is " << string(bodyStart, bodyLength));

View File

@ -110,7 +110,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestBatchHandler (rest::HttpRequest* request, struct TRI_vocbase_s* vocbase);
RestBatchHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor

View File

@ -56,9 +56,8 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestDocumentHandler::RestDocumentHandler (HttpRequest* request,
TRI_vocbase_t* vocbase)
: RestVocbaseBaseHandler(request, vocbase) {
RestDocumentHandler::RestDocumentHandler (HttpRequest* request)
: RestVocbaseBaseHandler(request) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -67,7 +67,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestDocumentHandler (rest::HttpRequest* request, struct TRI_vocbase_s* vocbase);
RestDocumentHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -53,9 +53,8 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestEdgeHandler::RestEdgeHandler (HttpRequest* request,
TRI_vocbase_t* vocbase)
: RestDocumentHandler(request, vocbase) {
RestEdgeHandler::RestEdgeHandler (HttpRequest* request)
: RestDocumentHandler(request) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -67,7 +67,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestEdgeHandler (rest::HttpRequest* request, struct TRI_vocbase_s* vocbase);
RestEdgeHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -54,9 +54,8 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestImportHandler::RestImportHandler (HttpRequest* request,
TRI_vocbase_t* vocbase)
: RestVocbaseBaseHandler(request, vocbase) {
RestImportHandler::RestImportHandler (HttpRequest* request)
: RestVocbaseBaseHandler(request) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -86,7 +86,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestImportHandler (rest::HttpRequest* request, struct TRI_vocbase_s* vocbase);
RestImportHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -69,9 +69,8 @@ const uint64_t RestReplicationHandler::maxChunkSize = 128 * 1024 * 1024;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestReplicationHandler::RestReplicationHandler (HttpRequest* request,
TRI_vocbase_t* vocbase)
: RestVocbaseBaseHandler(request, vocbase) {
RestReplicationHandler::RestReplicationHandler (HttpRequest* request)
: RestVocbaseBaseHandler(request) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -79,7 +79,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestReplicationHandler (rest::HttpRequest*, struct TRI_vocbase_s*);
RestReplicationHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor

View File

@ -51,8 +51,8 @@ using namespace triagens::arango;
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestUploadHandler::RestUploadHandler (HttpRequest* request, TRI_vocbase_t* vocbase)
: RestVocbaseBaseHandler(request, vocbase) {
RestUploadHandler::RestUploadHandler (HttpRequest* request)
: RestVocbaseBaseHandler(request) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -59,7 +59,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestUploadHandler (rest::HttpRequest* request, struct TRI_vocbase_s* vocbase);
RestUploadHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor

View File

@ -110,15 +110,11 @@ string RestVocbaseBaseHandler::UPLOAD_PATH = "/_api/upload";
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestVocbaseBaseHandler::RestVocbaseBaseHandler (HttpRequest* request,
TRI_vocbase_t* vocbase)
RestVocbaseBaseHandler::RestVocbaseBaseHandler (HttpRequest* request)
: RestBaseHandler(request),
_context(static_cast<VocbaseContext*>(request->getRequestContext())),
_vocbase(_context->getVocbase()),
_resolver(_vocbase) {
// this is to ensure we have not forgotten anything
assert(_vocbase == vocbase);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -132,8 +132,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestVocbaseBaseHandler (rest::HttpRequest*,
struct TRI_vocbase_s*);
RestVocbaseBaseHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor

View File

@ -108,41 +108,34 @@ using namespace triagens::arango;
////////////////////////////////////////////////////////////////////////////////
static void DefineApiHandlers (HttpHandlerFactory* factory,
ApplicationAdminServer* admin,
TRI_vocbase_t* vocbase) {
ApplicationAdminServer* admin) {
// add "/version" handler
admin->addBasicHandlers(factory, "/_api");
// add "/document" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_PATH,
RestHandlerCreator<RestDocumentHandler>::createData<TRI_vocbase_t*>,
vocbase);
RestHandlerCreator<RestDocumentHandler>::createNoData);
// add "/edge" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::EDGE_PATH,
RestHandlerCreator<RestEdgeHandler>::createData<TRI_vocbase_t*>,
vocbase);
RestHandlerCreator<RestEdgeHandler>::createNoData);
// add "/import" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::DOCUMENT_IMPORT_PATH,
RestHandlerCreator<RestImportHandler>::createData<TRI_vocbase_t*>,
vocbase);
RestHandlerCreator<RestImportHandler>::createNoData);
// add "/batch" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::BATCH_PATH,
RestHandlerCreator<RestBatchHandler>::createData<TRI_vocbase_t*>,
vocbase);
RestHandlerCreator<RestBatchHandler>::createNoData);
// add "/replication" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::REPLICATION_PATH,
RestHandlerCreator<RestReplicationHandler>::createData<TRI_vocbase_t*>,
vocbase);
RestHandlerCreator<RestReplicationHandler>::createNoData);
// add "/upload" handler
factory->addPrefixHandler(RestVocbaseBaseHandler::UPLOAD_PATH,
RestHandlerCreator<RestUploadHandler>::createData<TRI_vocbase_t*>,
vocbase);
RestHandlerCreator<RestUploadHandler>::createNoData);
}
////////////////////////////////////////////////////////////////////////////////
@ -150,8 +143,7 @@ static void DefineApiHandlers (HttpHandlerFactory* factory,
////////////////////////////////////////////////////////////////////////////////
static void DefineAdminHandlers (HttpHandlerFactory* factory,
ApplicationAdminServer* admin,
TRI_vocbase_t* vocbase) {
ApplicationAdminServer* admin) {
// add "/version" handler
admin->addBasicHandlers(factory, "/_admin");
@ -174,7 +166,7 @@ static TRI_vocbase_t* LookupDatabaseFromRequest (triagens::rest::HttpRequest* re
requestedName = TRI_VOC_SYSTEM_DATABASE;
}
TRI_vocbase_t* vocbase = TRI_GetDatabaseByNameServer(server, requestedName.c_str());
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer(server, requestedName.c_str());
if (vocbase == 0) {
// database not found
@ -224,7 +216,8 @@ static TRI_vocbase_t* LookupDatabaseFromRequest (triagens::rest::HttpRequest* re
////////////////////////////////////////////////////////////////////////////////
static bool SetRequestContext (triagens::rest::HttpRequest* request,
void* data) {
void* data,
bool manageResources) {
TRI_server_t* server = (TRI_server_t*) data;
TRI_vocbase_t* vocbase = LookupDatabaseFromRequest(request, server);
@ -234,7 +227,7 @@ static bool SetRequestContext (triagens::rest::HttpRequest* request,
return false;
}
request->setRequestContext(new triagens::arango::VocbaseContext(request, server, vocbase));
request->setRequestContext(new triagens::arango::VocbaseContext(request, server, vocbase, manageResources));
return true;
}
@ -638,10 +631,7 @@ void ArangoServer::buildApplicationServer () {
int ArangoServer::startupServer () {
v8::HandleScope scope;
// open all databases
openDatabases();
// .............................................................................
// prepare the various parts of the Arango server
// .............................................................................
@ -650,7 +640,12 @@ int ArangoServer::startupServer () {
_dispatcherThreads = 1;
}
TRI_vocbase_t* vocbase = TRI_GetDatabaseByNameServer(_server, TRI_VOC_SYSTEM_DATABASE);
// open all databases
openDatabases();
// fetch the system database
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);
assert(vocbase != 0);
@ -699,8 +694,8 @@ int ArangoServer::startupServer () {
HttpHandlerFactory* handlerFactory = _applicationEndpointServer->getHandlerFactory();
DefineApiHandlers(handlerFactory, _applicationAdminServer, vocbase);
DefineAdminHandlers(handlerFactory, _applicationAdminServer, vocbase);
DefineApiHandlers(handlerFactory, _applicationAdminServer);
DefineAdminHandlers(handlerFactory, _applicationAdminServer);
// add action handler
handlerFactory->addPrefixHandler(
@ -764,7 +759,7 @@ int ArangoServer::executeConsole (OperationMode::server_operation_mode_e mode) {
openDatabases();
// fetch the system database
TRI_vocbase_t* vocbase = TRI_GetDatabaseByNameServer(_server, TRI_VOC_SYSTEM_DATABASE);
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);
assert(vocbase != 0);
// load authentication
@ -1091,7 +1086,7 @@ int ArangoServer::executeRubyConsole () {
openDatabases();
// fetch the system database
TRI_vocbase_t* vocbase = TRI_GetDatabaseByNameServer(_server, TRI_VOC_SYSTEM_DATABASE);
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);
assert(vocbase != 0);
// load authentication

View File

@ -59,10 +59,12 @@ using namespace triagens::rest;
VocbaseContext::VocbaseContext (HttpRequest* request,
TRI_server_t* server,
TRI_vocbase_t* vocbase) :
TRI_vocbase_t* vocbase,
bool releaseDatabase) :
RequestContext(request),
_server(server),
_vocbase(vocbase) {
_vocbase(vocbase),
_releaseDatabase(releaseDatabase) {
assert(_server != 0);
assert(_vocbase != 0);
@ -73,7 +75,9 @@ VocbaseContext::VocbaseContext (HttpRequest* request,
////////////////////////////////////////////////////////////////////////////////
VocbaseContext::~VocbaseContext () {
if (_releaseDatabase) {
TRI_ReleaseVocBase(_vocbase);
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -80,7 +80,8 @@ namespace triagens {
VocbaseContext (rest::HttpRequest*,
struct TRI_server_s*,
struct TRI_vocbase_s*);
struct TRI_vocbase_s*,
bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
@ -139,11 +140,17 @@ namespace triagens {
struct TRI_server_s* _server;
////////////////////////////////////////////////////////////////////////////////
/// @brief system vocbase
/// @brief the vocbase
////////////////////////////////////////////////////////////////////////////////
struct TRI_vocbase_s* _vocbase;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not to release the database at end
////////////////////////////////////////////////////////////////////////////////
bool _releaseDatabase;
};
}
}

View File

@ -1,171 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief vocbase manager
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "RestServer/VocbaseManager.h"
#include "BasicsC/common.h"
#include "Logger/Logger.h"
#include "Rest/ConnectionInfo.h"
#include "Basics/StringUtils.h"
#include "BasicsC/files.h"
#include "BasicsC/tri-strings.h"
#include "RestServer/VocbaseContext.h"
#include "VocBase/auth.h"
#include "Actions/actions.h"
#include "HttpServer/ApplicationEndpointServer.h"
#include "V8/JSLoader.h"
#include "V8/v8-conv.h"
#include "V8/v8-globals.h"
#include "V8/v8-utils.h"
using namespace std;
using namespace triagens::basics;
using namespace triagens::arango;
using namespace triagens::rest;
// -----------------------------------------------------------------------------
// --SECTION-- public
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ArangoDB
/// @{
////////////////////////////////////////////////////////////////////////////////
/*
////////////////////////////////////////////////////////////////////////////////
/// @brief add an endpoint
////////////////////////////////////////////////////////////////////////////////
bool VocbaseManager::addEndpoint (std::string const& name,
std::vector<std::string> const& databaseNames) {
if (_endpointServer) {
{
WRITE_LOCKER(_rwLock);
_endpoints[name] = databaseNames;
}
return _endpointServer->addEndpoint(name);
}
return false;
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @brief authenticate a request
////////////////////////////////////////////////////////////////////////////////
/*
HttpResponse::HttpResponseCode VocbaseManager::authenticate (TRI_vocbase_t* vocbase,
triagens::rest::HttpRequest* request) {
assert(vocbase != 0);
std::map<TRI_vocbase_t*, std::map<std::string, std::string> >::iterator mapIter;
bool found;
char const* auth = request->header("authorization", found);
if (! found || ! TRI_CaseEqualString2(auth, "basic ", 6)) {
return HttpResponse::UNAUTHORIZED;
}
// skip over "basic "
auth += 6;
while (*auth == ' ') {
++auth;
}
{
READ_LOCKER(_rwLock);
mapIter = _authCache.find(vocbase);
if (mapIter == _authCache.end()) {
// unknown vocbase
return HttpResponse::NOT_FOUND;
}
map<string, string>::iterator i = mapIter->second.find(auth);
if (i != mapIter->second.end()) {
request->setUser(i->second);
return HttpResponse::OK;
}
}
string up = StringUtils::decodeBase64(auth);
std::string::size_type n = up.find(':', 0);
if (n == std::string::npos || n == 0 || n + 1 > up.size()) {
LOGGER_TRACE("invalid authentication data found, cannot extract username/password");
return HttpResponse::BAD;
}
const string username = up.substr(0, n);
LOGGER_TRACE("checking authentication for user '" << username << "'");
bool res = TRI_CheckAuthenticationAuthInfo2(vocbase, username.c_str(), up.substr(n + 1).c_str());
if (! res) {
return HttpResponse::UNAUTHORIZED;
}
WRITE_LOCKER(_rwLock);
mapIter = _authCache.find(vocbase);
if (mapIter == _authCache.end()) {
// unknown vocbase
return HttpResponse::UNAUTHORIZED;
}
mapIter->second[auth] = username;
request->setUser(username);
// TODO: create a user object for the VocbaseContext
return HttpResponse::OK;
}
*/
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:

View File

@ -6970,7 +6970,7 @@ static v8::Handle<v8::Value> MapGetVocBase (v8::Local<v8::String> name,
if ( key == "toString"
|| key == "toJSON"
|| key == "hasOwnProperty" // this prevents calling the property getter again (i.e. recursion!)
|| TRI_IsSystemCollectionName(key.c_str())) { // hide system collections
|| TRI_IsSystemNameCollection(key.c_str())) { // hide system collections
return scope.Close(v8::Handle<v8::Value>());
}
@ -7631,7 +7631,11 @@ static v8::Handle<v8::Value> JS_IsSystemDatabase (v8::Arguments const& argv) {
TRI_vocbase_t* vocbase = GetContextVocBase();
return scope.Close(v8::Boolean::New(vocbase->_isSystem));
if (vocbase == 0) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
return scope.Close(v8::Boolean::New(TRI_IsSystemVocBase(vocbase)));
}
////////////////////////////////////////////////////////////////////////////////
@ -7659,10 +7663,16 @@ static v8::Handle<v8::Value> JS_UseDatabase (v8::Arguments const& argv) {
const string name = TRI_ObjectToString(argv[0]);
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
TRI_vocbase_t* vocbase = TRI_GetDatabaseByNameServer((TRI_server_t*) v8g->_server, name.c_str());
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer((TRI_server_t*) v8g->_server, name.c_str());
if (vocbase != 0) {
// switch databases
void* orig = v8g->_vocbase;
assert(orig != 0);
v8g->_vocbase = vocbase;
TRI_ReleaseDatabaseServer((TRI_server_t*) v8g->_server, (TRI_vocbase_t*) orig);
return scope.Close(WrapVocBase(vocbase));
}
@ -7730,7 +7740,7 @@ static v8::Handle<v8::Value> JS_CreateDatabase (v8::Arguments const& argv) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (! vocbase->_isSystem) {
if (! TRI_IsSystemVocBase(vocbase)) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
}
@ -7805,8 +7815,11 @@ static v8::Handle<v8::Value> JS_CreateDatabase (v8::Arguments const& argv) {
// version check failed
// TODO: report an error
}
// finally decrease the reference-counter
TRI_ReleaseVocBase(database);
return scope.Close(WrapVocBase(database));
return scope.Close(v8::True());
}
////////////////////////////////////////////////////////////////////////////////
@ -7835,7 +7848,7 @@ static v8::Handle<v8::Value> JS_DropDatabase (v8::Arguments const& argv) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (! vocbase->_isSystem) {
if (! TRI_IsSystemVocBase(vocbase)) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
}
@ -7872,7 +7885,7 @@ static v8::Handle<v8::Value> JS_AddEndpoint (v8::Arguments const& argv) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (! vocbase->_isSystem) {
if (! TRI_IsSystemVocBase(vocbase)) {
TRI_V8_EXCEPTION(scope, TRI_ERROR_ARANGO_USE_SYSTEM_DATABASE);
}
@ -8524,7 +8537,7 @@ void TRI_InitV8VocBridge (v8::Handle<v8::Context> context,
// register the server
v8g->_server = server;
// set the default database
// register the database
v8g->_vocbase = vocbase;
// register the startup loader

View File

@ -1434,7 +1434,7 @@ int TRI_LoadCollectionInfo (char const* path,
if (TRI_EqualString(key->_value._string.data, "name")) {
TRI_CopyString(parameter->_name, value->_value._string.data, sizeof(parameter->_name));
parameter->_isSystem = TRI_IsSystemCollectionName(parameter->_name);
parameter->_isSystem = TRI_IsSystemNameCollection(parameter->_name);
}
else if (TRI_EqualString(key->_value._string.data, "cid")) {
parameter->_cid = (TRI_voc_cid_t) TRI_UInt64String(value->_value._string.data);
@ -2130,7 +2130,7 @@ bool TRI_IterateTicksCollection (const char* const path,
/// @brief determine whether a collection name is a system collection name
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsSystemCollectionName (char const* name) {
bool TRI_IsSystemNameCollection (char const* name) {
if (name == NULL) {
return false;
}
@ -2138,6 +2138,47 @@ bool TRI_IsSystemCollectionName (char const* name) {
return *name == '_';
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a collection name is allowed
///
/// Returns true if the name is allowed and false otherwise
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedNameCollection (bool allowSystem,
char const* name) {
bool ok;
char const* ptr;
size_t length = 0;
// check allow characters: must start with letter or underscore if system is allowed
for (ptr = name; *ptr; ++ptr) {
if (length == 0) {
if (allowSystem) {
ok = (*ptr == '_') || ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
}
else {
ok = ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
}
}
else {
ok = (*ptr == '_') || (*ptr == '-') || ('0' <= *ptr && *ptr <= '9') || ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
}
if (! ok) {
return false;
}
++length;
}
// invalid name length
if (length == 0 || length > TRI_COL_NAME_LENGTH) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the type name for a collection
////////////////////////////////////////////////////////////////////////////////

View File

@ -503,7 +503,14 @@ bool TRI_IterateTicksCollection (const char* const,
/// @brief determine whether a collection name is a system collection name
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsSystemCollectionName (char const*);
bool TRI_IsSystemNameCollection (char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a collection name is allowed
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedNameCollection (bool,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the type name for a collection

View File

@ -595,6 +595,14 @@ static int OpenDatabases (TRI_server_t* server) {
if (TRI_IsBooleanJson(deletedJson)) {
if (deletedJson->_value._boolean) {
// database is deleted, skip it!
LOG_INFO("found dropped database in directory '%s'",
databaseDirectory);
LOG_INFO("removing superfluous database directory '%s'",
databaseDirectory);
TRI_RemoveDirectory(databaseDirectory);
TRI_FreeString(TRI_CORE_MEM_ZONE, databaseDirectory);
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
continue;
@ -712,7 +720,7 @@ static int CloseDatabases (TRI_server_t* server) {
TRI_vocbase_t* vocbase = server->_databases._table[i];
if (vocbase != NULL) {
TRI_DestroyVocBase(vocbase, NULL);
TRI_DestroyVocBase(vocbase);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, vocbase);
// clear to avoid potential double freeing
@ -1535,7 +1543,7 @@ int TRI_CreateDatabaseServer (TRI_server_t* server,
int res;
size_t i, n;
if (! TRI_IsAllowedDatabaseName(false, name)) {
if (! TRI_IsAllowedNameVocBase(false, name)) {
return TRI_ERROR_ARANGO_DATABASE_NAME_INVALID;
}
@ -1573,6 +1581,10 @@ int TRI_CreateDatabaseServer (TRI_server_t* server,
path = TRI_Concatenate2File(server->_databasePath, file);
TRI_FreeString(TRI_CORE_MEM_ZONE, file);
LOG_INFO("creating database '%s', directory '%s'",
name,
path);
vocbase = TRI_OpenVocBase(server, path, tick, name, defaults, false);
TRI_FreeString(TRI_CORE_MEM_ZONE, path);
@ -1597,6 +1609,9 @@ int TRI_CreateDatabaseServer (TRI_server_t* server,
assert(vocbase != NULL);
// increase reference counter
TRI_UseVocBase(vocbase);
TRI_WriteLockReadWriteLock(&server->_lock);
TRI_InsertKeyAssociativePointer(&server->_databases, vocbase->_name, vocbase, false);
TRI_WriteUnlockReadWriteLock(&server->_lock);
@ -1618,40 +1633,96 @@ int TRI_DropDatabaseServer (TRI_server_t* server,
int res;
if (TRI_EqualString(name, TRI_VOC_SYSTEM_DATABASE)) {
// prevent deletion of system database
return TRI_ERROR_FORBIDDEN;
}
TRI_WriteLockReadWriteLock(&server->_lock);
vocbase = TRI_RemoveKeyAssociativePointer(&server->_databases, name);
if (vocbase == NULL) {
// not found
res = TRI_ERROR_ARANGO_DATABASE_NOT_FOUND;
}
else {
res = SaveDatabaseParameters(vocbase->_id, name, true, &server->_defaults, vocbase->_path);
// TODO FIXME: perform actual drop
// mark as deleted
if (TRI_DropVocBase(vocbase)) {
res = SaveDatabaseParameters(vocbase->_id,
vocbase->_name,
true,
&vocbase->_settings,
vocbase->_path);
}
else {
// already deleted
res = TRI_ERROR_ARANGO_DATABASE_NOT_FOUND;
}
}
TRI_WriteUnlockReadWriteLock(&server->_lock);
// move perform the actual deletion
if (vocbase != NULL) {
char* path;
// we are allowed to drop the database
while (TRI_IsUsedVocBase(vocbase)) {
// cycle until there are no more references to the database
usleep(500 * 1000);
}
// remember the database path
path = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, vocbase->_path);
TRI_DestroyVocBase(vocbase);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, vocbase);
// remove directory
TRI_RemoveDirectory(path);
TRI_FreeString(TRI_CORE_MEM_ZONE, path);
}
return res;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get a database by its name
/// this will increase the reference-counter for the database
////////////////////////////////////////////////////////////////////////////////
TRI_vocbase_t* TRI_GetDatabaseByNameServer (TRI_server_t* server,
char const* name) {
TRI_vocbase_t* TRI_UseDatabaseServer (TRI_server_t* server,
char const* name) {
TRI_vocbase_t* vocbase;
TRI_ReadLockReadWriteLock(&server->_lock);
vocbase = TRI_LookupByKeyAssociativePointer(&server->_databases, name);
if (vocbase != NULL) {
bool result = TRI_UseVocBase(vocbase);
// if we got here, no one else can have deleted the database
assert(result == true);
}
TRI_ReadUnlockReadWriteLock(&server->_lock);
return vocbase;
}
////////////////////////////////////////////////////////////////////////////////
/// @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 database names
////////////////////////////////////////////////////////////////////////////////

View File

@ -180,11 +180,20 @@ int TRI_DropDatabaseServer (TRI_server_t*,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief get a database by its name
/// @brief use a database by its name
/// this will increase the reference-counter for the database
////////////////////////////////////////////////////////////////////////////////
struct TRI_vocbase_s* TRI_GetDatabaseByNameServer (TRI_server_t*,
char const*);
struct TRI_vocbase_s* TRI_UseDatabaseServer (TRI_server_t*,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief release a previously used database
/// this will decrease the reference-counter for the database
////////////////////////////////////////////////////////////////////////////////
void TRI_ReleaseDatabaseServer (TRI_server_t*,
struct TRI_vocbase_s*);
////////////////////////////////////////////////////////////////////////////////
/// @brief return the list of all database names

View File

@ -533,7 +533,7 @@ static TRI_vocbase_col_t* AddCollection (TRI_vocbase_t* vocbase,
init._canUnload = true;
// check for special system collection names
if (TRI_IsSystemCollectionName(name)) {
if (TRI_IsSystemNameCollection(name)) {
// a few system collections have special behavior
if (TRI_EqualString(name, TRI_COL_NAME_ENDPOINTS) ||
TRI_EqualString(name, TRI_COL_NAME_REPLICATION) ||
@ -828,10 +828,6 @@ static int LoadCollectionVocBase (TRI_vocbase_t* vocbase,
TRI_vocbase_col_t* collection) {
TRI_col_type_e type;
if (! TRI_CanUseVocBase(vocbase)) {
return TRI_ERROR_ARANGO_DATABASE_NOT_FOUND;
}
// .............................................................................
// read lock
// .............................................................................
@ -1057,100 +1053,6 @@ void TRI_FreeCollectionsVocBase (TRI_vector_pointer_t* collections) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns whether or not the vocbase can be used
////////////////////////////////////////////////////////////////////////////////
bool TRI_CanUseVocBase (TRI_vocbase_t* vocbase) {
bool canUse;
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
canUse = vocbase->_canUse;
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return canUse;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a collection name is allowed
///
/// Returns true if the name is allowed and false otherwise
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedCollectionName (bool allowSystem, char const* name) {
bool ok;
char const* ptr;
size_t length = 0;
// check allow characters: must start with letter or underscore if system is allowed
for (ptr = name; *ptr; ++ptr) {
if (length == 0) {
if (allowSystem) {
ok = (*ptr == '_') || ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
}
else {
ok = ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
}
}
else {
ok = (*ptr == '_') || (*ptr == '-') || ('0' <= *ptr && *ptr <= '9') || ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
}
if (! ok) {
return false;
}
++length;
}
// invalid name length
if (length == 0 || length > TRI_COL_NAME_LENGTH) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a database name is allowed
///
/// Returns true if the name is allowed and false otherwise
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedDatabaseName (bool allowSystem, char const* name) {
bool ok;
char const* ptr;
size_t length = 0;
// check allow characters: must start with letter or underscore if system is allowed
for (ptr = name; *ptr; ++ptr) {
if (length == 0) {
if (allowSystem) {
ok = (*ptr == '_') || ('a' <= *ptr && *ptr <= 'z');
}
else {
ok = ('a' <= *ptr && *ptr <= 'z');
}
}
else {
ok = (*ptr == '_') || (*ptr == '-') || ('0' <= *ptr && *ptr <= '9') || ('a' <= *ptr && *ptr <= 'z');
}
if (! ok) {
return false;
}
++length;
}
// invalid name length
if (length == 0 || length > TRI_COL_NAME_LENGTH) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
@ -1197,7 +1099,6 @@ TRI_vocbase_t* TRI_OpenVocBase (TRI_server_t* server,
vocbase->_path = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, path);
vocbase->_name = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, name);
vocbase->_authInfoLoaded = false;
vocbase->_isSystem = TRI_EqualString(name, TRI_VOC_SYSTEM_DATABASE);
// use the defaults provided
TRI_ApplyVocBaseDefaults(vocbase, defaults);
@ -1227,6 +1128,10 @@ TRI_vocbase_t* TRI_OpenVocBase (TRI_server_t* server,
return NULL;
}
// init usage info
TRI_InitSpin(&vocbase->_usage._lock);
vocbase->_usage._refCount = 0;
vocbase->_usage._isDeleted = false;
TRI_InitCompactorVocBase(vocbase);
@ -1256,7 +1161,6 @@ TRI_vocbase_t* TRI_OpenVocBase (TRI_server_t* server,
NULL);
TRI_InitReadWriteLock(&vocbase->_inventoryLock);
TRI_InitReadWriteLock(&vocbase->_authInfoLock);
TRI_InitReadWriteLock(&vocbase->_lock);
vocbase->_authInfoFlush = true;
@ -1288,6 +1192,7 @@ TRI_vocbase_t* TRI_OpenVocBase (TRI_server_t* server,
TRI_FreeShadowStore(vocbase->_cursors);
TRI_DestroyReadWriteLock(&vocbase->_authInfoLock);
TRI_DestroyReadWriteLock(&vocbase->_lock);
TRI_DestroySpin(&vocbase->_usage._lock);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, vocbase);
TRI_set_errno(res);
@ -1365,8 +1270,6 @@ TRI_vocbase_t* TRI_OpenVocBase (TRI_server_t* server,
}
}
vocbase->_canUse = true;
// we are done
return vocbase;
}
@ -1375,8 +1278,7 @@ TRI_vocbase_t* TRI_OpenVocBase (TRI_server_t* server,
/// @brief closes a database and all collections
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyVocBase (TRI_vocbase_t* vocbase,
TRI_vector_pointer_t* reuseCollections) {
void TRI_DestroyVocBase (TRI_vocbase_t* vocbase) {
TRI_vector_pointer_t collections;
size_t i;
@ -1384,7 +1286,6 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase,
TRI_WRITE_LOCK_COLLECTIONS_VOCBASE(vocbase);
// cannot use this vocbase from now on
vocbase->_canUse = false;
TRI_CopyDataVectorPointer(&collections, &vocbase->_collections);
TRI_WRITE_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
@ -1434,9 +1335,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase,
collection = (TRI_vocbase_col_t*) vocbase->_deadCollections._buffer[i];
if (vocbase->_isSystem) {
TRI_FreeCollectionVocBase(collection);
}
TRI_FreeCollectionVocBase(collection);
}
// free collections
@ -1445,15 +1344,7 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase,
collection = (TRI_vocbase_col_t*) vocbase->_collections._buffer[i];
if (reuseCollections != 0) {
// the pointer to the collection is transferred to the other vector,
// which is then responsible to free the collection later
TRI_PushBackVectorPointer(reuseCollections, collection);
}
else {
// instantly free the collection
TRI_FreeCollectionVocBase(collection);
}
TRI_FreeCollectionVocBase(collection);
}
// free the auth info
@ -1474,17 +1365,17 @@ void TRI_DestroyVocBase (TRI_vocbase_t* vocbase,
// free the cursors
TRI_FreeShadowStore(vocbase->_cursors);
// destroy locks
TRI_DestroySpin(&vocbase->_usage._lock);
TRI_DestroyReadWriteLock(&vocbase->_inventoryLock);
TRI_DestroyReadWriteLock(&vocbase->_authInfoLock);
TRI_DestroyReadWriteLock(&vocbase->_lock);
TRI_DestroyCondition(&vocbase->_syncWaitersCondition);
TRI_DestroyCondition(&vocbase->_cleanupCondition);
// free the filename path
// free name and path
TRI_Free(TRI_CORE_MEM_ZONE, vocbase->_path);
TRI_Free(TRI_CORE_MEM_ZONE, vocbase->_name);
}
@ -1633,11 +1524,6 @@ char* TRI_GetCollectionNameByIdVocBase (TRI_vocbase_t* vocbase,
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
if (! vocbase->_canUse) {
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return NULL;
}
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id));
if (found == NULL) {
@ -1669,12 +1555,7 @@ TRI_vocbase_col_t* TRI_LookupCollectionByNameVocBase (TRI_vocbase_t* vocbase,
// otherwise we'll look up the collection by name
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
if (vocbase->_canUse) {
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name));
}
else {
found = NULL;
}
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name));
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found;
@ -1688,12 +1569,7 @@ TRI_vocbase_col_t* TRI_LookupCollectionByIdVocBase (TRI_vocbase_t* vocbase, TRI_
TRI_vocbase_col_t* found;
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
if (vocbase->_canUse) {
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id));
}
else {
found = NULL;
}
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsById, &id));
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
return found;
@ -1710,12 +1586,7 @@ TRI_vocbase_col_t* TRI_FindCollectionByNameOrCreateVocBase (TRI_vocbase_t* vocba
TRI_vocbase_col_t* found;
TRI_READ_LOCK_COLLECTIONS_VOCBASE(vocbase);
if (vocbase->_canUse) {
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name));
}
else {
found = NULL;
}
found = CONST_CAST(TRI_LookupByKeyAssociativePointer(&vocbase->_collectionsByName, name));
TRI_READ_UNLOCK_COLLECTIONS_VOCBASE(vocbase);
if (found != NULL) {
@ -1765,17 +1636,12 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase,
name = parameter->_name;
// check that the name does not contain any strange characters
if (! TRI_IsAllowedCollectionName(parameter->_isSystem, name)) {
if (! TRI_IsAllowedNameCollection(parameter->_isSystem, name)) {
TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
return NULL;
}
if (! TRI_CanUseVocBase(vocbase)) {
TRI_set_errno(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
return NULL;
}
type = (TRI_col_type_e) parameter->_type;
if (! TRI_IS_DOCUMENT_COLLECTION(type)) {
@ -1944,10 +1810,6 @@ int TRI_DropCollectionVocBase (TRI_vocbase_t* vocbase,
TRI_server_id_t generatingServer) {
int res;
if (! TRI_CanUseVocBase(vocbase)) {
return TRI_set_errno(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (! collection->_canDrop) {
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
}
@ -2092,10 +1954,6 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase,
char* oldName;
int res;
if (! TRI_CanUseVocBase(vocbase)) {
return TRI_set_errno(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
if (! collection->_canRename) {
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
}
@ -2120,22 +1978,22 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase,
if (! override) {
bool isSystem;
isSystem = TRI_IsSystemCollectionName(oldName);
isSystem = TRI_IsSystemNameCollection(oldName);
if (isSystem && ! TRI_IsSystemCollectionName(newName)) {
if (isSystem && ! TRI_IsSystemNameCollection(newName)) {
// a system collection shall not be renamed to a non-system collection name
TRI_FreeString(TRI_CORE_MEM_ZONE, oldName);
return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
}
else if (! isSystem && TRI_IsSystemCollectionName(newName)) {
else if (! isSystem && TRI_IsSystemNameCollection(newName)) {
// a non-system collection shall not be renamed to a system collection name
TRI_FreeString(TRI_CORE_MEM_ZONE, oldName);
return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
}
if (! TRI_IsAllowedCollectionName(isSystem, newName)) {
if (! TRI_IsAllowedNameCollection(isSystem, newName)) {
TRI_FreeString(TRI_CORE_MEM_ZONE, oldName);
return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME);
@ -2359,6 +2217,119 @@ void TRI_ReleaseCollectionVocBase (TRI_vocbase_t* vocbase,
TRI_READ_UNLOCK_STATUS_VOCBASE_COL(collection);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief increase the reference counter for a database
////////////////////////////////////////////////////////////////////////////////
bool TRI_UseVocBase (TRI_vocbase_t* vocbase) {
bool result;
TRI_LockSpin(&vocbase->_usage._lock);
if (vocbase->_usage._isDeleted) {
result = false;
}
else {
++vocbase->_usage._refCount;
result = true;
}
TRI_UnlockSpin(&vocbase->_usage._lock);
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief decrease the reference counter for a database
////////////////////////////////////////////////////////////////////////////////
void TRI_ReleaseVocBase (TRI_vocbase_t* vocbase) {
TRI_LockSpin(&vocbase->_usage._lock);
--vocbase->_usage._refCount;
TRI_UnlockSpin(&vocbase->_usage._lock);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief marks a database as deleted
////////////////////////////////////////////////////////////////////////////////
bool TRI_DropVocBase (TRI_vocbase_t* vocbase) {
bool result;
TRI_LockSpin(&vocbase->_usage._lock);
if (vocbase->_usage._isDeleted) {
result = false;
}
else {
vocbase->_usage._isDeleted = true;
result = true;
}
TRI_UnlockSpin(&vocbase->_usage._lock);
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns whether any references are held on a database
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsUsedVocBase (TRI_vocbase_t* vocbase) {
bool result;
TRI_LockSpin(&vocbase->_usage._lock);
result = (vocbase->_usage._refCount > 0);
TRI_UnlockSpin(&vocbase->_usage._lock);
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns whether the database is the system database
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsSystemVocBase (TRI_vocbase_t* vocbase) {
return TRI_EqualString(vocbase->_name, TRI_VOC_SYSTEM_DATABASE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a database name is allowed
///
/// Returns true if the name is allowed and false otherwise
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedNameVocBase (bool allowSystem,
char const* name) {
bool ok;
char const* ptr;
size_t length = 0;
// check allow characters: must start with letter or underscore if system is allowed
for (ptr = name; *ptr; ++ptr) {
if (length == 0) {
if (allowSystem) {
ok = (*ptr == '_') || ('a' <= *ptr && *ptr <= 'z');
}
else {
ok = ('a' <= *ptr && *ptr <= 'z');
}
}
else {
ok = (*ptr == '_') || (*ptr == '-') || ('0' <= *ptr && *ptr <= '9') || ('a' <= *ptr && *ptr <= 'z');
}
if (! ok) {
return false;
}
++length;
}
// invalid name length
if (length == 0 || length > TRI_COL_NAME_LENGTH) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -318,11 +318,15 @@ struct TRI_vocbase_defaults_s;
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_vocbase_s {
TRI_voc_tick_t _id;
char* _path; // path to the data directory
TRI_voc_tick_t _id; // internal database id
char* _path; // path to the data directory
char* _name; // database name
bool _canUse; // this is set to false during deletion of a database
bool _isSystem;
struct {
TRI_spin_t _lock; // a lock protecting the usage information
uint32_t _refCount; // reference counter
bool _isDeleted; // flag if database is marked as deleted
} _usage;
TRI_vocbase_defaults_t _settings;
@ -441,39 +445,6 @@ void TRI_FreeCollectionVocBase (TRI_vocbase_col_t*);
void TRI_FreeCollectionsVocBase (struct TRI_vector_pointer_s*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns whether or not the vocbase can be used
////////////////////////////////////////////////////////////////////////////////
bool TRI_CanUseVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a collection name is allowed
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedCollectionName (bool,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a database name is allowed
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedDatabaseName (bool,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup VocBase
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief opens an existing database, loads all collections
////////////////////////////////////////////////////////////////////////////////
@ -489,8 +460,7 @@ TRI_vocbase_t* TRI_OpenVocBase (struct TRI_server_s*,
/// @brief closes a database and all collections
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyVocBase (TRI_vocbase_t*,
struct TRI_vector_pointer_s*);
void TRI_DestroyVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief load authentication information
@ -621,6 +591,43 @@ TRI_vocbase_col_t* TRI_UseCollectionByNameVocBase (TRI_vocbase_t*,
void TRI_ReleaseCollectionVocBase (TRI_vocbase_t*,
TRI_vocbase_col_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief increase the reference counter for a database
////////////////////////////////////////////////////////////////////////////////
bool TRI_UseVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief decrease the reference counter for a database
////////////////////////////////////////////////////////////////////////////////
void TRI_ReleaseVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief marks a database as deleted
////////////////////////////////////////////////////////////////////////////////
bool TRI_DropVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns whether any references are held on a database
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsUsedVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns whether the database is the system database
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsSystemVocBase (TRI_vocbase_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a database name is allowed
////////////////////////////////////////////////////////////////////////////////
bool TRI_IsAllowedNameVocBase (bool,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

View File

@ -100,18 +100,26 @@ function get_api_database (req, res) {
///
/// @RESTRETURNCODE{400}
/// is returned if the request parameters are invalid or if a database with the
/// specified name or path already exists.
/// specified name already exists. If the request is carried out from any other
/// database than the `_system` database, this error will be returned, too.
///
/// @EXAMPLES
///
/// @EXAMPLE_ARANGOSH_RUN{RestDatabaseCreate}
/// var url = "/_api/database";
/// var name = "example";
/// try {
/// db._dropDatabase(name);
/// }
/// catch (err) {
/// }
///
/// var data = {
/// name: "example"
/// name: name
/// };
/// var response = logCurlRequest('POST', url, JSON.stringify(data));
///
/// db._dropDatabase("example");
/// db._dropDatabase(name);
/// assert(response.code === 200);
///
/// logJsonResponse(response);
@ -142,7 +150,7 @@ function post_api_database (req, res) {
return;
}
var result = arangodb.db._createDatabase(json.name || "", json.path || "", options);
var result = arangodb.db._createDatabase(json.name || "", options);
actions.resultOk(req, res, actions.HTTP_OK, { result : result });
}
@ -168,6 +176,10 @@ function post_api_database (req, res) {
/// @RESTRETURNCODE{200}
/// is returned if the database was dropped successfully.
///
/// @RESTRETURNCODE{400}
/// is returned if the request is carried out from any other database than the
/// `_system` database.
///
/// @RESTRETURNCODE{404}
/// is returned if the database could not be found.
///
@ -175,8 +187,9 @@ function post_api_database (req, res) {
///
/// @EXAMPLE_ARANGOSH_RUN{RestDatabaseDrop}
/// var url = "/_api/database";
/// db._createDatabase("example");
/// var response = logCurlRequest('DELETE', url + "/test");
/// var name = "example";
/// db._createDatabase(name);
/// var response = logCurlRequest('DELETE', url + '/' + name);
///
/// assert(response.code === 200);
///
@ -190,7 +203,7 @@ function delete_api_database (req, res) {
return;
}
var result = arangodb.db._deleteDatabase(req.suffix[0]);
var result = arangodb.db._dropDatabase(req.suffix[0]);
actions.resultOk(req, res, actions.HTTP_OK, { result : result });
}

View File

@ -67,7 +67,7 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestAdminLogHandler (rest::HttpRequest* request);
RestAdminLogHandler (rest::HttpRequest*);
////////////////////////////////////////////////////////////////////////////////
/// @}

View File

@ -116,16 +116,6 @@ HttpHandlerFactory::~HttpHandlerFactory () {
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief flush the authentication cache
////////////////////////////////////////////////////////////////////////////////
void HttpHandlerFactory::flushAuthentication () {
WRITE_LOCKER(_authLock);
_authCache.clear();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns header and body size restrictions
////////////////////////////////////////////////////////////////////////////////
@ -147,7 +137,7 @@ HttpResponse::HttpResponseCode HttpHandlerFactory::authenticateRequest (HttpRequ
RequestContext* rc = request->getRequestContext();
if (rc == 0) {
if (! setRequestContext(request)) {
if (! setRequestContext(request, true)) {
return HttpResponse::NOT_FOUND;
}
@ -163,8 +153,9 @@ HttpResponse::HttpResponseCode HttpHandlerFactory::authenticateRequest (HttpRequ
/// @brief set request context, wrapper method
////////////////////////////////////////////////////////////////////////////////
bool HttpHandlerFactory::setRequestContext (HttpRequest* request) {
return _setContext(request, _setContextData);
bool HttpHandlerFactory::setRequestContext (HttpRequest* request,
bool manageResources) {
return _setContext(request, _setContextData, manageResources);
}
////////////////////////////////////////////////////////////////////////////////
@ -191,7 +182,7 @@ HttpRequest* HttpHandlerFactory::createRequest (ConnectionInfo const& info,
#endif
HttpRequest* request = new HttpRequest(info, ptr, length);
setRequestContext(request);
setRequestContext(request, true);
return request;
}

View File

@ -104,7 +104,7 @@ namespace triagens {
/// @brief context handler
////////////////////////////////////////////////////////////////////////////////
typedef bool (*context_fptr) (HttpRequest*, void*);
typedef bool (*context_fptr) (HttpRequest*, void*, bool);
////////////////////////////////////////////////////////////////////////////////
/// @}
@ -162,12 +162,6 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief flush the authentication cache
////////////////////////////////////////////////////////////////////////////////
void flushAuthentication ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns header and body size restrictions
////////////////////////////////////////////////////////////////////////////////
@ -184,7 +178,8 @@ namespace triagens {
/// @brief set request context, wrapper method
////////////////////////////////////////////////////////////////////////////////
virtual bool setRequestContext (HttpRequest*);
virtual bool setRequestContext (HttpRequest*,
bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the authentication realm