mirror of https://gitee.com/bigwinds/arangodb
allow dropping system collections in some rare cases
This commit is contained in:
parent
bbb2cfabdc
commit
396ab41736
|
@ -1757,7 +1757,7 @@ int InitialSyncer::handleCollection(VPackSlice const& parameters,
|
||||||
// regular collection
|
// regular collection
|
||||||
setProgress("dropping " + collectionMsg);
|
setProgress("dropping " + collectionMsg);
|
||||||
|
|
||||||
int res = _vocbase->dropCollection(col, true);
|
int res = _vocbase->dropCollection(col, true, true);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
errorMsg = "unable to drop " + collectionMsg + ": " +
|
errorMsg = "unable to drop " + collectionMsg + ": " +
|
||||||
|
|
|
@ -527,7 +527,7 @@ int Syncer::dropCollection(VPackSlice const& slice, bool reportError) {
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _vocbase->dropCollection(col, true);
|
return _vocbase->dropCollection(col, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1572,7 +1572,7 @@ int RestReplicationHandler::processRestoreCollection(
|
||||||
// drop an existing collection if it exists
|
// drop an existing collection if it exists
|
||||||
if (col != nullptr) {
|
if (col != nullptr) {
|
||||||
if (dropExisting) {
|
if (dropExisting) {
|
||||||
int res = _vocbase->dropCollection(col, true);
|
int res = _vocbase->dropCollection(col, true, true);
|
||||||
|
|
||||||
if (res == TRI_ERROR_FORBIDDEN) {
|
if (res == TRI_ERROR_FORBIDDEN) {
|
||||||
// some collections must not be dropped
|
// some collections must not be dropped
|
||||||
|
|
|
@ -1200,7 +1200,7 @@ std::string MMFilesEngine::collectionDirectory(TRI_voc_tick_t databaseId, TRI_vo
|
||||||
auto it = _collectionPaths.find(databaseId);
|
auto it = _collectionPaths.find(databaseId);
|
||||||
|
|
||||||
if (it == _collectionPaths.end()) {
|
if (it == _collectionPaths.end()) {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "trying to determine directory for unknown collection");
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "trying to determine directory for unknown database");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it2 = (*it).second.find(id);
|
auto it2 = (*it).second.find(id);
|
||||||
|
@ -1357,7 +1357,7 @@ void MMFilesEngine::unregisterCollectionPath(TRI_voc_tick_t databaseId, TRI_voc_
|
||||||
if (it == _collectionPaths.end()) {
|
if (it == _collectionPaths.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(*it).second.erase(id);
|
// (*it).second.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMFilesEngine::saveCollectionInfo(TRI_vocbase_t* vocbase,
|
void MMFilesEngine::saveCollectionInfo(TRI_vocbase_t* vocbase,
|
||||||
|
|
|
@ -843,7 +843,22 @@ static void JS_DropVocbaseCol(v8::FunctionCallbackInfo<v8::Value> const& args) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = collection->vocbase()->dropCollection(collection, true);
|
bool allowDropSystem = false;
|
||||||
|
if (args.Length() > 0) {
|
||||||
|
// options
|
||||||
|
if (args[0]->IsObject()) {
|
||||||
|
TRI_GET_GLOBALS();
|
||||||
|
v8::Handle<v8::Object> optionsObject = args[0].As<v8::Object>();
|
||||||
|
TRI_GET_GLOBAL_STRING(IsSystemKey);
|
||||||
|
if (optionsObject->Has(IsSystemKey)) {
|
||||||
|
allowDropSystem = TRI_ObjectToBoolean(optionsObject->Get(IsSystemKey));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allowDropSystem = TRI_ObjectToBoolean(args[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = collection->vocbase()->dropCollection(collection, allowDropSystem, true);
|
||||||
|
|
||||||
if (res != TRI_ERROR_NO_ERROR) {
|
if (res != TRI_ERROR_NO_ERROR) {
|
||||||
TRI_V8_THROW_EXCEPTION_MESSAGE(res, "cannot drop collection");
|
TRI_V8_THROW_EXCEPTION_MESSAGE(res, "cannot drop collection");
|
||||||
|
|
|
@ -915,11 +915,13 @@ int TRI_vocbase_t::unloadCollection(arangodb::LogicalCollection* collection, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief drops a collection
|
/// @brief drops a collection
|
||||||
int TRI_vocbase_t::dropCollection(arangodb::LogicalCollection* collection, bool writeMarker) {
|
int TRI_vocbase_t::dropCollection(arangodb::LogicalCollection* collection, bool allowDropSystem, bool writeMarker) {
|
||||||
TRI_ASSERT(collection != nullptr);
|
TRI_ASSERT(collection != nullptr);
|
||||||
|
|
||||||
if (collection->isSystem() &&
|
if (!allowDropSystem &&
|
||||||
|
collection->isSystem() &&
|
||||||
!arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
!arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
||||||
|
// prevent dropping of system collections
|
||||||
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
|
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,7 +315,7 @@ struct TRI_vocbase_t {
|
||||||
bool writeMarker);
|
bool writeMarker);
|
||||||
|
|
||||||
/// @brief drops a collection
|
/// @brief drops a collection
|
||||||
int dropCollection(arangodb::LogicalCollection* collection, bool writeMarker);
|
int dropCollection(arangodb::LogicalCollection* collection, bool allowDropSystem, bool writeMarker);
|
||||||
|
|
||||||
/// @brief callback for collection dropping
|
/// @brief callback for collection dropping
|
||||||
static bool DropCollectionCallback(arangodb::LogicalCollection* collection);
|
static bool DropCollectionCallback(arangodb::LogicalCollection* collection);
|
||||||
|
|
|
@ -597,7 +597,7 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
if (other != nullptr) {
|
if (other != nullptr) {
|
||||||
TRI_voc_cid_t otherCid = other->cid();
|
TRI_voc_cid_t otherCid = other->cid();
|
||||||
state->releaseCollection(otherCid);
|
state->releaseCollection(otherCid);
|
||||||
vocbase->dropCollection(other, false);
|
vocbase->dropCollection(other, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = vocbase->renameCollection(collection, name, true, false);
|
int res = vocbase->renameCollection(collection, name, true, false);
|
||||||
|
@ -768,7 +768,7 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
|
|
||||||
if (collection != nullptr) {
|
if (collection != nullptr) {
|
||||||
// drop an existing collection
|
// drop an existing collection
|
||||||
vocbase->dropCollection(collection, false);
|
vocbase->dropCollection(collection, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ARANGODB_ENABLE_ROCKSDB
|
#ifdef ARANGODB_ENABLE_ROCKSDB
|
||||||
|
@ -788,7 +788,7 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
TRI_voc_cid_t otherCid = collection->cid();
|
TRI_voc_cid_t otherCid = collection->cid();
|
||||||
|
|
||||||
state->releaseCollection(otherCid);
|
state->releaseCollection(otherCid);
|
||||||
vocbase->dropCollection(collection, false);
|
vocbase->dropCollection(collection, true, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(WARN) << "empty name attribute in create collection marker for collection " << collectionId << " and database " << databaseId;
|
LOG(WARN) << "empty name attribute in create collection marker for collection " << collectionId << " and database " << databaseId;
|
||||||
|
@ -973,7 +973,7 @@ bool RecoverState::ReplayMarker(TRI_df_marker_t const* marker, void* data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collection != nullptr) {
|
if (collection != nullptr) {
|
||||||
vocbase->dropCollection(collection, false);
|
vocbase->dropCollection(collection, true, false);
|
||||||
}
|
}
|
||||||
#ifdef ARANGODB_ENABLE_ROCKSDB
|
#ifdef ARANGODB_ENABLE_ROCKSDB
|
||||||
RocksDBFeature::dropCollection(databaseId, collectionId);
|
RocksDBFeature::dropCollection(databaseId, collectionId);
|
||||||
|
|
|
@ -601,7 +601,15 @@ function delete_api_collection (req, res) {
|
||||||
id: collection._id
|
id: collection._id
|
||||||
};
|
};
|
||||||
|
|
||||||
collection.drop();
|
var options = {};
|
||||||
|
if (req.parameters.hasOwnProperty('isSystem')) {
|
||||||
|
// are we allowed to drop system collections?
|
||||||
|
var value = req.parameters.isSystem.toLowerCase();
|
||||||
|
if (value === 'true' || value === 'yes' || value === 'on' || value === 'y' || value === '1') {
|
||||||
|
options.isSystem = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collection.drop(options);
|
||||||
|
|
||||||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -425,8 +425,13 @@ ArangoCollection.prototype.revision = function () {
|
||||||
// / @brief drops a collection
|
// / @brief drops a collection
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoCollection.prototype.drop = function () {
|
ArangoCollection.prototype.drop = function (options) {
|
||||||
var requestResult = this._database._connection.DELETE(this._baseurl());
|
var requestResult;
|
||||||
|
if (typeof options === 'object' && options.isSystem) {
|
||||||
|
requestResult = this._database._connection.DELETE(this._baseurl() + '?isSystem=true');
|
||||||
|
} else {
|
||||||
|
requestResult = this._database._connection.DELETE(this._baseurl());
|
||||||
|
}
|
||||||
|
|
||||||
if (requestResult !== null
|
if (requestResult !== null
|
||||||
&& requestResult.error === true
|
&& requestResult.error === true
|
||||||
|
|
|
@ -386,7 +386,7 @@ ArangoDatabase.prototype._truncate = function (id) {
|
||||||
// / @brief drops a collection
|
// / @brief drops a collection
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoDatabase.prototype._drop = function (id) {
|
ArangoDatabase.prototype._drop = function (id, options) {
|
||||||
var name;
|
var name;
|
||||||
|
|
||||||
for (name in this) {
|
for (name in this) {
|
||||||
|
@ -395,7 +395,7 @@ ArangoDatabase.prototype._drop = function (id) {
|
||||||
|
|
||||||
if (collection instanceof this._collectionConstructor) {
|
if (collection instanceof this._collectionConstructor) {
|
||||||
if (collection._id === id || collection._name === id) {
|
if (collection._id === id || collection._name === id) {
|
||||||
return collection.drop();
|
return collection.drop(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,7 @@ ArangoDatabase.prototype._drop = function (id) {
|
||||||
|
|
||||||
var c = this._collection(id);
|
var c = this._collection(id);
|
||||||
if (c) {
|
if (c) {
|
||||||
return c.drop();
|
return c.drop(options);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
|
@ -118,7 +118,7 @@ ArangoDatabase.prototype._executeTransaction = function (data) {
|
||||||
// / @brief was docuBlock collectionDatabaseDrop
|
// / @brief was docuBlock collectionDatabaseDrop
|
||||||
// //////////////////////////////////////////////////////////////////////////////
|
// //////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ArangoDatabase.prototype._drop = function (name) {
|
ArangoDatabase.prototype._drop = function (name, options) {
|
||||||
var collection = name;
|
var collection = name;
|
||||||
|
|
||||||
if (!(name instanceof ArangoCollection)) {
|
if (!(name instanceof ArangoCollection)) {
|
||||||
|
@ -130,7 +130,7 @@ ArangoDatabase.prototype._drop = function (name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return collection.drop();
|
return collection.drop(options);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// ignore if the collection does not exist
|
// ignore if the collection does not exist
|
||||||
if (err instanceof ArangoError &&
|
if (err instanceof ArangoError &&
|
||||||
|
|
|
@ -187,7 +187,7 @@ function ReplicationSuite() {
|
||||||
|
|
||||||
db._drop(cn);
|
db._drop(cn);
|
||||||
db._drop(cn2);
|
db._drop(cn2);
|
||||||
db._drop("_test");
|
db._drop("_test", { isSystem: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -199,14 +199,14 @@ function ReplicationSuite() {
|
||||||
|
|
||||||
db._drop(cn);
|
db._drop(cn);
|
||||||
db._drop(cn2);
|
db._drop(cn2);
|
||||||
db._drop("_test");
|
db._drop("_test", { isSystem: true });
|
||||||
|
|
||||||
connectToSlave();
|
connectToSlave();
|
||||||
replication.applier.stop();
|
replication.applier.stop();
|
||||||
replication.applier.forget();
|
replication.applier.forget();
|
||||||
db._drop(cn);
|
db._drop(cn);
|
||||||
db._drop(cn2);
|
db._drop(cn2);
|
||||||
db._drop("_test");
|
db._drop("_test", { isSystem: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue