1
0
Fork 0

issue 383.3: implement remainder of IResearchViewDBServer tests, use the data-source id (primary key) instead of an arbitrary instance for dropCollection()/dropView(), backport from iresearch upstream: ensure block is flushed if key index is full (#5176)

This commit is contained in:
Vasiliy 2018-04-23 00:33:46 +03:00 committed by Andrey Abramov
parent da4519df43
commit 9062c41592
28 changed files with 342 additions and 206 deletions

View File

@ -1816,9 +1816,12 @@ class index_block {
static const size_t SIZE = Size;
bool push_back(doc_id_t key, uint64_t offset) {
assert(keys_ <= key_);
assert(key_ >= keys_);
assert(key_ < keys_ + Size);
*key_++ = key;
assert(key >= key_[-1]);
assert(offset_ >= offsets_);
assert(offset_ < offsets_ + Size);
*offset_++ = offset;
assert(offset >= offset_[-1]);
return key_ == std::end(keys_);
@ -1931,6 +1934,13 @@ class writer final : public iresearch::columnstore_writer {
// commit previous key and offset unless the 'reset' method has been called
if (max_ != pending_key_) {
// flush block if we've overcome INDEX_BLOCK_SIZE size (before push_back)
if (INDEX_BLOCK_SIZE <= block_index_.size()) {
flush_block();
min_ = key;
offset = block_buf_.size(); // reset offset to position in the current block
}
// will trigger 'flush_block' if offset >= MAX_DATA_BLOCK_SIZE
offset = offsets_[size_t(block_index_.push_back(pending_key_, offset))];
max_ = pending_key_;

View File

@ -2647,7 +2647,7 @@ std::shared_ptr<LogicalCollection> ClusterMethods::persistCollectionInAgency(
} else {
// system collections should never enforce replicationfactor
// to allow them to come up with 1 dbserver
if (col->isSystem()) {
if (col->system()) {
enforceReplicationFactor = false;
}
@ -2685,7 +2685,9 @@ std::shared_ptr<LogicalCollection> ClusterMethods::persistCollectionInAgency(
}), dbServers.end());
}
std::random_shuffle(dbServers.begin(), dbServers.end());
shards = DistributeShardsEvenly(ci, numberOfShards, replicationFactor, dbServers, !col->isSystem());
shards = DistributeShardsEvenly(
ci, numberOfShards, replicationFactor, dbServers, !col->system()
);
}
if (shards->empty() && !col->isSmart()) {

View File

@ -43,6 +43,12 @@ typedef irs::async_utils::read_write_mutex::write_mutex WriteMutex;
////////////////////////////////////////////////////////////////////////////////
const std::string COLLECTIONS_FIELD("collections");
////////////////////////////////////////////////////////////////////////////////
/// @brief the name of the field in the IResearch View definition denoting the
/// view deletion marker (from LogicalView.cpp)
////////////////////////////////////////////////////////////////////////////////
const std::string DELETED_FIELD("deleted");
////////////////////////////////////////////////////////////////////////////////
/// @brief the name of the field in the IResearch View definition denoting the
/// view id (from LogicalView.cpp)
@ -67,12 +73,27 @@ const std::string LINKS_FIELD("links");
////////////////////////////////////////////////////////////////////////////////
const std::string NAME_FIELD("name");
////////////////////////////////////////////////////////////////////////////////
/// @brief the name of the field in the IResearch View definition denoting the
/// view plan ID (from LogicalView.cpp)
////////////////////////////////////////////////////////////////////////////////
const std::string PLAN_ID_FIELD("planId");
////////////////////////////////////////////////////////////////////////////////
/// @brief the name of the field in the IResearch View definition denoting the
/// view properties (from LogicalView.cpp)
////////////////////////////////////////////////////////////////////////////////
const std::string PROPERTIES_FIELD("properties");
////////////////////////////////////////////////////////////////////////////////
/// @brief the name of the field in the IResearch View definition denoting the
/// view type (from LogicalView.cpp)
////////////////////////////////////////////////////////////////////////////////
const std::string TYPE_FIELD("type");
////////////////////////////////////////////////////////////////////////////////
/// @brief the view name prefix of per-cid view instances
////////////////////////////////////////////////////////////////////////////////
static std::string const VIEW_NAME_PREFIX("_iresearch_");
////////////////////////////////////////////////////////////////////////////////
@ -130,7 +151,10 @@ IResearchViewDBServer::IResearchViewDBServer(
arangodb::DatabasePathFeature const& dbPathFeature,
uint64_t planVersion
): LogicalView(vocbase, info, planVersion),
_meta(info),
_meta(
info.isObject() && info.get(PROPERTIES_FIELD).isObject()
? info.get(PROPERTIES_FIELD) : emptyObjectSlice()
),
_persistedPath(getPersistedPath(dbPathFeature, id())) {
}
@ -143,7 +167,7 @@ arangodb::Result IResearchViewDBServer::drop() {
SCOPED_LOCK(mutex); // 'collections_' can be asynchronously read
for (auto itr = _collections.begin(); itr != _collections.end();) {
auto res = vocbase().dropView(*(itr->second));
auto res = vocbase().dropView(itr->second->id(), true); // per-cid collections always system
if (!res.ok()) {
return res; // fail on first failure
@ -164,7 +188,7 @@ arangodb::Result IResearchViewDBServer::drop(TRI_voc_cid_t cid) {
return arangodb::Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
}
auto res = vocbase().dropView(*(itr->second));
auto res = vocbase().dropView(itr->second->id(), true); // per-cid collections always system
if (res.ok()) {
_collections.erase(itr);
@ -187,45 +211,29 @@ std::shared_ptr<arangodb::LogicalView> IResearchViewDBServer::ensure(
static const std::function<bool(irs::string_ref const& key)> acceptor = [](
irs::string_ref const& key
)->bool {
// ignored fields
return key != ID_FIELD
&& key != IS_SYSTEM_FIELD
&& key != NAME_FIELD
&& key != PROPERTIES_FIELD;
return key != COLLECTIONS_FIELD && key != LINKS_FIELD; // ignored fields
};
arangodb::velocypack::Builder builder;
builder.openObject();
builder.add(ID_FIELD, arangodb::velocypack::Value("0")); // force unique ID
builder.add(IS_SYSTEM_FIELD, arangodb::velocypack::Value(true)); // required to for use of VIEW_NAME_PREFIX
builder.add(NAME_FIELD, toValuePair(generateName(name(), id(), cid))); // mark the view definition as an internal per-cid instance
builder.add(TYPE_FIELD, toValuePair(DATA_SOURCE_TYPE.name())); // type required for proper factory selection
if (!mergeSliceSkipKeys(builder, _meta.slice(), acceptor)) {
LOG_TOPIC(WARN, arangodb::iresearch::TOPIC)
<< "failure to generate definition while constructing IResearch View in database '" << vocbase().id() << "'";
{
builder.add(
PROPERTIES_FIELD,
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Object)
);
return nullptr;
}
auto props = _meta.slice().get(PROPERTIES_FIELD);
if (props.isObject()) {
static const std::function<bool(irs::string_ref const& key)> propsAcceptor = [](
irs::string_ref const& key
)->bool {
return key != COLLECTIONS_FIELD && key != LINKS_FIELD; // ignored fields
};
builder.add(PROPERTIES_FIELD, VPackValue(VPackValueType::Object));
if (!mergeSliceSkipKeys(builder, props, propsAcceptor)) {
if (!mergeSliceSkipKeys(builder, _meta.slice(), acceptor)) {
LOG_TOPIC(WARN, arangodb::iresearch::TOPIC)
<< "failure to generate properties definition while constructing IResearch View in database '" << vocbase().id() << "'";
return nullptr;
}
builder.close();
builder.close(); // close PROPERTIES_FIELD
}
builder.close();
@ -467,7 +475,7 @@ void IResearchViewDBServer::open() {
arangodb::Result IResearchViewDBServer::rename(
std::string&& newName,
bool doSync
bool /*doSync*/
) {
ReadMutex mutex(_mutex);
SCOPED_LOCK(mutex); // 'collections_' can be asynchronously modified
@ -482,25 +490,6 @@ arangodb::Result IResearchViewDBServer::rename(
}
}
static const std::function<bool(irs::string_ref const& key)> acceptor = [](
irs::string_ref const& key
)->bool {
return key != NAME_FIELD; // ignore name filed
};
arangodb::velocypack::Builder builder;
builder.openObject();
builder.add(NAME_FIELD, arangodb::velocypack::Value(std::move(newName)));
if (!mergeSliceSkipKeys(builder, _meta.slice(), acceptor)) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failure to generate definition while renaming IResearch View in database '") + vocbase().name() + "'"
);
}
builder.close();
_meta = std::move(builder);
name(std::move(newName));
return arangodb::Result();
@ -509,60 +498,54 @@ arangodb::Result IResearchViewDBServer::rename(
void IResearchViewDBServer::toVelocyPack(
arangodb::velocypack::Builder& result,
bool includeProperties,
bool /*includeSystem*/
bool includeSystem
) const {
TRI_ASSERT(result.isOpenObject());
ReadMutex mutex(_mutex);
SCOPED_LOCK(mutex); // '_collections'/'_meta' can be asynchronously modified
static const std::function<bool(irs::string_ref const& key)> acceptor = [](
irs::string_ref const& key
)->bool {
return key != PROPERTIES_FIELD; // ignored fields
};
result.add(ID_FIELD, arangodb::velocypack::Value(std::to_string(id())));
result.add(NAME_FIELD, arangodb::velocypack::Value(name()));
result.add(TYPE_FIELD, arangodb::velocypack::Value(type().name()));
if (!mergeSliceSkipKeys(result, _meta.slice(), acceptor)) {
LOG_TOPIC(WARN, arangodb::iresearch::TOPIC)
<< "failure to generate definition while for IResearch View in database '" << vocbase().name() << "'";
return; // error during output
if (includeSystem) {
result.add(DELETED_FIELD, arangodb::velocypack::Value(deleted()));
result.add(IS_SYSTEM_FIELD, arangodb::velocypack::Value(system()));
result.add(PLAN_ID_FIELD, arangodb::velocypack::Value(std::to_string(planId())));
}
if (!includeProperties) {
return; // nothing more to output
}
if (includeProperties) {
static const std::function<bool(irs::string_ref const& key)> acceptor = [](
irs::string_ref const& key
)->bool {
return key != COLLECTIONS_FIELD && key != LINKS_FIELD; // ignored fields
};
ReadMutex mutex(_mutex);
SCOPED_LOCK(mutex); // '_collections'/'_meta' can be asynchronously modified
static const std::function<bool(irs::string_ref const& key)> propsAcceptor = [](
irs::string_ref const& key
)->bool {
return key != COLLECTIONS_FIELD && key != LINKS_FIELD; // ignored fields
};
auto properties = _meta.slice().get(PROPERTIES_FIELD);
result.add(
PROPERTIES_FIELD,
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Object)
);
{
result.add(
COLLECTIONS_FIELD,
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Array)
PROPERTIES_FIELD,
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Object)
);
for (auto& entry: _collections) {
result.add(arangodb::velocypack::Value(entry.first));
{
result.add(
COLLECTIONS_FIELD,
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Array)
);
for (auto& entry: _collections) {
result.add(arangodb::velocypack::Value(entry.first));
}
result.close(); // close COLLECTIONS_FIELD
}
result.close(); // close COLLECTIONS_FIELD
}
if (!mergeSliceSkipKeys(result, _meta.slice(), acceptor)) {
LOG_TOPIC(WARN, arangodb::iresearch::TOPIC)
<< "failure to generate definition while properties generating jSON IResearch View in database '" << vocbase().name() << "'";
}
if (!mergeSliceSkipKeys(result, properties, propsAcceptor)) {
LOG_TOPIC(WARN, arangodb::iresearch::TOPIC)
<< "failure to generate definition while properties generating jSON IResearch View in database '" << vocbase().name() << "'";
result.close(); // close PROPERTIES_FIELD
}
result.close(); // close PROPERTIES_FIELD
}
arangodb::Result IResearchViewDBServer::updateProperties(
@ -605,7 +588,7 @@ arangodb::Result IResearchViewDBServer::updateProperties(
if (partialUpdate) {
IResearchViewMeta oldMeta;
if (!oldMeta.init(_meta.slice().get(PROPERTIES_FIELD), error)
if (!oldMeta.init(_meta.slice(), error)
|| !meta.init(props.slice(), error, oldMeta)) {
return arangodb::Result(
TRI_ERROR_BAD_PARAMETER,
@ -632,27 +615,10 @@ arangodb::Result IResearchViewDBServer::updateProperties(
// prepare replacement '_meta'
// ...........................................................................
static const std::function<bool(irs::string_ref const& key)> acceptor = [](
irs::string_ref const& key
)->bool {
return key != PROPERTIES_FIELD; // ignored fields
};
arangodb::velocypack::Builder builder;
builder.openObject();
if (!mergeSliceSkipKeys(builder, _meta.slice(), acceptor)) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failure to generate definition while updating IResearch View in database '") + vocbase().name() + "'"
);
}
builder.add(
PROPERTIES_FIELD,
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Object)
);
if (!meta.json(builder)) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
@ -660,7 +626,6 @@ arangodb::Result IResearchViewDBServer::updateProperties(
);
}
builder.close(); // close PROPERTIES_FIELD
builder.close();
// ...........................................................................

View File

@ -709,7 +709,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
auto otherCid = other->id();
state->releaseCollection(otherCid);
vocbase->dropCollection(other.get(), true, -1.0);
vocbase->dropCollection(otherCid, true, -1.0);
}
}
@ -851,7 +851,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
break;
}
vocbase->dropView(*other);
vocbase->dropView(other->id(), true);
}
int res = vocbase->renameView(view, name);
@ -1058,7 +1058,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
if (collection != nullptr) {
// drop an existing collection
vocbase->dropCollection(collection, true, -1.0);
vocbase->dropCollection(collection->id(), true, -1.0);
}
MMFilesPersistentIndexFeature::dropCollection(databaseId, collectionId);
@ -1077,7 +1077,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
auto otherCid = collection->id();
state->releaseCollection(otherCid);
vocbase->dropCollection(collection, true, -1.0);
vocbase->dropCollection(otherCid, true, -1.0);
}
} else {
LOG_TOPIC(WARN, arangodb::Logger::ENGINES)
@ -1174,7 +1174,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
vocbase->lookupView(viewId);
if (view != nullptr) {
vocbase->dropView(*view); // drop an existing view
vocbase->dropView(view->id(), true); // drop an existing view
}
// check if there is another view with the same name as the one that
@ -1187,7 +1187,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
view = vocbase->lookupView(name);
if (view != nullptr) {
vocbase->dropView(*view);
vocbase->dropView(view->id(), true);
}
} else {
LOG_TOPIC(WARN, arangodb::Logger::ENGINES)
@ -1397,7 +1397,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
}
if (collection != nullptr) {
vocbase->dropCollection(collection, true, -1.0);
vocbase->dropCollection(collection->id(), true, -1.0);
}
MMFilesPersistentIndexFeature::dropCollection(databaseId, collectionId);
break;
@ -1427,7 +1427,7 @@ bool MMFilesWalRecoverState::ReplayMarker(MMFilesMarker const* marker,
vocbase->lookupView(viewId);
if (view != nullptr) {
vocbase->dropView(*view);
vocbase->dropView(view->id(), true);
}
break;

View File

@ -817,7 +817,9 @@ Result DatabaseInitialSyncer::handleCollection(VPackSlice const& parameters,
// in this case we must drop it because we will run into duplicate
// name conflicts otherwise
try {
int res = vocbase()->dropCollection(col, true, -1.0);
auto res =
vocbase()->dropCollection(col->id(), true, -1.0).errorNumber();
if (res == TRI_ERROR_NO_ERROR) {
col = nullptr;
}
@ -876,7 +878,8 @@ Result DatabaseInitialSyncer::handleCollection(VPackSlice const& parameters,
}
setProgress("dropping " + collectionMsg);
int res = vocbase()->dropCollection(col, true, -1.0);
auto res =
vocbase()->dropCollection(col->id(), true, -1.0).errorNumber();
if (res != TRI_ERROR_NO_ERROR) {
return Result(res, std::string("unable to drop ") + collectionMsg + ": " + TRI_errno_string(res));

View File

@ -270,7 +270,7 @@ Result GlobalInitialSyncer::updateServerInventory(VPackSlice const& masterDataba
return;
}
if (collection->isSystem()) {
if (collection->system()) {
// we will not drop system collections here
return;
}
@ -280,7 +280,9 @@ Result GlobalInitialSyncer::updateServerInventory(VPackSlice const& masterDataba
for (auto const& collection : toDrop) {
try {
int res = vocbase->dropCollection(collection, false, -1.0);
auto res =
vocbase->dropCollection(collection->id(), false, -1.0).errorNumber();
if (res != TRI_ERROR_NO_ERROR) {
LOG_TOPIC(ERR, Logger::FIXME) << "unable to drop collection " << collection->name() << ": " << TRI_errno_string(res);
}

View File

@ -584,7 +584,7 @@ Result Syncer::createCollection(TRI_vocbase_t* vocbase,
col = vocbase->lookupCollection(name).get();
if (col != nullptr) {
if (col->isSystem()) {
if (col->system()) {
TRI_ASSERT(!simulate32Client() || col->globallyUniqueId() == col->name());
SingleCollectionTransaction trx(
transaction::StandaloneContext::Create(vocbase),
@ -606,7 +606,7 @@ Result Syncer::createCollection(TRI_vocbase_t* vocbase,
return trx.finish(opRes.result);
} else {
vocbase->dropCollection(col, false, -1.0);
vocbase->dropCollection(col->id(), false, -1.0);
}
}
@ -665,7 +665,7 @@ Result Syncer::dropCollection(VPackSlice const& slice, bool reportError) {
return Result();
}
return Result(vocbase->dropCollection(col, true, -1.0));
return vocbase->dropCollection(col->id(), true, -1.0);
}
/// @brief creates an index, based on the VelocyPack provided

View File

@ -297,7 +297,8 @@ Result TailingSyncer::processDocument(TRI_replication_operation_e type,
return Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND);
}
bool isSystem = coll->isSystem();
bool isSystem = coll->system();
// extract "data"
VPackSlice const doc = slice.get("data");
@ -576,7 +577,7 @@ Result TailingSyncer::renameCollection(VPackSlice const& slice) {
TRI_ASSERT(col == nullptr);
return Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, "unable to identify collection");
}
if (col->isSystem()) {
if (col->system()) {
LOG_TOPIC(WARN, Logger::REPLICATION) << "Renaming system collection " << col->name();
}
return Result(vocbase->renameCollection(col, name, true));

View File

@ -85,7 +85,8 @@ void RestCollectionHandler::handleCommandGet() {
ExecContext const* exec = ExecContext::CURRENT;
bool canUse = exec == nullptr ||
exec->canUseCollection(coll->name(), auth::Level::RO);
if (canUse && (!excludeSystem || !coll->isSystem())) {
if (canUse && (!excludeSystem || !coll->system())) {
collectionRepresentation(builder, coll,
/*showProperties*/ false,
/*showFigures*/ false, /*showCount*/ false,
@ -493,7 +494,7 @@ void RestCollectionHandler::collectionRepresentation(
builder.add("type", VPackValue(coll->type()));
if (!showProperties) {
builder.add("isSystem", VPackValue(coll->isSystem()));
builder.add("isSystem", VPackValue(coll->system()));
builder.add("globallyUniqueId", VPackValue(coll->globallyUniqueId()));
} else {
Result res = methods::Collections::properties(coll, builder);

View File

@ -909,7 +909,7 @@ Result RestReplicationHandler::processRestoreCollection(
// drop an existing collection if it exists
if (col != nullptr) {
if (dropExisting) {
Result res = _vocbase.dropCollection(col, true, -1.0);
auto res = _vocbase.dropCollection(col->id(), true, -1.0);
if (res.errorNumber() == TRI_ERROR_FORBIDDEN) {
// some collections must not be dropped
@ -2547,7 +2547,7 @@ int RestReplicationHandler::createCollection(VPackSlice slice,
}
/* Temporary ASSERTS to prove correctness of new constructor */
TRI_ASSERT(col->isSystem() == (name[0] == '_'));
TRI_ASSERT(col->system() == (name[0] == '_'));
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
TRI_voc_cid_t planId = 0;
VPackSlice const planIdSlice = slice.get("planId");

View File

@ -227,6 +227,7 @@ void RestViewHandler::deleteView() {
}
std::string const& name = suffixes[0];
auto allowDropSystem = _request->parsedValue("isSystem", false);
auto view = _vocbase.lookupView(name);
if (!view) {
@ -238,7 +239,7 @@ void RestViewHandler::deleteView() {
return;
}
auto res = _vocbase.dropView(*view).errorNumber();
auto res = _vocbase.dropView(view->id(), allowDropSystem).errorNumber();
if (res == TRI_ERROR_NO_ERROR) {
generateOk(rest::ResponseCode::OK, VPackSlice::trueSlice());

View File

@ -104,7 +104,7 @@ RocksDBCollection::RocksDBCollection(LogicalCollection* collection,
_primaryIndex(nullptr),
_cache(nullptr),
_cachePresent(false),
_cacheEnabled(!collection->isSystem() &&
_cacheEnabled(!collection->system() &&
basics::VelocyPackHelper::readBooleanValue(
info, "cacheEnabled", false)) {
VPackSlice s = info.get("isVolatile");
@ -163,10 +163,12 @@ void RocksDBCollection::setPath(std::string const&) {
Result RocksDBCollection::updateProperties(VPackSlice const& slice,
bool doSync) {
bool isSys = _logicalCollection != nullptr && _logicalCollection->isSystem();
auto isSys = _logicalCollection != nullptr && _logicalCollection->system();
_cacheEnabled = !isSys && basics::VelocyPackHelper::readBooleanValue(
slice, "cacheEnabled", _cacheEnabled);
primaryIndex()->setCacheEnabled(_cacheEnabled);
if (_cacheEnabled) {
createCache();
primaryIndex()->createCache();

View File

@ -58,7 +58,7 @@ RocksDBIndex::RocksDBIndex(
_cf(cf),
_cache(nullptr),
_cachePresent(false),
_cacheEnabled(useCache && !collection->isSystem()) {
_cacheEnabled(useCache && !collection->system()) {
TRI_ASSERT(cf != nullptr && cf != RocksDBColumnFamily::definitions());
if (_cacheEnabled) {
createCache();
@ -79,7 +79,7 @@ RocksDBIndex::RocksDBIndex(TRI_idx_iid_t id, LogicalCollection* collection,
_cf(cf),
_cache(nullptr),
_cachePresent(false),
_cacheEnabled(useCache && !collection->isSystem()) {
_cacheEnabled(useCache && !collection->system()) {
TRI_ASSERT(cf != nullptr && cf != RocksDBColumnFamily::definitions());
if (_objectId == 0) {
@ -163,8 +163,9 @@ void RocksDBIndex::createCache() {
return;
}
TRI_ASSERT(!_collection->isSystem() &&
!ServerState::instance()->isCoordinator());
TRI_ASSERT(
!_collection->system() && !ServerState::instance()->isCoordinator()
);
TRI_ASSERT(_cache.get() == nullptr);
TRI_ASSERT(CacheManagerFeature::MANAGER != nullptr);
LOG_TOPIC(DEBUG, Logger::CACHE) << "Creating index cache";

View File

@ -277,8 +277,10 @@ int PhysicalCollection::newObjectForInsert(
// _id
uint8_t* p = builder.add(StaticStrings::IdString,
VPackValuePair(9ULL, VPackValueType::Custom));
*p++ = 0xf3; // custom type for _id
if (_isDBServer && !_logicalCollection->isSystem()) {
if (_isDBServer && !_logicalCollection->system()) {
// db server in cluster, note: the local collections _statistics,
// _statisticsRaw and _statistics15 (which are the only system
// collections)

View File

@ -1920,10 +1920,12 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
try {
auto coll =
ClusterInfo::instance()->getCollection(vocbase->name(), name);
if (coll->isSystem()) {
if (coll->system()) {
TRI_V8_THROW_EXCEPTION_USAGE(
"Cannot use pregel on system collection");
}
if (coll->status() == TRI_VOC_COL_STATUS_DELETED || coll->deleted()) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, name);
}
@ -1943,16 +1945,19 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
}
std::vector<CollectionID> edgeColls;
// load edge collection
for (std::string const& name : paramEdges) {
if (ss->isCoordinator()) {
try {
auto coll =
ClusterInfo::instance()->getCollection(vocbase->name(), name);
if (coll->isSystem()) {
if (coll->system()) {
TRI_V8_THROW_EXCEPTION_USAGE(
"Cannot use pregel on system collection");
}
if (!coll->isSmart()) {
std::vector<std::string> eKeys = coll->shardKeys();
if ( eKeys.size() != 1 || eKeys[0] != "vertex") {
@ -1961,11 +1966,14 @@ static void JS_PregelStart(v8::FunctionCallbackInfo<v8::Value> const& args) {
"smart graphs");
}
}
if (coll->status() == TRI_VOC_COL_STATUS_DELETED || coll->deleted()) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, name);
}
// smart edge collections contain multiple actual collections
std::vector<std::string> actual = coll->realNamesForRead();
edgeColls.insert(edgeColls.end(), actual.begin(), actual.end());
} catch (...) {
TRI_V8_THROW_EXCEPTION_MESSAGE(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND, name);

View File

@ -218,19 +218,36 @@ static void JS_DropViewVocbase(
TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
}
// we require exactly 1 argument
if (args.Length() != 1) {
TRI_V8_THROW_EXCEPTION_USAGE("_dropView(<name>)");
// we require exactly 1 string argument and an optional boolean argument
if (args.Length() < 1 || args.Length() > 2) {
TRI_V8_THROW_EXCEPTION_USAGE("_dropView(<name> [, allowDropSystem])");
}
PREVENT_EMBEDDED_TRANSACTION();
bool allowDropSystem = false;
if (args.Length() > 1) {
// options
if (args[1]->IsObject()) {
TRI_GET_GLOBALS();
v8::Handle<v8::Object> optionsObject = args[1].As<v8::Object>();
TRI_GET_GLOBAL_STRING(IsSystemKey);
if (optionsObject->Has(IsSystemKey)) {
allowDropSystem = TRI_ObjectToBoolean(optionsObject->Get(IsSystemKey));
}
} else {
allowDropSystem = TRI_ObjectToBoolean(args[1]);
}
}
// extract the name
std::string const name = TRI_ObjectToString(args[0]);
auto view = vocbase->lookupView(name);
if (view) {
auto res = vocbase->dropView(*view).errorNumber();
auto res = vocbase->dropView(view->id(), allowDropSystem).errorNumber();
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION(res);
@ -259,7 +276,25 @@ static void JS_DropViewVocbaseObj(
PREVENT_EMBEDDED_TRANSACTION();
auto res = view->vocbase().dropView(*view).errorNumber();
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]);
}
}
auto res =
view->vocbase().dropView(view->id(), allowDropSystem).errorNumber();
if (res != TRI_ERROR_NO_ERROR) {
TRI_V8_THROW_EXCEPTION_MESSAGE(res, "cannot drop view");

View File

@ -183,7 +183,6 @@ LogicalCollection::LogicalCollection(LogicalCollection const& other)
_status(other.status()),
_isSmart(other.isSmart()),
_isLocal(false),
_isSystem(other.isSystem()),
_waitForSync(other.waitForSync()),
_version(other._version),
_replicationFactor(other.replicationFactor()),
@ -220,6 +219,8 @@ LogicalCollection::LogicalCollection(
ReadPlanId(info, 0),
ReadStringValue(info, "name", ""),
planVersion,
TRI_vocbase_t::IsSystemName(ReadStringValue(info, "name", ""))
&& Helper::readBooleanValue(info, "isSystem", false),
Helper::readBooleanValue(info, "deleted", false)
),
_internalVersion(0),
@ -231,8 +232,6 @@ LogicalCollection::LogicalCollection(
info, "status", TRI_VOC_COL_STATUS_CORRUPTED)),
_isSmart(Helper::readBooleanValue(info, "isSmart", false)),
_isLocal(!ServerState::instance()->isCoordinator()),
_isSystem(TRI_vocbase_t::IsSystemName(ReadStringValue(info, "name", "")) &&
Helper::readBooleanValue(info, "isSystem", false)),
_waitForSync(Helper::readBooleanValue(info, "waitForSync", false)),
_version(Helper::readNumericValue<uint32_t>(info, "version",
currentVersion())),
@ -542,8 +541,6 @@ TRI_voc_rid_t LogicalCollection::revision(transaction::Methods* trx) const {
bool LogicalCollection::isLocal() const { return _isLocal; }
bool LogicalCollection::isSystem() const { return _isSystem; }
bool LogicalCollection::waitForSync() const { return _waitForSync; }
bool LogicalCollection::isSmart() const { return _isSmart; }
@ -765,9 +762,10 @@ void LogicalCollection::toVelocyPackForClusterInventory(VPackBuilder& result,
bool useSystem,
bool isReady,
bool allInSync) const {
if (_isSystem && !useSystem) {
if (system() && !useSystem) {
return;
}
result.openObject();
result.add(VPackValue("parameters"));
@ -813,7 +811,7 @@ void LogicalCollection::toVelocyPack(VPackBuilder& result, bool translateCids,
// Collection Flags
result.add("deleted", VPackValue(deleted()));
result.add("isSystem", VPackValue(_isSystem));
result.add("isSystem", VPackValue(system()));
result.add("waitForSync", VPackValue(_waitForSync));
result.add("globallyUniqueId", VPackValue(_globallyUniqueId));
@ -1362,7 +1360,7 @@ std::string LogicalCollection::generateGloballyUniqueId() const {
result.push_back('/');
result.append(name());
} else { // single server
if (isSystem()) { // system collection can't be renamed
if (system()) { // system collection can't be renamed
result.append(name());
} else {
TRI_ASSERT(id());

View File

@ -161,7 +161,6 @@ class LogicalCollection: public LogicalDataSource {
// SECTION: Properties
TRI_voc_rid_t revision(transaction::Methods*) const;
bool isLocal() const;
bool isSystem() const;
bool waitForSync() const;
bool isSmart() const;
bool isAStub() const { return _isAStub; }
@ -391,8 +390,6 @@ class LogicalCollection: public LogicalDataSource {
// SECTION: Properties
bool _isLocal;
bool const _isSystem;
bool _waitForSync;
uint32_t _version;

View File

@ -91,6 +91,7 @@ class LogicalDataSource {
TRI_voc_cid_t planId,
std::string&& name,
uint64_t planVersion,
bool system,
bool deleted
) noexcept
: _name(std::move(name)),
@ -100,7 +101,8 @@ class LogicalDataSource {
_id(id),
_planId(planId ? planId : id),
_planVersion(planVersion),
_deleted(deleted) {
_deleted(deleted),
_system(system) {
}
LogicalDataSource(LogicalDataSource const& other)
@ -111,7 +113,8 @@ class LogicalDataSource {
_id(other._id),
_planId(other._planId),
_planVersion(other._planVersion),
_deleted(other._deleted) {
_deleted(other._deleted),
_system(other._system) {
}
virtual ~LogicalDataSource() = default;
@ -124,6 +127,7 @@ class LogicalDataSource {
TRI_voc_cid_t planId() const noexcept { return _planId; }
uint64_t planVersion() const noexcept { return _planVersion; }
virtual Result rename(std::string&& newName, bool doSync) = 0;
bool system() const noexcept { return _system; }
Type const& type() const noexcept { return _type; }
TRI_vocbase_t& vocbase() const noexcept { return _vocbase; }
@ -145,6 +149,7 @@ class LogicalDataSource {
// then the version in the agency Plan that underpins
// the information in this object. Otherwise 0.
bool _deleted; // data-source marked as deleted
bool const _system; // this instance represents a system data-source
};
} // arangodb

View File

@ -38,6 +38,24 @@ using Helper = arangodb::basics::VelocyPackHelper;
namespace {
bool ReadIsSystem(arangodb::velocypack::Slice info) {
if (!info.isObject()) {
return false;
}
auto name =
arangodb::basics::VelocyPackHelper::getStringValue(info, "name", "");
if (!TRI_vocbase_t::IsSystemName(name)) {
return false;
}
// same condition as in LogicalCollection
return arangodb::basics::VelocyPackHelper::readBooleanValue(
info, "isSystem", false
);
}
TRI_voc_cid_t ReadPlanId(VPackSlice info, TRI_voc_cid_t vid) {
if (!info.isObject()) {
// ERROR CASE
@ -112,6 +130,7 @@ LogicalView::LogicalView(
ReadPlanId(definition, 0),
arangodb::basics::VelocyPackHelper::getStringValue(definition, "name", ""),
planVersion,
ReadIsSystem(definition),
Helper::readBooleanValue(definition, "deleted", false)
) {
if (!TRI_vocbase_t::IsAllowedName(definition)) {
@ -306,6 +325,7 @@ void DBServerLogicalView::toVelocyPack(
if (includeSystem) {
result.add("deleted", VPackValue(deleted()));
result.add("isSystem", VPackValue(system()));
// FIXME not sure if the following is relevant
// Cluster Specific

View File

@ -453,7 +453,7 @@ Result Collections::rename(LogicalCollection* coll, std::string const& newName,
static Result DropVocbaseColCoordinator(arangodb::LogicalCollection* collection,
bool allowDropSystem) {
if (collection->isSystem() && !allowDropSystem) {
if (collection->system() && !allowDropSystem) {
return TRI_ERROR_FORBIDDEN;
}
@ -502,7 +502,8 @@ Result Collections::drop(TRI_vocbase_t* vocbase, LogicalCollection* coll,
res = DropVocbaseColCoordinator(coll, allowDropSystem);
#endif
} else {
int r = coll->vocbase().dropCollection(coll, allowDropSystem, timeout);
auto r =
coll->vocbase().dropCollection(coll->id(), allowDropSystem, timeout).errorNumber();
if (r != TRI_ERROR_NO_ERROR) {
res.reset(r, "cannot drop collection");

View File

@ -1260,12 +1260,27 @@ int TRI_vocbase_t::unloadCollection(arangodb::LogicalCollection* collection,
}
/// @brief drops a collection
int TRI_vocbase_t::dropCollection(arangodb::LogicalCollection* collection,
bool allowDropSystem, double timeout) {
TRI_ASSERT(collection != nullptr);
arangodb::Result TRI_vocbase_t::dropCollection(
TRI_voc_cid_t cid,
bool allowDropSystem,
double timeout
) {
auto* collection = lookupCollection(cid).get();
if (!collection) {
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
}
StorageEngine* engine = EngineSelectorFeature::ENGINE;
if (!allowDropSystem && collection->isSystem() && !engine->inRecovery()) {
if (!engine) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to find StorageEngine while dropping collection '") + collection->name() + "'"
);
}
if (!allowDropSystem && collection->system() && !engine->inRecovery()) {
// prevent dropping of system collections
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
}
@ -1363,7 +1378,7 @@ int TRI_vocbase_t::renameCollection(
std::string const& newName,
bool doOverride
) {
if (collection->isSystem()) {
if (collection->system()) {
return TRI_set_errno(TRI_ERROR_FORBIDDEN);
}
@ -1678,12 +1693,36 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createView(
}
/// @brief drops a view
arangodb::Result TRI_vocbase_t::dropView(arangodb::LogicalView& view) {
arangodb::Result TRI_vocbase_t::dropView(
TRI_voc_cid_t cid,
bool allowDropSystem
) {
auto view = lookupView(cid);
if (!view) {
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
}
if (!allowDropSystem && view->system()) {
StorageEngine* engine = EngineSelectorFeature::ENGINE;
if (!engine) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to find StorageEngine while dropping view '") + view->name() + "'"
);
}
if (!engine->inRecovery()) {
return TRI_ERROR_FORBIDDEN; // prevent dropping of system views
}
}
if (ServerState::instance()->isCoordinator()) {
ClusterInfo* ci = ClusterInfo::instance();
std::string errorMsg;
auto res =
ci->dropViewCoordinator(name(), std::to_string(view.id()), errorMsg);
ci->dropViewCoordinator(name(), std::to_string(view->id()), errorMsg);
if (res == TRI_ERROR_NO_ERROR) {
return res;
@ -1705,7 +1744,7 @@ arangodb::Result TRI_vocbase_t::dropView(arangodb::LogicalView& view) {
RECURSIVE_WRITE_LOCKER_NAMED(writeLocker, _dataSourceLock, _dataSourceLockWriteOwner,
basics::ConditionalLocking::DoNotLock);
CONDITIONAL_WRITE_LOCKER(
locker, view._lock, basics::ConditionalLocking::DoNotLock
locker, view->_lock, basics::ConditionalLocking::DoNotLock
);
while (true) {
@ -1740,18 +1779,18 @@ arangodb::Result TRI_vocbase_t::dropView(arangodb::LogicalView& view) {
arangodb::aql::PlanCache::instance()->invalidate(this);
arangodb::aql::QueryCache::instance()->invalidate(this);
auto res = view.drop();
auto res = view->drop();
if (!res.ok()) {
return res;
}
unregisterView(view);
unregisterView(*view);
locker.unlock();
writeLocker.unlock();
events::DropView(view.name(), TRI_ERROR_NO_ERROR);
events::DropView(view->name(), TRI_ERROR_NO_ERROR);
if (DatabaseFeature::DATABASE != nullptr &&
DatabaseFeature::DATABASE->versionTracker() != nullptr) {

View File

@ -280,7 +280,7 @@ struct TRI_vocbase_t {
);
/// @brief drops a view
arangodb::Result dropView(arangodb::LogicalView& view);
arangodb::Result dropView(TRI_voc_cid_t cid, bool allowDropSystem);
/// @brief returns all known collections with their parameters
/// and optionally indexes
@ -348,8 +348,11 @@ struct TRI_vocbase_t {
/// @brief drops a collection, no timeout if timeout is < 0.0, otherwise
/// timeout is in seconds. Essentially, the timeout counts to acquire the
/// write lock for using the collection.
int dropCollection(arangodb::LogicalCollection* collection,
bool allowDropSystem, double timeout);
arangodb::Result dropCollection(
TRI_voc_cid_t cid,
bool allowDropSystem,
double timeout
);
/// @brief callback for collection dropping
static bool DropCollectionCallback(arangodb::LogicalCollection* collection);

View File

@ -535,7 +535,7 @@ SECTION("test_persistence") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -836,7 +836,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -871,7 +871,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -909,7 +909,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -950,7 +950,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -993,7 +993,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -1025,7 +1025,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -1059,7 +1059,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -1097,7 +1097,7 @@ SECTION("test_start") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");
@ -1158,7 +1158,7 @@ SECTION("test_tokens") {
auto collection = vocbase->lookupCollection("_iresearch_analyzers");
if (collection) {
vocbase->dropCollection(collection.get(), true, -1);
vocbase->dropCollection(collection->id(), true, -1);
}
collection = vocbase->lookupCollection("_iresearch_analyzers");

View File

@ -252,10 +252,11 @@ SECTION("test_defaults") {
arangodb::iresearch::IResearchViewMeta meta;
std::string error;
CHECK(6 == slice.length());
CHECK(7 == slice.length());
CHECK(slice.get("name").copyString() == "testView");
CHECK(slice.get("type").copyString() == arangodb::iresearch::DATA_SOURCE_TYPE.name());
CHECK(false == slice.get("deleted").getBool());
CHECK(false == slice.get("isSystem").getBool());
slice = slice.get("properties");
CHECK(slice.isObject());
CHECK((5U == slice.length()));
@ -335,7 +336,7 @@ SECTION("test_drop") {
CHECK((true == logicalCollection->getIndexes().empty()));
CHECK((false == !vocbase.lookupView("testView")));
CHECK((true == TRI_IsDirectory(dataPath.c_str())));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropView(view->id(), false).ok()));
CHECK((true == logicalCollection->getIndexes().empty()));
CHECK((true == !vocbase.lookupView("testView")));
CHECK((false == TRI_IsDirectory(dataPath.c_str())));
@ -373,7 +374,7 @@ SECTION("test_drop_with_link") {
CHECK(true == res.ok());
CHECK((false == logicalCollection->getIndexes().empty()));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropView(view->id(), false).ok()));
CHECK((true == logicalCollection->getIndexes().empty()));
CHECK((true == !vocbase.lookupView("testView")));
CHECK((false == TRI_IsDirectory(dataPath.c_str())));
@ -1686,7 +1687,7 @@ SECTION("test_unregister_link") {
StorageEngineMock::inRecoveryResult = true;
auto restore = irs::make_finally([&before]()->void { StorageEngineMock::inRecoveryResult = before; });
persisted = false;
CHECK((TRI_ERROR_NO_ERROR == vocbase.dropCollection(logicalCollection, true, -1)));
CHECK((true == vocbase.dropCollection(logicalCollection->id(), true, -1).ok()));
CHECK((false == persisted)); // link removal does not persist view meta
CHECK((nullptr == vocbase.lookupCollection("testCollection")));
@ -1706,7 +1707,7 @@ SECTION("test_unregister_link") {
}
CHECK((false == !vocbase.lookupView("testView")));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropView(view->id(), false).ok()));
CHECK((true == !vocbase.lookupView("testView")));
}
@ -1766,7 +1767,7 @@ SECTION("test_unregister_link") {
CHECK((nullptr != vocbase.lookupCollection("testCollection")));
persisted = false;
CHECK((TRI_ERROR_NO_ERROR == vocbase.dropCollection(logicalCollection, true, -1)));
CHECK((true == vocbase.dropCollection(logicalCollection->id(), true, -1).ok()));
CHECK((true == persisted)); // collection removal persists view meta
CHECK((nullptr == vocbase.lookupCollection("testCollection")));
@ -1786,7 +1787,7 @@ SECTION("test_unregister_link") {
}
CHECK((false == !vocbase.lookupView("testView")));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropView(view->id(), false).ok()));
CHECK((true == !vocbase.lookupView("testView")));
}
@ -1812,10 +1813,10 @@ SECTION("test_unregister_link") {
view->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((1 == cids.size()));
CHECK((false == !vocbase.lookupView("testView")));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropView(view->id(), false).ok()));
CHECK((true == !vocbase.lookupView("testView")));
CHECK((nullptr != vocbase.lookupCollection("testCollection")));
CHECK((TRI_ERROR_NO_ERROR == vocbase.dropCollection(logicalCollection, true, -1)));
CHECK((true == vocbase.dropCollection(logicalCollection->id(), true, -1).ok()));
CHECK((nullptr == vocbase.lookupCollection("testCollection")));
}
@ -1838,7 +1839,7 @@ SECTION("test_unregister_link") {
viewImpl->visitCollections([&cids](TRI_voc_cid_t cid)->bool { cids.emplace(cid); return true; });
CHECK((1 == cids.size()));
logicalCollection->getIndexes()[0]->unload(); // release view reference to prevent deadlock due to ~IResearchView() waiting for IResearchLink::unload()
CHECK((true == vocbase.dropView(*logicalView).ok()));
CHECK((true == vocbase.dropView(logicalView->id(), false).ok()));
CHECK((1 == logicalView.use_count())); // ensure destructor for ViewImplementation is called
CHECK((false == logicalCollection->getIndexes().empty()));
}
@ -2233,7 +2234,7 @@ SECTION("test_transaction_registration") {
}
// drop collection from vocbase
CHECK((TRI_ERROR_NO_ERROR == vocbase.dropCollection(logicalCollection1, true, 0)));
CHECK((true == vocbase.dropCollection(logicalCollection1->id(), true, 0).ok()));
// read transaction (by id) (one collection dropped)
{

View File

@ -457,9 +457,9 @@ SECTION("test_toVelocyPack") {
builder.close();
auto slice = builder.slice();
CHECK((3 == slice.length()));
CHECK((slice.hasKey("id") && slice.get("id").isString() && std::string("1") == slice.get("id").copyString()));
CHECK((slice.hasKey("name") && slice.get("name").isString() && std::string("testView") == slice.get("name").copyString()));
CHECK((slice.hasKey("type") && slice.get("type").isString() && arangodb::iresearch::DATA_SOURCE_TYPE.name() == slice.get("type").copyString()));
CHECK((slice.hasKey("unusedKey") && slice.get("unusedKey").isString() && std::string("unusedValue") == slice.get("unusedKey").copyString())); // ensure the original definition is fully stored
}
// includeProperties
@ -481,9 +481,9 @@ SECTION("test_toVelocyPack") {
builder.close();
auto slice = builder.slice();
CHECK((4 == slice.length()));
CHECK((slice.hasKey("id") && slice.get("id").isString() && std::string("2") == slice.get("id").copyString()));
CHECK((slice.hasKey("name") && slice.get("name").isString() && std::string("testView") == slice.get("name").copyString()));
CHECK((slice.hasKey("type") && slice.get("type").isString() && arangodb::iresearch::DATA_SOURCE_TYPE.name() == slice.get("type").copyString()));
CHECK((slice.hasKey("unusedKey") && slice.get("unusedKey").isString() && std::string("unusedValue") == slice.get("unusedKey").copyString())); // ensure the original definition is fully stored
CHECK((slice.hasKey("properties")));
auto props = slice.get("properties");
CHECK((props.isObject()));
@ -491,7 +491,7 @@ SECTION("test_toVelocyPack") {
CHECK((props.hasKey("collections") && props.get("collections").isArray() && 0 == props.get("collections").length()));
}
// includeSystem (same as base)
// includeSystem
{
s.agency->responses.clear();
s.agency->responses["POST /_api/agency/read HTTP/1.1\r\n\r\n[[\"/Sync/LatestID\"]]"] = "http/1.0 200\n\n[ { \"\": { \"Sync\": { \"LatestID\" : 1 } } } ]";
@ -509,10 +509,13 @@ SECTION("test_toVelocyPack") {
wiew->toVelocyPack(builder, false, true);
builder.close();
auto slice = builder.slice();
CHECK((3 == slice.length()));
CHECK((6 == slice.length()));
CHECK((slice.hasKey("deleted") && slice.get("deleted").isBoolean() && false == slice.get("deleted").getBoolean()));
CHECK((slice.hasKey("id") && slice.get("id").isString() && std::string("3") == slice.get("id").copyString()));
CHECK((slice.hasKey("isSystem") && slice.get("isSystem").isBoolean() && false == slice.get("isSystem").getBoolean()));
CHECK((slice.hasKey("name") && slice.get("name").isString() && std::string("testView") == slice.get("name").copyString()));
CHECK((slice.hasKey("planId") && slice.get("planId").isString() && std::string("3") == slice.get("planId").copyString()));
CHECK((slice.hasKey("type") && slice.get("type").isString() && arangodb::iresearch::DATA_SOURCE_TYPE.name() == slice.get("type").copyString()));
CHECK((slice.hasKey("unusedKey") && slice.get("unusedKey").isString() && std::string("unusedValue") == slice.get("unusedKey").copyString())); // ensure the original definition is fully stored
}
}
@ -759,7 +762,43 @@ SECTION("test_updateProperties") {
}
SECTION("test_visitCollections") {
// FIXME TODO implemet
// visit empty
{
s.agency->responses.clear();
s.agency->responses["POST /_api/agency/read HTTP/1.1\r\n\r\n[[\"/Sync/LatestID\"]]"] = "http/1.0 200\n\n[ { \"\": { \"Sync\": { \"LatestID\" : 1 } } } ]";
s.agency->responses["POST /_api/agency/write HTTP/1.1"] = "http/1.0 200\n\n{\"results\": []}";
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }");
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto wiew = arangodb::iresearch::IResearchViewDBServer::make(vocbase, json->slice(), 42);
CHECK((false == !wiew));
auto* impl = dynamic_cast<arangodb::iresearch::IResearchViewDBServer*>(wiew.get());
CHECK((nullptr != impl));
static auto visitor = [](TRI_voc_cid_t)->bool { return false; };
CHECK((true == wiew->visitCollections(visitor))); // no collections in view
}
// visit non-empty
{
s.agency->responses.clear();
s.agency->responses["POST /_api/agency/read HTTP/1.1\r\n\r\n[[\"/Sync/LatestID\"]]"] = "http/1.0 200\n\n[ { \"\": { \"Sync\": { \"LatestID\" : 1 } } } ]";
s.agency->responses["POST /_api/agency/write HTTP/1.1"] = "http/1.0 200\n\n{\"results\": []}";
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\", \"type\": \"arangosearch\" }");
TRI_vocbase_t vocbase(TRI_vocbase_type_e::TRI_VOCBASE_TYPE_NORMAL, 1, "testVocbase");
auto wiew = arangodb::iresearch::IResearchViewDBServer::make(vocbase, json->slice(), 42);
CHECK((false == !wiew));
auto* impl = dynamic_cast<arangodb::iresearch::IResearchViewDBServer*>(wiew.get());
CHECK((nullptr != impl));
auto view = impl->ensure(123);
CHECK((false == !view));
std::set<TRI_voc_cid_t> cids = { 123 };
static auto visitor = [&cids](TRI_voc_cid_t cid)->bool { return 1 == cids.erase(cid); };
CHECK((true == wiew->visitCollections(visitor))); // all collections expected
CHECK((true == cids.empty()));
CHECK((true == impl->drop(123).ok()));
CHECK((true == wiew->visitCollections(visitor))); // no collections in view
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -233,8 +233,8 @@ SECTION("test_getDataSource") {
CHECK((true == !resolver.getView("testViewGUID")));
}
CHECK((TRI_ERROR_NO_ERROR == vocbase.dropCollection(collection, true, 0)));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropCollection(collection->id(), true, 0).ok()));
CHECK((true == vocbase.dropView(view->id(), true).ok()));
CHECK((true == collection->deleted()));
CHECK((true == view->deleted()));

View File

@ -338,8 +338,8 @@ SECTION("test_lookupDataSource") {
CHECK((true == !vocbase.lookupView("testViewGUID")));
}
CHECK((TRI_ERROR_NO_ERROR == vocbase.dropCollection(collection, true, 0)));
CHECK((true == vocbase.dropView(*view).ok()));
CHECK((true == vocbase.dropCollection(collection->id(), true, 0).ok()));
CHECK((true == vocbase.dropView(view->id(), true).ok()));
CHECK((true == collection->deleted()));
CHECK((true == view->deleted()));