mirror of https://gitee.com/bigwinds/arangodb
Merge pull request #4977 from arangodb/feature/remove-view-implementation
Feature/remove view implementation
This commit is contained in:
commit
7b7d118873
|
@ -59,6 +59,7 @@ if (USE_IRESEARCH)
|
|||
IResearch/IResearchRocksDBRecoveryHelper.cpp
|
||||
IResearch/IResearchRocksDBRecoveryHelper.h
|
||||
IResearch/IResearchView.cpp IResearch/IResearchView.h
|
||||
IResearch/IResearchViewCoordinator.cpp IResearch/IResearchViewCoordinator.h
|
||||
IResearch/IResearchViewOptimizerRules.cpp IResearch/IResearchViewOptimizerRules.h
|
||||
IResearch/IResearchViewNode.cpp IResearch/IResearchViewNode.h
|
||||
IResearch/IResearchViewBlock.cpp IResearch/IResearchViewBlock.h
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "IResearchFeature.h"
|
||||
#include "IResearchRocksDBRecoveryHelper.h"
|
||||
#include "IResearchView.h"
|
||||
#include "IResearchViewCoordinator.h"
|
||||
#include "ApplicationServerHelper.h"
|
||||
|
||||
#include "RestServer/ViewTypesFeature.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "StorageEngine/TransactionState.h"
|
||||
#include "Transaction/Methods.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "Cluster/ServerState.h"
|
||||
|
||||
#include "Aql/AqlValue.h"
|
||||
#include "Aql/AqlFunctionFeature.h"
|
||||
|
@ -186,9 +188,9 @@ arangodb::Result transactionStateRegistrationCallback(
|
|||
|
||||
// TODO FIXME find a better way to look up an IResearch View
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
#else
|
||||
auto* impl = static_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = static_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
#endif
|
||||
|
||||
if (!impl) {
|
||||
|
@ -269,7 +271,13 @@ void IResearchFeature::prepare() {
|
|||
}
|
||||
|
||||
// register 'arangosearch' view
|
||||
viewTypes->emplace(IResearchView::type(), IResearchView::make);
|
||||
if (arangodb::ServerState::instance()->isCoordinator()) {
|
||||
viewTypes->emplace(IResearchView::type(), IResearchViewCoordinator::make);
|
||||
} else {
|
||||
// DB server in custer or single-server
|
||||
viewTypes->emplace(IResearchView::type(), IResearchView::make);
|
||||
}
|
||||
|
||||
|
||||
// register 'arangosearch' TransactionState state-change callback factory
|
||||
arangodb::transaction::Methods::addStateRegistrationCallback(
|
||||
|
@ -326,4 +334,4 @@ NS_END // arangodb
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -170,8 +170,7 @@ int IResearchLink::drop() {
|
|||
|
||||
// if the collection is in the process of being removed then drop it from the view
|
||||
if (_collection->deleted()) {
|
||||
auto result =
|
||||
_view->updateLogicalProperties(emptyObjectSlice(), true, false); // revalidate all links
|
||||
auto result = _view->updateProperties(emptyObjectSlice(), true, false); // revalidate all links
|
||||
|
||||
if (!result.ok()) {
|
||||
LOG_TOPIC(WARN, iresearch::IResearchFeature::IRESEARCH)
|
||||
|
@ -231,9 +230,9 @@ bool IResearchLink::init(arangodb::velocypack::Slice const& definition) {
|
|||
|
||||
// TODO FIXME find a better way to look up an iResearch View
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto* view = dynamic_cast<IResearchView*>(logicalView->getImplementation());
|
||||
auto* view = dynamic_cast<IResearchView*>(logicalView.get());
|
||||
#else
|
||||
auto* view = static_cast<IResearchView*>(logicalView->getImplementation());
|
||||
auto* view = static_cast<IResearchView*>(logicalView.get());
|
||||
#endif
|
||||
|
||||
if (!view) {
|
||||
|
@ -589,4 +588,4 @@ NS_END // arangodb
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -205,7 +205,11 @@ class IResearchLink {
|
|||
// FIXME TODO remove once View::updateProperties(...) will be fixed to write
|
||||
// the update delta into the WAL marker instead of the full persisted state
|
||||
// FIXME TODO remove #include "IResearchView.h"
|
||||
friend arangodb::Result IResearchView::updateProperties(arangodb::velocypack::Slice const&, bool, bool);
|
||||
// friend arangodb::Result IResearchView::updatePropertiesImpl(
|
||||
// arangodb::velocypack::Slice const&, bool, bool
|
||||
// );
|
||||
friend class IResearchView;
|
||||
|
||||
|
||||
LogicalCollection* _collection; // the linked collection
|
||||
TRI_voc_cid_t _defaultId; // the identifier of the desired view (iff _view == nullptr)
|
||||
|
@ -228,4 +232,4 @@ int EnhanceJsonIResearchLink(
|
|||
NS_END // iresearch
|
||||
NS_END // arangodb
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -218,9 +218,9 @@ void dropCollectionFromAllViews(
|
|||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
|
||||
#else
|
||||
auto* view = static_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto* view = static_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
|
||||
#endif
|
||||
|
||||
if (!view) {
|
||||
|
@ -276,9 +276,9 @@ void dropCollectionFromView(
|
|||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
|
||||
#else
|
||||
auto* view = static_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto* view = static_cast<arangodb::iresearch::IResearchView*>(logicalView.get());
|
||||
#endif
|
||||
|
||||
if (!view) {
|
||||
|
@ -433,4 +433,4 @@ void IResearchRocksDBRecoveryHelper::LogData(const rocksdb::Slice& blob) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "Aql/SortCondition.h"
|
||||
#include "Basics/Result.h"
|
||||
#include "Basics/files.h"
|
||||
#include "Basics/WriteLocker.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Logger/LogMacros.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
|
@ -764,10 +765,11 @@ IResearchView::PersistedStore::PersistedStore(irs::utf8_path&& path)
|
|||
}
|
||||
|
||||
IResearchView::IResearchView(
|
||||
arangodb::LogicalView* view,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
irs::utf8_path&& persistedPath
|
||||
) : ViewImplementation(view, info),
|
||||
TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
irs::utf8_path&& persistedPath,
|
||||
bool isNew
|
||||
) : DBServerLogicalView(vocbase, info, isNew),
|
||||
FlushTransaction(toString(*this)),
|
||||
_asyncMetaRevision(1),
|
||||
_asyncSelf(irs::memory::make_unique<AsyncSelf>(this)),
|
||||
|
@ -1007,13 +1009,25 @@ IResearchView::~IResearchView() {
|
|||
SCOPED_LOCK(mutex);
|
||||
|
||||
if (_storePersisted) {
|
||||
_storePersisted._writer->commit();
|
||||
_storePersisted._writer->close();
|
||||
_storePersisted._writer.reset();
|
||||
_storePersisted._directory->close();
|
||||
_storePersisted._directory.reset();
|
||||
try {
|
||||
_storePersisted._writer->commit();
|
||||
_storePersisted._writer->close();
|
||||
_storePersisted._writer.reset();
|
||||
_storePersisted._directory->close();
|
||||
_storePersisted._directory.reset();
|
||||
} catch (...) {
|
||||
// FIXME add logging
|
||||
// must not propagate exception out of destructor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// noexcept below
|
||||
if (deleted()) {
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
engine->destroyView(vocbase(), this);
|
||||
}
|
||||
}
|
||||
|
||||
IResearchView::MemoryStore& IResearchView::activeMemoryStore() const {
|
||||
|
@ -1028,7 +1042,7 @@ void IResearchView::drop() {
|
|||
std::unordered_set<TRI_voc_cid_t> collections;
|
||||
|
||||
// drop all known links
|
||||
if (_logicalView && _logicalView->vocbase()) {
|
||||
if (vocbase()) {
|
||||
arangodb::velocypack::Builder builder;
|
||||
|
||||
{
|
||||
|
@ -1044,7 +1058,7 @@ void IResearchView::drop() {
|
|||
builder.close();
|
||||
}
|
||||
|
||||
if (!updateLinks(collections, *(_logicalView->vocbase()), *this, builder.slice()).ok()) {
|
||||
if (!updateLinks(collections, *(vocbase()), *this, builder.slice()).ok()) {
|
||||
throw std::runtime_error(std::string("failed to remove links while removing iResearch view '") + std::to_string(id()) + "'");
|
||||
}
|
||||
}
|
||||
|
@ -1069,8 +1083,8 @@ void IResearchView::drop() {
|
|||
|
||||
collections.insert(_meta._collections.begin(), _meta._collections.end());
|
||||
|
||||
if (_logicalView->vocbase()) {
|
||||
validateLinks(collections, *(_logicalView->vocbase()), *this);
|
||||
if (vocbase()) {
|
||||
validateLinks(collections, *(vocbase()), *this);
|
||||
}
|
||||
|
||||
// ArangoDB global consistency check, no known dangling links
|
||||
|
@ -1105,6 +1119,8 @@ void IResearchView::drop() {
|
|||
// remove persisted data store directory if present
|
||||
if (_storePersisted._path.exists_directory(exists)
|
||||
&& (!exists || _storePersisted._path.remove())) {
|
||||
DBServerLogicalView::drop();
|
||||
deleted(true);
|
||||
return; // success
|
||||
}
|
||||
} catch (std::exception const& e) {
|
||||
|
@ -1287,7 +1303,7 @@ void IResearchView::getPropertiesVPack(
|
|||
|
||||
_meta.json(builder);
|
||||
|
||||
if (!_logicalView || !_logicalView->vocbase() || forPersistence) {
|
||||
if (!vocbase() || forPersistence) {
|
||||
return; // nothing more to output (persistent configuration does not need links)
|
||||
}
|
||||
|
||||
|
@ -1296,7 +1312,7 @@ void IResearchView::getPropertiesVPack(
|
|||
// add CIDs of known collections to list
|
||||
for (auto& entry: _meta._collections) {
|
||||
// skip collections missing from vocbase or UserTransaction constructor will throw an exception
|
||||
if (nullptr != _logicalView->vocbase()->lookupCollection(entry)) {
|
||||
if (nullptr != vocbase()->lookupCollection(entry)) {
|
||||
collections.emplace_back(std::to_string(entry));
|
||||
}
|
||||
}
|
||||
|
@ -1312,7 +1328,7 @@ void IResearchView::getPropertiesVPack(
|
|||
|
||||
try {
|
||||
arangodb::transaction::UserTransaction trx(
|
||||
transaction::StandaloneContext::Create(_logicalView->vocbase()),
|
||||
transaction::StandaloneContext::Create(vocbase()),
|
||||
collections, // readCollections
|
||||
EMPTY, // writeCollections
|
||||
EMPTY, // exclusiveCollections
|
||||
|
@ -1375,10 +1391,6 @@ void IResearchView::getPropertiesVPack(
|
|||
builder.add(LINKS_FIELD, linksBuilder.slice());
|
||||
}
|
||||
|
||||
TRI_voc_cid_t IResearchView::id() const noexcept {
|
||||
return _logicalView ? _logicalView->id() : 0; // 0 is an invalid view id
|
||||
}
|
||||
|
||||
int IResearchView::insert(
|
||||
transaction::Methods& trx,
|
||||
TRI_voc_cid_t cid,
|
||||
|
@ -1537,14 +1549,7 @@ arangodb::Result IResearchView::link(
|
|||
TRI_voc_cid_t cid,
|
||||
arangodb::velocypack::Slice const link
|
||||
) {
|
||||
if (!_logicalView) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_INTERNAL,
|
||||
std::string("failed to find logical view while linking IResearch view '") + std::to_string(id()) + "'"
|
||||
);
|
||||
}
|
||||
|
||||
auto* vocbase = _logicalView->vocbase();
|
||||
auto* vocbase = this->vocbase();
|
||||
|
||||
if (!vocbase) {
|
||||
return arangodb::Result(
|
||||
|
@ -1582,14 +1587,17 @@ arangodb::Result IResearchView::link(
|
|||
return result;
|
||||
}
|
||||
|
||||
/*static*/ IResearchView::ptr IResearchView::make(
|
||||
arangodb::LogicalView* view,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
/*static*/ std::shared_ptr<LogicalView> IResearchView::make(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
) {
|
||||
if (!view) {
|
||||
auto const id = readViewId(info);
|
||||
|
||||
if (0 == id) {
|
||||
// invalid ID
|
||||
LOG_TOPIC(WARN, IResearchFeature::IRESEARCH)
|
||||
<< "invalid LogicalView argument while constructing IResearch view";
|
||||
<< "got invalid view identifier while constructing IResearch view";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1598,7 +1606,8 @@ arangodb::Result IResearchView::link(
|
|||
|
||||
if (!feature) {
|
||||
LOG_TOPIC(WARN, IResearchFeature::IRESEARCH)
|
||||
<< "failure to find feature 'DatabasePath' while constructing IResearch view '" << view->id() << "'";
|
||||
<< "failure to find feature 'DatabasePath' while constructing IResearch view '"
|
||||
<< id << "' in database '" << vocbase.id() << "'";
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1613,21 +1622,29 @@ arangodb::Result IResearchView::link(
|
|||
dataPath /= subPath;
|
||||
dataPath /= arangodb::iresearch::IResearchView::type().name();
|
||||
dataPath += "-";
|
||||
dataPath += std::to_string(view->id());
|
||||
dataPath += std::to_string(id);
|
||||
|
||||
auto view = std::shared_ptr<IResearchView>(
|
||||
new IResearchView(&vocbase, info, std::move(dataPath), isNew)
|
||||
);
|
||||
|
||||
auto props = info.get("properties");
|
||||
|
||||
if (props.isNone()) {
|
||||
// if no 'properties' then assume defaults
|
||||
props = emptyObjectSlice();
|
||||
}
|
||||
|
||||
PTR_NAMED(IResearchView, ptr, view, info, std::move(dataPath));
|
||||
auto& impl = reinterpret_cast<IResearchView&>(*ptr);
|
||||
auto& json = info.isNone() ? emptyObjectSlice() : info; // if no 'info' then assume defaults
|
||||
std::string error;
|
||||
|
||||
if (!impl._meta.init(json, error)) {
|
||||
if (!view->_meta.init(props, error)) {
|
||||
LOG_TOPIC(WARN, iresearch::IResearchFeature::IRESEARCH)
|
||||
<< "failed to initialize iResearch view from definition, error: " << error;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(ptr);
|
||||
return view;
|
||||
}
|
||||
|
||||
size_t IResearchView::memory() const {
|
||||
|
@ -1659,6 +1676,8 @@ size_t IResearchView::memory() const {
|
|||
}
|
||||
|
||||
void IResearchView::open() {
|
||||
DBServerLogicalView::open();
|
||||
|
||||
auto* engine = arangodb::EngineSelectorFeature::ENGINE;
|
||||
|
||||
if (engine) {
|
||||
|
@ -1935,30 +1954,40 @@ bool IResearchView::sync(size_t maxMsec /*= 0*/) {
|
|||
return type;
|
||||
}
|
||||
|
||||
arangodb::Result IResearchView::updateLogicalProperties(
|
||||
arangodb::velocypack::Slice const& slice,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
) {
|
||||
return _logicalView
|
||||
? _logicalView->updateProperties(slice, partialUpdate, doSync)
|
||||
: arangodb::Result(TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND)
|
||||
;
|
||||
void IResearchView::toVelocyPack(
|
||||
velocypack::Builder& result,
|
||||
bool includeProperties,
|
||||
bool includeSystem
|
||||
) const {
|
||||
// We write into an open object
|
||||
TRI_ASSERT(result.isOpenObject());
|
||||
|
||||
DBServerLogicalView::toVelocyPack(result, includeProperties, includeSystem);
|
||||
|
||||
// Object is still open
|
||||
TRI_ASSERT(result.isOpenObject());
|
||||
|
||||
if (includeProperties) {
|
||||
// implementation Information
|
||||
result.add("properties", VPackValue(VPackValueType::Object));
|
||||
// note: includeSystem and forPersistence are not 100% synonymous,
|
||||
// however, for our purposes this is an okay mapping; we only set
|
||||
// includeSystem if we are persisting the properties
|
||||
getPropertiesVPack(result, includeSystem);
|
||||
result.close();
|
||||
}
|
||||
|
||||
TRI_ASSERT(result.isOpenObject()); // We leave the object open
|
||||
}
|
||||
|
||||
arangodb::Result IResearchView::updateProperties(
|
||||
arangodb::velocypack::Slice const& slice,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
velocypack::Slice const& slice,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
) {
|
||||
if (!_logicalView) {
|
||||
return arangodb::Result(
|
||||
TRI_ERROR_INTERNAL,
|
||||
std::string("failed to find logical view while updating IResearch view '") + std::to_string(id()) + "'"
|
||||
);
|
||||
}
|
||||
WRITE_LOCKER(writeLocker, _infoLock);
|
||||
|
||||
auto* vocbase = _logicalView->vocbase();
|
||||
auto* vocbase = this->vocbase();
|
||||
|
||||
if (!vocbase) {
|
||||
return arangodb::Result(
|
||||
|
@ -1971,7 +2000,7 @@ arangodb::Result IResearchView::updateProperties(
|
|||
IResearchViewMeta meta;
|
||||
IResearchViewMeta::Mask mask;
|
||||
WriteMutex mutex(_mutex); // '_meta' can be asynchronously read
|
||||
arangodb::Result res = arangodb::Result(/*TRI_ERROR_NO_ERROR*/);
|
||||
arangodb::Result res;
|
||||
|
||||
{
|
||||
SCOPED_LOCK(mutex);
|
||||
|
@ -2115,6 +2144,10 @@ arangodb::Result IResearchView::updateProperties(
|
|||
|
||||
// FIXME TODO to ensure valid recovery remove the original datapath only if the entire, but under lock to prevent double rename
|
||||
|
||||
if (res.ok()) {
|
||||
res = DBServerLogicalView::updateProperties(slice, partialUpdate, doSync);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2151,7 +2184,7 @@ void IResearchView::registerFlushCallback() {
|
|||
}
|
||||
|
||||
bool IResearchView::visitCollections(
|
||||
std::function<bool(TRI_voc_cid_t)> const& visitor
|
||||
LogicalView::CollectionVisitor const& visitor
|
||||
) const {
|
||||
ReadMutex mutex(_mutex);
|
||||
SCOPED_LOCK(mutex);
|
||||
|
@ -2209,14 +2242,14 @@ void IResearchView::verifyKnownCollections() {
|
|||
}
|
||||
|
||||
for (auto cid : cids) {
|
||||
auto collection = _logicalView->vocbase()->lookupCollection(cid);
|
||||
auto collection = vocbase()->lookupCollection(cid);
|
||||
|
||||
if (!collection) {
|
||||
// collection no longer exists, drop it and move on
|
||||
LOG_TOPIC(TRACE, arangodb::iresearch::IResearchFeature::IRESEARCH)
|
||||
<< "collection '" << cid
|
||||
<< "' no longer exists! removing from IResearch view '"
|
||||
<< _logicalView->id() << "'";
|
||||
<< id() << "'";
|
||||
drop(cid);
|
||||
} else {
|
||||
// see if the link still exists, otherwise drop and move on
|
||||
|
@ -2225,7 +2258,7 @@ void IResearchView::verifyKnownCollections() {
|
|||
LOG_TOPIC(TRACE, arangodb::iresearch::IResearchFeature::IRESEARCH)
|
||||
<< "collection '" << cid
|
||||
<< "' no longer linked! removing from IResearch view '"
|
||||
<< _logicalView->id() << "'";
|
||||
<< id() << "'";
|
||||
drop(cid);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,11 @@
|
|||
|
||||
#include "Containers.h"
|
||||
#include "IResearchViewMeta.h"
|
||||
#include "Basics/ReadWriteLock.h"
|
||||
#include "Basics/WriteLocker.h"
|
||||
#include "VocBase/LogicalDataSource.h"
|
||||
#include "VocBase/LocalDocumentId.h"
|
||||
#include "VocBase/ViewImplementation.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "Utils/FlushTransaction.h"
|
||||
|
||||
#include "store/directory.hpp"
|
||||
|
@ -98,7 +100,7 @@ class PrimaryKeyIndexReader: public irs::index_reader {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief an abstraction over the IResearch index implementing the
|
||||
/// ViewImplementation interface
|
||||
/// LogicalView interface
|
||||
/// @note the responsibility of the IResearchView API is to only manage the
|
||||
/// IResearch data store, i.e. insert/remove/query
|
||||
/// the IResearchView API does not manage which and how the data gets
|
||||
|
@ -107,12 +109,9 @@ class PrimaryKeyIndexReader: public irs::index_reader {
|
|||
/// which may be, but are not explicitly required to be, triggered via
|
||||
/// the IResearchLink or IResearchViewBlock
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class IResearchView final: public arangodb::ViewImplementation,
|
||||
class IResearchView final: public arangodb::DBServerLogicalView,
|
||||
public arangodb::FlushTransaction {
|
||||
public:
|
||||
typedef std::unique_ptr<arangodb::ViewImplementation> ptr;
|
||||
typedef std::shared_ptr<IResearchView> sptr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief AsyncValue holding the view itself, modifiable by IResearchView
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -128,6 +127,8 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
virtual ~IResearchView();
|
||||
|
||||
using arangodb::LogicalView::name;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief apply any changes to 'state' required by this view
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -150,20 +151,6 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
int drop(TRI_voc_cid_t cid);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fill and return a JSON description of a IResearchView object
|
||||
/// only fields describing the view itself, not 'link' descriptions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void getPropertiesVPack(
|
||||
arangodb::velocypack::Builder& builder,
|
||||
bool forPersistence
|
||||
) const override;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the id identifying the current iResearch View or '0' if unknown
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
TRI_voc_cid_t id() const noexcept;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief insert a document into this IResearch View and the underlying
|
||||
/// IResearch stores
|
||||
|
@ -205,8 +192,8 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
/// @brief view factory
|
||||
/// @returns initialized view object
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static ptr make(
|
||||
arangodb::LogicalView* view,
|
||||
static std::shared_ptr<LogicalView> make(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
);
|
||||
|
@ -259,15 +246,11 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
static arangodb::LogicalDataSource::Type const& type() noexcept;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief update the view properties via the LogicalView allowing for tracking
|
||||
/// update via WAL entries
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
arangodb::Result updateLogicalProperties(
|
||||
arangodb::velocypack::Slice const& slice,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
);
|
||||
void toVelocyPack(
|
||||
velocypack::Builder& result,
|
||||
bool includeProperties,
|
||||
bool includeSystem
|
||||
) const override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief called when a view's properties are updated (i.e. delta-modified)
|
||||
|
@ -282,9 +265,7 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
/// @brief visit all collection IDs that were added to the view
|
||||
/// @return 'visitor' success
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
bool visitCollections(
|
||||
std::function<bool(TRI_voc_cid_t)> const& visitor
|
||||
) const override;
|
||||
bool visitCollections(CollectionVisitor const& visitor) const override;
|
||||
|
||||
private:
|
||||
struct DataStore {
|
||||
|
@ -334,11 +315,21 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
> FlushTransactionPtr;
|
||||
|
||||
IResearchView(
|
||||
arangodb::LogicalView*,
|
||||
TRI_vocbase_t* vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
irs::utf8_path&& persistedPath
|
||||
irs::utf8_path&& persistedPath,
|
||||
bool isNew
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief fill and return a JSON description of a IResearchView object
|
||||
/// only fields describing the view itself, not 'link' descriptions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void getPropertiesVPack(
|
||||
arangodb::velocypack::Builder& builder,
|
||||
bool forPersistence
|
||||
) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Called in post-recovery to remove any dangling documents old links
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -374,8 +365,11 @@ class IResearchView final: public arangodb::ViewImplementation,
|
|||
std::function<void(arangodb::TransactionState& state)> _trxReadCallback; // for snapshot(...)
|
||||
std::function<void(arangodb::TransactionState& state)> _trxWriteCallback; // for insert(...)/remove(...)
|
||||
std::atomic<bool> _inRecovery;
|
||||
|
||||
// FIXME came from "LogicalView", check whether it needs to be there
|
||||
mutable basics::ReadWriteLock _infoLock; // lock protecting the properties
|
||||
};
|
||||
|
||||
NS_END // iresearch
|
||||
NS_END // arangodb
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#include "IResearchViewCoordinator.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace iresearch {
|
||||
|
||||
/*static*/ std::shared_ptr<LogicalView> IResearchViewCoordinator::make(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
) {
|
||||
// FIXME implement
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
} // iresearch
|
||||
} // arangodb
|
|
@ -0,0 +1,81 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2018 ArangoDB 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Andrey Abramov
|
||||
/// @author Vasiliy Nabatchikov
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGODB_IRESEARCH__IRESEARCH_VIEW_COORDINATOR_H
|
||||
#define ARANGODB_IRESEARCH__IRESEARCH_VIEW_COORDINATOR_H 1
|
||||
|
||||
#include "VocBase/LogicalView.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace iresearch {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @class IResearchViewCoordinator
|
||||
/// @brief an abstraction over the distributed IResearch index implementing the
|
||||
/// LogicalView interface
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class IResearchViewCoordinator final: public arangodb::LogicalView {
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief view factory
|
||||
/// @returns initialized view object
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static std::shared_ptr<LogicalView> make(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
);
|
||||
|
||||
bool visitCollections(CollectionVisitor const& visitor) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void open() override { }
|
||||
|
||||
void drop() override { }
|
||||
|
||||
virtual Result rename(std::string&& newName, bool doSync) {
|
||||
return { TRI_ERROR_NOT_IMPLEMENTED };
|
||||
}
|
||||
|
||||
virtual void toVelocyPack(
|
||||
arangodb::velocypack::Builder& result,
|
||||
bool includeProperties = false,
|
||||
bool includeSystem = false
|
||||
) const {
|
||||
// FIXME: implement
|
||||
}
|
||||
|
||||
virtual arangodb::Result updateProperties(
|
||||
arangodb::velocypack::Slice const& properties,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
) {
|
||||
return { TRI_ERROR_NOT_IMPLEMENTED };
|
||||
}
|
||||
}; // IResearchViewCoordinator
|
||||
|
||||
} // iresearch
|
||||
} // arangodb
|
||||
|
||||
#endif // ARANGODB_IRESEARCH__IRESEARCH_VIEW_COORDINATOR_H
|
|
@ -279,9 +279,9 @@ std::unique_ptr<aql::ExecutionBlock> IResearchViewNode::createBlock(
|
|||
std::unordered_set<std::string> const&
|
||||
) const {
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto* impl = dynamic_cast<IResearchView*>(view()->getImplementation());
|
||||
auto* impl = dynamic_cast<IResearchView*>(view().get());
|
||||
#else
|
||||
auto* impl = static_cast<IResearchView*>(view()->getImplementation());
|
||||
auto* impl = static_cast<IResearchView*>(view().get());
|
||||
#endif
|
||||
|
||||
if (!impl) {
|
||||
|
|
|
@ -2040,8 +2040,9 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
std::string const& name,
|
||||
bool wasCleanShutdown,
|
||||
bool isUpgrade) {
|
||||
auto vocbase =
|
||||
std::make_unique<TRI_vocbase_t>(TRI_VOCBASE_TYPE_NORMAL, id, name);
|
||||
auto vocbase = std::make_unique<TRI_vocbase_t>(
|
||||
TRI_VOCBASE_TYPE_NORMAL, id, name
|
||||
);
|
||||
|
||||
// scan the database path for views
|
||||
try {
|
||||
|
@ -2055,7 +2056,7 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
VPackSlice slice = builder.slice();
|
||||
TRI_ASSERT(slice.isArray());
|
||||
|
||||
ViewTypesFeature* viewTypesFeature =
|
||||
auto const* viewTypes =
|
||||
application_features::ApplicationServer::getFeature<ViewTypesFeature>(
|
||||
"ViewTypes");
|
||||
|
||||
|
@ -2063,11 +2064,11 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
// we found a view that is still active
|
||||
LOG_TOPIC(TRACE, Logger::FIXME) << "processing view: " << it.toJson();
|
||||
|
||||
arangodb::velocypack::StringRef type(it.get("type"));
|
||||
auto& dataSourceType = arangodb::LogicalDataSource::Type::emplace(type);
|
||||
auto& creator = viewTypesFeature->factory(dataSourceType);
|
||||
arangodb::velocypack::StringRef const type(it.get("type"));
|
||||
auto const& dataSourceType = arangodb::LogicalDataSource::Type::emplace(type);
|
||||
auto const& viewFactory = viewTypes->factory(dataSourceType);
|
||||
|
||||
if (!creator) {
|
||||
if (!viewFactory) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"no handler found for view type"
|
||||
|
@ -2085,18 +2086,21 @@ TRI_vocbase_t* MMFilesEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
);
|
||||
}
|
||||
|
||||
auto view = std::make_shared<arangodb::LogicalView>(vocbase.get(), it);
|
||||
auto view = viewFactory(*vocbase, it, false);
|
||||
|
||||
if (!view) {
|
||||
auto const message =
|
||||
"failed to instantiate view of type "
|
||||
+ dataSourceType.name();
|
||||
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message.c_str());
|
||||
}
|
||||
|
||||
StorageEngine::registerView(vocbase.get(), view);
|
||||
|
||||
registerViewPath(vocbase->id(), view->id(), viewPath);
|
||||
|
||||
view->spawnImplementation(creator, it, false);
|
||||
|
||||
if (view->getImplementation() == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unable to spawn view implementation");
|
||||
}
|
||||
view->getImplementation()->open();
|
||||
view->open();
|
||||
}
|
||||
} catch (std::exception const& ex) {
|
||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "error while opening database views: "
|
||||
|
|
|
@ -124,7 +124,7 @@ void RestViewHandler::createView() {
|
|||
if (view != nullptr) {
|
||||
VPackBuilder props;
|
||||
props.openObject();
|
||||
view->toVelocyPack(props);
|
||||
view->toVelocyPack(props, false, false);
|
||||
props.close();
|
||||
generateResult(rest::ResponseCode::CREATED, props.slice());
|
||||
} else {
|
||||
|
@ -194,12 +194,14 @@ void RestViewHandler::modifyView(bool partialUpdate) {
|
|||
return;
|
||||
}
|
||||
|
||||
auto result = view->updateProperties(body, partialUpdate,
|
||||
true); // TODO: not force sync?
|
||||
auto const result = view->updateProperties(
|
||||
body, partialUpdate, true
|
||||
); // TODO: not force sync?
|
||||
|
||||
if (result.ok()) {
|
||||
VPackBuilder updated;
|
||||
updated.openObject();
|
||||
view->getImplementation()->getPropertiesVPack(updated, false);
|
||||
view->toVelocyPack(updated, false, false);
|
||||
updated.close();
|
||||
generateResult(rest::ResponseCode::OK, updated.slice());
|
||||
return;
|
||||
|
@ -283,7 +285,7 @@ void RestViewHandler::getListOfViews() {
|
|||
for (std::shared_ptr<LogicalView> view : views) {
|
||||
if (view.get() != nullptr) {
|
||||
props.openObject();
|
||||
view->toVelocyPack(props, true);
|
||||
view->toVelocyPack(props, true, false);
|
||||
props.close();
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +299,7 @@ void RestViewHandler::getSingleView(std::string const& name) {
|
|||
if (view.get() != nullptr) {
|
||||
VPackBuilder props;
|
||||
props.openObject();
|
||||
view->toVelocyPack(props, true);
|
||||
view->toVelocyPack(props, true, false);
|
||||
props.close();
|
||||
generateResult(rest::ResponseCode::OK, props.slice());
|
||||
} else {
|
||||
|
@ -312,7 +314,7 @@ void RestViewHandler::getViewProperties(std::string const& name) {
|
|||
if (view.get() != nullptr) {
|
||||
VPackBuilder props;
|
||||
props.openObject();
|
||||
view->getImplementation()->getPropertiesVPack(props, false);
|
||||
view->toVelocyPack(props, false, false);
|
||||
props.close();
|
||||
generateResult(rest::ResponseCode::OK, props.slice());
|
||||
} else {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
namespace {
|
||||
|
||||
std::string const FEATURE_NAME("ViewTypes");
|
||||
arangodb::ViewCreator const INVALID{};
|
||||
arangodb::ViewFactory const INVALID{};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -45,12 +45,12 @@ ViewTypesFeature::ViewTypesFeature(
|
|||
|
||||
bool ViewTypesFeature::emplace(
|
||||
LogicalDataSource::Type const& type,
|
||||
ViewCreator creator
|
||||
ViewFactory const& creator
|
||||
) {
|
||||
return _factories.emplace(&type, creator).second;
|
||||
}
|
||||
|
||||
ViewCreator const& ViewTypesFeature::factory(
|
||||
ViewFactory const& ViewTypesFeature::factory(
|
||||
LogicalDataSource::Type const& type
|
||||
) const noexcept {
|
||||
auto itr = _factories.find(&type);
|
||||
|
@ -62,10 +62,11 @@ ViewCreator const& ViewTypesFeature::factory(
|
|||
return FEATURE_NAME;
|
||||
}
|
||||
|
||||
void ViewTypesFeature::prepare() {
|
||||
}
|
||||
void ViewTypesFeature::prepare() { }
|
||||
|
||||
void ViewTypesFeature::unprepare() { _factories.clear(); }
|
||||
void ViewTypesFeature::unprepare() {
|
||||
_factories.clear();
|
||||
}
|
||||
|
||||
} // arangodb
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
#include "VocBase/LogicalDataSource.h"
|
||||
#include "VocBase/ViewImplementation.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
|
||||
namespace arangodb {
|
||||
|
||||
|
@ -35,10 +35,10 @@ class ViewTypesFeature final: public application_features::ApplicationFeature {
|
|||
|
||||
public:
|
||||
/// @return 'factory' for 'type' was added successfully
|
||||
bool emplace(LogicalDataSource::Type const& type, ViewCreator factory);
|
||||
bool emplace(LogicalDataSource::Type const& type, ViewFactory const& factory);
|
||||
|
||||
/// @return factory for the specified type or false if no such type
|
||||
ViewCreator const& factory(
|
||||
ViewFactory const& factory(
|
||||
LogicalDataSource::Type const& type
|
||||
) const noexcept;
|
||||
|
||||
|
@ -47,9 +47,9 @@ class ViewTypesFeature final: public application_features::ApplicationFeature {
|
|||
void unprepare() override final;
|
||||
|
||||
private:
|
||||
std::unordered_map<LogicalDataSource::Type const*, arangodb::ViewCreator> _factories;
|
||||
std::unordered_map<LogicalDataSource::Type const*, arangodb::ViewFactory> _factories;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1687,20 +1687,20 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
|
||||
VPackSlice slice = builder.slice();
|
||||
VPackSlice const slice = builder.slice();
|
||||
TRI_ASSERT(slice.isArray());
|
||||
|
||||
ViewTypesFeature* viewTypesFeature =
|
||||
auto const* viewTypes =
|
||||
application_features::ApplicationServer::getFeature<ViewTypesFeature>(
|
||||
"ViewTypes");
|
||||
|
||||
for (auto const& it : VPackArrayIterator(slice)) {
|
||||
// we found a view that is still active
|
||||
arangodb::velocypack::StringRef type(it.get("type"));
|
||||
auto& dataSourceType = arangodb::LogicalDataSource::Type::emplace(type);
|
||||
auto& creator = viewTypesFeature->factory(dataSourceType);
|
||||
arangodb::velocypack::StringRef const type(it.get("type"));
|
||||
auto const& dataSourceType = arangodb::LogicalDataSource::Type::emplace(type);
|
||||
auto const& viewFactory = viewTypes->factory(dataSourceType);
|
||||
|
||||
if (!creator) {
|
||||
if (!viewFactory) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"no handler found for view type"
|
||||
|
@ -1709,12 +1709,19 @@ TRI_vocbase_t* RocksDBEngine::openExistingDatabase(TRI_voc_tick_t id,
|
|||
|
||||
TRI_ASSERT(!it.get("id").isNone());
|
||||
|
||||
auto view = std::make_shared<arangodb::LogicalView>(vocbase.get(), it);
|
||||
auto view = viewFactory(*vocbase, it, false);
|
||||
|
||||
if (!view) {
|
||||
auto const message =
|
||||
"failed to instantiate view of type "
|
||||
+ dataSourceType.name();
|
||||
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message.c_str());
|
||||
}
|
||||
|
||||
StorageEngine::registerView(vocbase.get(), view);
|
||||
|
||||
view->spawnImplementation(creator, it, false);
|
||||
view->getImplementation()->open();
|
||||
view->open();
|
||||
}
|
||||
} catch (std::exception const& ex) {
|
||||
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "error while opening database: "
|
||||
|
|
|
@ -435,7 +435,7 @@ static void JS_PropertiesViewVocbase(
|
|||
|
||||
VPackBuilder vpackProperties;
|
||||
vpackProperties.openObject();
|
||||
view->toVelocyPack(vpackProperties, true);
|
||||
view->toVelocyPack(vpackProperties, true, false);
|
||||
vpackProperties.close();
|
||||
|
||||
// return the current parameter set
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "Basics/ReadLocker.h"
|
||||
#include "Basics/Result.h"
|
||||
#include "Basics/VelocyPackHelper.h"
|
||||
#include "Basics/WriteLocker.h"
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Cluster/ClusterInfo.h"
|
||||
#include "Cluster/ServerState.h"
|
||||
#include "StorageEngine/EngineSelectorFeature.h"
|
||||
|
@ -38,27 +38,6 @@ using Helper = arangodb::basics::VelocyPackHelper;
|
|||
|
||||
namespace {
|
||||
|
||||
TRI_voc_cid_t ReadId(VPackSlice info) {
|
||||
if (!info.isObject()) {
|
||||
// ERROR CASE
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Somehow the id is now propagated to dbservers
|
||||
TRI_voc_cid_t id = Helper::extractIdValue(info);
|
||||
|
||||
if (id == 0) {
|
||||
if (ServerState::instance()->isDBServer()) {
|
||||
id = ClusterInfo::instance()->uniqid(1);
|
||||
} else if (ServerState::instance()->isCoordinator()) {
|
||||
id = ClusterInfo::instance()->uniqid(1);
|
||||
} else {
|
||||
id = TRI_NewTickServer();
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
TRI_voc_cid_t ReadPlanId(VPackSlice info, TRI_voc_cid_t vid) {
|
||||
if (!info.isObject()) {
|
||||
// ERROR CASE
|
||||
|
@ -82,6 +61,31 @@ TRI_voc_cid_t ReadPlanId(VPackSlice info, TRI_voc_cid_t vid) {
|
|||
|
||||
} // namespace
|
||||
|
||||
/*static*/ TRI_voc_cid_t LogicalView::readViewId(VPackSlice info) {
|
||||
if (!info.isObject()) {
|
||||
// ERROR CASE
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Somehow the id is now propagated to dbservers
|
||||
TRI_voc_cid_t id = Helper::extractIdValue(info);
|
||||
|
||||
if (id == 0) {
|
||||
if (ServerState::instance()->isDBServer()) {
|
||||
id = ClusterInfo::instance()->uniqid(1);
|
||||
} else if (ServerState::instance()->isCoordinator()) {
|
||||
id = ClusterInfo::instance()->uniqid(1);
|
||||
} else {
|
||||
id = TRI_NewTickServer();
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- LogicalView
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/*static*/ LogicalDataSource::Category const& LogicalView::category() noexcept {
|
||||
static const Category category;
|
||||
|
||||
|
@ -98,7 +102,7 @@ LogicalView::LogicalView(TRI_vocbase_t* vocbase, VPackSlice const& info)
|
|||
arangodb::basics::VelocyPackHelper::getStringRef(info, "type", "")
|
||||
),
|
||||
vocbase,
|
||||
ReadId(info),
|
||||
LogicalView::readViewId(info),
|
||||
ReadPlanId(info, 0),
|
||||
arangodb::basics::VelocyPackHelper::getStringValue(info, "name", ""),
|
||||
Helper::readBooleanValue(info, "deleted", false)
|
||||
|
@ -111,7 +115,19 @@ LogicalView::LogicalView(TRI_vocbase_t* vocbase, VPackSlice const& info)
|
|||
TRI_UpdateTickServer(static_cast<TRI_voc_tick_t>(id()));
|
||||
}
|
||||
|
||||
LogicalView::~LogicalView() {
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- DBServerLogicalView
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
DBServerLogicalView::DBServerLogicalView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
VPackSlice const& info,
|
||||
bool isNew
|
||||
) : LogicalView(vocbase, info),
|
||||
_isNew(isNew) {
|
||||
}
|
||||
|
||||
DBServerLogicalView::~DBServerLogicalView() {
|
||||
if (deleted()) {
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
|
@ -119,7 +135,28 @@ LogicalView::~LogicalView() {
|
|||
}
|
||||
}
|
||||
|
||||
Result LogicalView::rename(std::string&& newName, bool doSync) {
|
||||
void DBServerLogicalView::open() {
|
||||
// Coordinators are not allowed to have local views!
|
||||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||
|
||||
if (!_isNew) {
|
||||
return;
|
||||
}
|
||||
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
engine->createView(vocbase(), id(), this);
|
||||
_isNew = false;
|
||||
}
|
||||
|
||||
void DBServerLogicalView::drop() {
|
||||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
engine->dropView(vocbase(), this);
|
||||
}
|
||||
|
||||
Result DBServerLogicalView::rename(std::string&& newName, bool doSync) {
|
||||
auto oldName = name();
|
||||
|
||||
try {
|
||||
|
@ -144,22 +181,9 @@ Result LogicalView::rename(std::string&& newName, bool doSync) {
|
|||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
void LogicalView::drop() {
|
||||
deleted(true);
|
||||
|
||||
if (getImplementation() != nullptr) {
|
||||
getImplementation()->drop();
|
||||
}
|
||||
|
||||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
engine->dropView(vocbase(), this);
|
||||
}
|
||||
|
||||
void LogicalView::toVelocyPack(
|
||||
VPackBuilder& result,
|
||||
bool includeProperties,
|
||||
void DBServerLogicalView::toVelocyPack(
|
||||
velocypack::Builder &result,
|
||||
bool /*includeProperties*/,
|
||||
bool includeSystem
|
||||
) const {
|
||||
// We write into an open object
|
||||
|
@ -177,64 +201,31 @@ void LogicalView::toVelocyPack(
|
|||
// Cluster Specific
|
||||
result.add("planId", VPackValue(std::to_string(planId())));
|
||||
|
||||
if (includeSystem) {
|
||||
// storage engine related properties
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine );
|
||||
engine->getViewProperties(vocbase(), this, result);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeProperties && (getImplementation() != nullptr)) {
|
||||
// implementation Information
|
||||
result.add("properties", VPackValue(VPackValueType::Object));
|
||||
// note: includeSystem and forPersistence are not 100% synonymous,
|
||||
// however, for our purposes this is an okay mapping; we only set
|
||||
// includeSystem if we are persisting the properties
|
||||
getImplementation()->getPropertiesVPack(result, includeSystem);
|
||||
result.close();
|
||||
}
|
||||
|
||||
TRI_ASSERT(result.isOpenObject()); // We leave the object open
|
||||
}
|
||||
|
||||
arangodb::Result LogicalView::updateProperties(VPackSlice const& slice,
|
||||
bool partialUpdate,
|
||||
bool doSync) {
|
||||
WRITE_LOCKER(writeLocker, _lock);
|
||||
|
||||
TRI_ASSERT(getImplementation() != nullptr);
|
||||
|
||||
// the implementation may filter/change/react to the changes
|
||||
arangodb::Result implResult =
|
||||
getImplementation()->updateProperties(slice, partialUpdate, doSync);
|
||||
|
||||
if (implResult.ok()) {
|
||||
// after this call the properties are stored
|
||||
// storage engine related properties
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine );
|
||||
engine->getViewProperties(vocbase(), this, result);
|
||||
}
|
||||
}
|
||||
|
||||
arangodb::Result DBServerLogicalView::updateProperties(
|
||||
VPackSlice const& /*slice*/,
|
||||
bool /*partialUpdate*/,
|
||||
bool doSync
|
||||
) {
|
||||
// after this call the properties are stored
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
TRI_ASSERT(engine);
|
||||
|
||||
try {
|
||||
engine->changeView(vocbase(), id(), this, doSync);
|
||||
} catch (arangodb::basics::Exception const& e) {
|
||||
return { e.code() };
|
||||
} catch (...) {
|
||||
return { TRI_ERROR_INTERNAL };
|
||||
}
|
||||
|
||||
return implResult;
|
||||
}
|
||||
|
||||
/// @brief Persist the connected physical view
|
||||
/// This should be called AFTER the view is successfully
|
||||
/// created and only on Single/DBServer
|
||||
void LogicalView::persistPhysicalView() {
|
||||
// Coordinators are not allowed to have local views!
|
||||
TRI_ASSERT(!ServerState::instance()->isCoordinator());
|
||||
|
||||
// We have not yet persisted this view
|
||||
StorageEngine* engine = EngineSelectorFeature::ENGINE;
|
||||
engine->createView(vocbase(), id(), this);
|
||||
}
|
||||
|
||||
void LogicalView::spawnImplementation(
|
||||
ViewCreator creator, arangodb::velocypack::Slice const& parameters,
|
||||
bool isNew) {
|
||||
_implementation = creator(this, parameters.get("properties"), isNew);
|
||||
return {};
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
|
||||
#include "LogicalDataSource.h"
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/ReadWriteLock.h"
|
||||
#include "Basics/Result.h"
|
||||
#include "VocBase/ViewImplementation.h"
|
||||
#include "Basics/ReadWriteLock.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
|
||||
#include <velocypack/Buffer.h>
|
||||
|
@ -37,72 +36,127 @@ namespace arangodb {
|
|||
|
||||
namespace velocypack {
|
||||
class Slice;
|
||||
class Builder;
|
||||
}
|
||||
|
||||
namespace aql {
|
||||
class ExecutionPlan;
|
||||
struct ExecutionContext;
|
||||
}
|
||||
|
||||
class PhysicalView;
|
||||
|
||||
class LogicalView final: public LogicalDataSource {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @class LogicalView
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class LogicalView : public LogicalDataSource {
|
||||
public:
|
||||
typedef std::function<bool(TRI_voc_cid_t)> CollectionVisitor;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the category representing a logical view
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
static Category const& category() noexcept;
|
||||
|
||||
LogicalView(TRI_vocbase_t* vocbase, velocypack::Slice const& definition);
|
||||
|
||||
~LogicalView() override;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief invoke visitor on all collections that a view will return
|
||||
/// @return visitation was successful
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
bool visitCollections(
|
||||
std::function<bool(TRI_voc_cid_t)> const& visitor
|
||||
) const {
|
||||
return _implementation && _implementation->visitCollections(visitor);
|
||||
}
|
||||
virtual bool visitCollections(CollectionVisitor const& visitor) const = 0;
|
||||
|
||||
ViewImplementation* getImplementation() const {
|
||||
return _implementation.get();
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief opens an existing view when the server is restarted
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual void open() = 0;
|
||||
|
||||
virtual void drop() override;
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief drop an existing view
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual void drop() = 0;
|
||||
|
||||
virtual Result rename(std::string&& newName, bool doSync) override;
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief renames an existing view
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual Result rename(
|
||||
std::string&& newName,
|
||||
bool doSync
|
||||
) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief builds a VelocyPack representation of the node LogicalView
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual void toVelocyPack(
|
||||
velocypack::Builder& result,
|
||||
bool includeProperties,
|
||||
bool includeSystem
|
||||
) const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief updates properties of an existing view
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual arangodb::Result updateProperties(
|
||||
velocypack::Slice const& properties,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
) = 0;
|
||||
|
||||
protected:
|
||||
static TRI_voc_cid_t readViewId(velocypack::Slice slice);
|
||||
|
||||
LogicalView(TRI_vocbase_t* vocbase, velocypack::Slice const& definition);
|
||||
|
||||
private:
|
||||
// FIXME seems to be ugly
|
||||
friend struct ::TRI_vocbase_t;
|
||||
mutable basics::ReadWriteLock _lock;
|
||||
}; // LogicalView
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief typedef for a LogicalView factory function
|
||||
/// This typedef is used when registering the creator function for any view
|
||||
/// type. the creator function is called when a view is first created or
|
||||
/// re-opened after a server restart. the VelocyPack Slice will contain all
|
||||
/// information about the view's general and implementation-specific properties.
|
||||
/// the isNew flag will be true if the view is first created, and false if a
|
||||
/// view is re-opened on a server restart.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
typedef std::function<std::shared_ptr<LogicalView>(
|
||||
TRI_vocbase_t& vocbase, // database
|
||||
arangodb::velocypack::Slice const& properties, // view properties
|
||||
bool isNew
|
||||
)> ViewFactory;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @class DBServerLogicalView
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class DBServerLogicalView : public LogicalView {
|
||||
public:
|
||||
~DBServerLogicalView() override;
|
||||
|
||||
void open() override;
|
||||
|
||||
void drop() override;
|
||||
|
||||
Result rename(
|
||||
std::string&& newName,
|
||||
bool doSync
|
||||
) override final;
|
||||
|
||||
void toVelocyPack(
|
||||
velocypack::Builder& result,
|
||||
bool includeProperties = false,
|
||||
bool includeSystem = false
|
||||
) const;
|
||||
bool includeProperties,
|
||||
bool includeSystem
|
||||
) const override;
|
||||
|
||||
arangodb::Result updateProperties(
|
||||
velocypack::Slice const& properties,
|
||||
bool partialUpdate,
|
||||
bool doSync
|
||||
) override;
|
||||
|
||||
protected:
|
||||
DBServerLogicalView(
|
||||
TRI_vocbase_t* vocbase,
|
||||
velocypack::Slice const& definition,
|
||||
bool isNew
|
||||
);
|
||||
|
||||
/// @brief Persist the connected physical view.
|
||||
/// This should be called AFTER the view is successfully
|
||||
/// created and only on Sinlge/DBServer
|
||||
void persistPhysicalView();
|
||||
|
||||
/// @brief Create implementation object using factory method
|
||||
void spawnImplementation(ViewCreator creator,
|
||||
arangodb::velocypack::Slice const& parameters,
|
||||
bool isNew);
|
||||
|
||||
private:
|
||||
friend struct ::TRI_vocbase_t;
|
||||
|
||||
std::unique_ptr<ViewImplementation> _implementation;
|
||||
mutable basics::ReadWriteLock _lock; // lock protecting the properties
|
||||
};
|
||||
bool _isNew;
|
||||
}; // LogicalView
|
||||
|
||||
} // namespace arangodb
|
||||
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 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 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_VOCBASE_VIEW_IMPLEMENTATION_H
|
||||
#define ARANGOD_VOCBASE_VIEW_IMPLEMENTATION_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
|
||||
#include <velocypack/Builder.h>
|
||||
#include <velocypack/Slice.h>
|
||||
|
||||
namespace arangodb {
|
||||
class LogicalView;
|
||||
class PhysicalView;
|
||||
class Result;
|
||||
class ViewIterator;
|
||||
|
||||
namespace aql {
|
||||
|
||||
class Ast;
|
||||
struct AstNode;
|
||||
class SortCondition;
|
||||
class ExecutionPlan;
|
||||
class ExpressionContext;
|
||||
struct Variable;
|
||||
|
||||
};
|
||||
|
||||
namespace transaction {
|
||||
|
||||
class Methods;
|
||||
|
||||
};
|
||||
|
||||
/// @brief interface for view implementation
|
||||
class ViewImplementation {
|
||||
protected:
|
||||
ViewImplementation(LogicalView* logical,
|
||||
arangodb::velocypack::Slice const& info)
|
||||
: _logicalView(logical) {}
|
||||
|
||||
public:
|
||||
virtual ~ViewImplementation() = default;
|
||||
|
||||
/// @brief called when a view's properties are updated
|
||||
virtual arangodb::Result updateProperties(
|
||||
arangodb::velocypack::Slice const& slice, bool partialUpdate,
|
||||
bool doSync) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief invoke visitor on all collections that a view will return
|
||||
/// @return visitation was successful
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool visitCollections(
|
||||
std::function<bool(TRI_voc_cid_t)> const& visitor
|
||||
) const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief called when a view's properties are materialized into
|
||||
/// the VelocyPack Builder passed into the method. the implementation
|
||||
/// is supposed to fill in all its specific properties. The Builder
|
||||
/// points into an open VelocyPack object. The method is supposed to
|
||||
/// add all its own property attributes with their values, and must
|
||||
/// not close the Builder
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual void getPropertiesVPack(velocypack::Builder&,
|
||||
bool forPersistence) const = 0;
|
||||
|
||||
/// @brief opens an existing view when the server is restarted
|
||||
virtual void open() = 0;
|
||||
|
||||
/// @brief drops an existing view
|
||||
virtual void drop() = 0;
|
||||
|
||||
protected:
|
||||
LogicalView* _logicalView;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief typedef for a ViewImplementation creator function
|
||||
/// This typedef is used when registering the creator function for any view
|
||||
/// type. the creator function is called when a view is first created or
|
||||
/// re-opened after a server restart. the VelocyPack Slice will contain all
|
||||
/// information about the view's general and implementation-specific properties.
|
||||
/// the isNew flag will be true if the view is first created, and false if a
|
||||
/// view is re-opened on a server restart.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
typedef std::function<std::unique_ptr<ViewImplementation>(
|
||||
LogicalView*, arangodb::velocypack::Slice const&, bool isNew)>
|
||||
ViewCreator;
|
||||
|
||||
} // namespace arangodb
|
||||
|
||||
#endif
|
|
@ -64,7 +64,6 @@
|
|||
#include "V8Server/v8-user-structures.h"
|
||||
#include "VocBase/LogicalCollection.h"
|
||||
#include "VocBase/LogicalView.h"
|
||||
#include "VocBase/ViewImplementation.h"
|
||||
#include "VocBase/ticks.h"
|
||||
|
||||
#include <thread>
|
||||
|
@ -315,10 +314,12 @@ bool TRI_vocbase_t::unregisterCollection(
|
|||
auto itr = _dataSourceById.find(collection->id());
|
||||
|
||||
if (itr == _dataSourceById.end()
|
||||
|| !std::dynamic_pointer_cast<arangodb::LogicalCollection>(itr->second)) {
|
||||
|| itr->second->category() != LogicalCollection::category()) {
|
||||
return true; // no such collection
|
||||
}
|
||||
|
||||
TRI_ASSERT(std::dynamic_pointer_cast<arangodb::LogicalCollection>(itr->second));
|
||||
|
||||
// only if we find the collection by its id, we can delete it by name
|
||||
_dataSourceById.erase(itr);
|
||||
|
||||
|
@ -392,10 +393,12 @@ bool TRI_vocbase_t::unregisterView(
|
|||
auto itr = _dataSourceById.find(view->id());
|
||||
|
||||
if (itr == _dataSourceById.end()
|
||||
|| !std::dynamic_pointer_cast<arangodb::LogicalView>(itr->second)) {
|
||||
|| itr->second->category() != arangodb::LogicalView::category()) {
|
||||
return true; // no such view
|
||||
}
|
||||
|
||||
TRI_ASSERT(std::dynamic_pointer_cast<arangodb::LogicalView>(itr->second));
|
||||
|
||||
// only if we find the collection by its id, we can delete it by name
|
||||
_dataSourceById.erase(itr);
|
||||
|
||||
|
@ -892,12 +895,20 @@ std::vector<std::string> TRI_vocbase_t::collectionNames() {
|
|||
result.reserve(_dataSourceByName.size());
|
||||
|
||||
for (auto& entry: _dataSourceByName) {
|
||||
auto collection =
|
||||
std::dynamic_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
TRI_ASSERT(entry.second);
|
||||
|
||||
if (entry.second->category() != LogicalCollection::category()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto view = std::dynamic_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
TRI_ASSERT(view);
|
||||
#else
|
||||
auto view = std::static_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
#endif
|
||||
|
||||
if (collection) {
|
||||
result.emplace_back(entry.first);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1334,10 +1345,12 @@ int TRI_vocbase_t::renameView(
|
|||
auto itr1 = _dataSourceByName.find(oldName);
|
||||
|
||||
if (itr1 == _dataSourceByName.end()
|
||||
|| !std::dynamic_pointer_cast<arangodb::LogicalView>(itr1->second)) {
|
||||
|| arangodb::LogicalView::category() == itr1->second->category()) {
|
||||
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
|
||||
}
|
||||
|
||||
TRI_ASSERT(std::dynamic_pointer_cast<arangodb::LogicalView>(itr1->second));
|
||||
|
||||
_dataSourceByName.emplace(newName, view);
|
||||
_dataSourceByName.erase(oldName);
|
||||
|
||||
|
@ -1443,10 +1456,12 @@ int TRI_vocbase_t::renameCollection(
|
|||
auto itr1 = _dataSourceByName.find(oldName);
|
||||
|
||||
if (itr1 == _dataSourceByName.end()
|
||||
|| !std::dynamic_pointer_cast<arangodb::LogicalCollection>(itr1->second)) {
|
||||
|| arangodb::LogicalCollection::category() != itr1->second->category()) {
|
||||
return TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND;
|
||||
}
|
||||
|
||||
TRI_ASSERT(std::dynamic_pointer_cast<arangodb::LogicalCollection>(itr1->second));
|
||||
|
||||
auto* databaseFeature =
|
||||
application_features::ApplicationServer::getFeature<DatabaseFeature>("Database");
|
||||
TRI_ASSERT(databaseFeature);
|
||||
|
@ -1516,9 +1531,10 @@ arangodb::LogicalCollection* TRI_vocbase_t::useCollection(
|
|||
|
||||
auto it = _dataSourceByName.find(name);
|
||||
|
||||
if (it != _dataSourceByName.end()) {
|
||||
collection =
|
||||
std::dynamic_pointer_cast<arangodb::LogicalCollection>(it->second).get();
|
||||
if (it != _dataSourceByName.end()
|
||||
&& it->second->category() == LogicalCollection::category()) {
|
||||
TRI_ASSERT(std::dynamic_pointer_cast<LogicalCollection>(it->second));
|
||||
collection = static_cast<LogicalCollection*>(it->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1567,23 +1583,24 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createViewWorker(
|
|||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_ILLEGAL_NAME);
|
||||
}
|
||||
|
||||
auto type =
|
||||
auto const type =
|
||||
arangodb::basics::VelocyPackHelper::getStringRef(parameters, "type", "");
|
||||
ViewTypesFeature* viewTypesFeature =
|
||||
auto const* viewTypes =
|
||||
application_features::ApplicationServer::getFeature<ViewTypesFeature>(
|
||||
"ViewTypes");
|
||||
|
||||
if (!viewTypesFeature) {
|
||||
if (!viewTypes) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_INTERNAL,
|
||||
std::string("failed to find feature '") + arangodb::ViewTypesFeature::name() + "'"
|
||||
);
|
||||
}
|
||||
|
||||
auto& dataSourceType = arangodb::LogicalDataSource::Type::emplace(type);
|
||||
auto& creator = viewTypesFeature->factory(dataSourceType);
|
||||
auto const& dataSourceType = arangodb::LogicalDataSource::Type::emplace(type);
|
||||
|
||||
if (!creator) {
|
||||
auto const& viewFactory = viewTypes->factory(dataSourceType);
|
||||
|
||||
if (!viewFactory) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(
|
||||
TRI_ERROR_BAD_PARAMETER,
|
||||
"no handler found for view type"
|
||||
|
@ -1591,7 +1608,15 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createViewWorker(
|
|||
}
|
||||
|
||||
// Try to create a new view. This is not registered yet
|
||||
auto view = std::make_shared<arangodb::LogicalView>(this, parameters);
|
||||
auto view = viewFactory(*this, parameters, true);
|
||||
|
||||
if (!view) {
|
||||
auto const message =
|
||||
"failed to instantiate view of type "
|
||||
+ dataSourceType.name();
|
||||
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER, message.c_str());
|
||||
}
|
||||
|
||||
RECURSIVE_WRITE_LOCKER(_dataSourceLock, _dataSourceLockWriteOwner);
|
||||
|
||||
|
@ -1599,34 +1624,26 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createViewWorker(
|
|||
|
||||
if (it != _dataSourceByName.end()) {
|
||||
events::CreateView(name, TRI_ERROR_ARANGO_DUPLICATE_NAME);
|
||||
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_ARANGO_DUPLICATE_NAME);
|
||||
}
|
||||
|
||||
registerView(basics::ConditionalLocking::DoNotLock, view);
|
||||
|
||||
try {
|
||||
// id might have been assigned
|
||||
id = view->id();
|
||||
|
||||
// now let's actually create the backing implementation
|
||||
view->spawnImplementation(creator, parameters, true);
|
||||
if (view->getImplementation() == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "could not spawn view "
|
||||
"implementation");
|
||||
}
|
||||
|
||||
// Let's try to persist it.
|
||||
view->persistPhysicalView();
|
||||
|
||||
// And lets open it.
|
||||
view->getImplementation()->open();
|
||||
view->open();
|
||||
|
||||
events::CreateView(name, TRI_ERROR_NO_ERROR);
|
||||
return view;
|
||||
} catch (...) {
|
||||
unregisterView(view);
|
||||
throw;
|
||||
}
|
||||
|
||||
// noexcept below
|
||||
id = view->id();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/// @brief creates a new view from parameter set
|
||||
|
@ -1930,12 +1947,20 @@ std::vector<std::shared_ptr<arangodb::LogicalView>> TRI_vocbase_t::views() {
|
|||
views.reserve(_dataSourceById.size());
|
||||
|
||||
for (auto& entry: _dataSourceById) {
|
||||
auto view =
|
||||
std::dynamic_pointer_cast<arangodb::LogicalView>(entry.second);
|
||||
TRI_ASSERT(entry.second);
|
||||
|
||||
if (view) {
|
||||
views.emplace_back(view);
|
||||
if (entry.second->category() != LogicalView::category()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto view = std::dynamic_pointer_cast<arangodb::LogicalView>(entry.second);
|
||||
TRI_ASSERT(view);
|
||||
#else
|
||||
auto view = std::static_pointer_cast<arangodb::LogicalView>(entry.second);
|
||||
#endif
|
||||
|
||||
views.emplace_back(view);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1952,12 +1977,20 @@ void TRI_vocbase_t::processCollections(
|
|||
}
|
||||
} else {
|
||||
for (auto& entry: _dataSourceById) {
|
||||
auto collection =
|
||||
std::dynamic_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
TRI_ASSERT(entry.second);
|
||||
|
||||
if (collection) {
|
||||
cb(collection.get());
|
||||
if (entry.second->category() != LogicalCollection::category()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto collection = std::dynamic_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
TRI_ASSERT(collection);
|
||||
#else
|
||||
auto collection = std::static_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
#endif
|
||||
|
||||
cb(collection.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1980,12 +2013,20 @@ std::vector<arangodb::LogicalCollection*> TRI_vocbase_t::collections(
|
|||
collections.reserve(_dataSourceById.size());
|
||||
|
||||
for (auto& entry: _dataSourceById) {
|
||||
auto collection =
|
||||
std::dynamic_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
TRI_ASSERT(entry.second);
|
||||
|
||||
if (collection) {
|
||||
collections.emplace_back(collection.get());
|
||||
if (entry.second->category() != LogicalCollection::category()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
auto collection = std::dynamic_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
TRI_ASSERT(collection);
|
||||
#else
|
||||
auto collection = std::static_pointer_cast<arangodb::LogicalCollection>(entry.second);
|
||||
#endif
|
||||
|
||||
collections.emplace_back(collection.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "Basics/ReadWriteLock.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/voc-errors.h"
|
||||
#include "VocBase/ViewImplementation.h"
|
||||
#include "VocBase/voc-types.h"
|
||||
|
||||
#include "velocypack/Builder.h"
|
||||
|
@ -455,4 +454,4 @@ void TRI_SanitizeObject(arangodb::velocypack::Slice const slice,
|
|||
void TRI_SanitizeObjectWithEdges(arangodb::velocypack::Slice const slice,
|
||||
arangodb::velocypack::Builder& builder);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -387,9 +387,9 @@ TEST_CASE("IResearchExpressionFilterTest", "[iresearch][iresearch-expression-fil
|
|||
}");
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
}
|
||||
|
||||
|
|
|
@ -227,9 +227,7 @@ SECTION("test_analyzer") {
|
|||
REQUIRE((nullptr != collection0));
|
||||
auto* collection1 = vocbase.createCollection(createCollection1->slice());
|
||||
REQUIRE((nullptr != collection1));
|
||||
auto logicalView = vocbase.createView(createView->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* viewImpl = logicalView->getImplementation();
|
||||
auto viewImpl = vocbase.createView(createView->slice(), 0);
|
||||
REQUIRE((nullptr != viewImpl));
|
||||
|
||||
// populate collections
|
||||
|
@ -346,9 +344,7 @@ SECTION("test_async_index") {
|
|||
REQUIRE((nullptr != collection0));
|
||||
auto* collection1 = vocbase.createCollection(createCollection1->slice());
|
||||
REQUIRE((nullptr != collection1));
|
||||
auto logicalView = vocbase.createView(createView->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* viewImpl = logicalView->getImplementation();
|
||||
auto viewImpl = vocbase.createView(createView->slice(), 0);
|
||||
REQUIRE((nullptr != viewImpl));
|
||||
|
||||
// link collections with view
|
||||
|
@ -547,9 +543,7 @@ SECTION("test_fields") {
|
|||
REQUIRE((nullptr != collection0));
|
||||
auto* collection1 = vocbase.createCollection(createCollection1->slice());
|
||||
REQUIRE((nullptr != collection1));
|
||||
auto logicalView = vocbase.createView(createView->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* viewImpl = logicalView->getImplementation();
|
||||
auto viewImpl = vocbase.createView(createView->slice(), 0);
|
||||
REQUIRE((nullptr != viewImpl));
|
||||
|
||||
// populate collections
|
||||
|
@ -641,4 +635,4 @@ SECTION("test_fields") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -325,9 +325,9 @@ SECTION("test_write") {
|
|||
}");
|
||||
auto* logicalCollection = vocbase.createCollection(collectionJson->slice());
|
||||
REQUIRE((nullptr != logicalCollection));
|
||||
auto logicalView = vocbase.createView(viewJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(viewJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
view->open();
|
||||
auto* flush = arangodb::iresearch::getFeature<arangodb::FlushFeature>("Flush");
|
||||
|
|
|
@ -251,7 +251,7 @@ TEST_CASE("IResearchQueryTestAggregate", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -417,4 +417,4 @@ TEST_CASE("IResearchQueryTestAggregate", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -251,7 +251,7 @@ TEST_CASE("IResearchQueryTestAnd", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -669,4 +669,4 @@ TEST_CASE("IResearchQueryTestAnd", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -258,7 +258,7 @@ TEST_CASE("IResearchQueryTestBooleanTerm", "[iresearch][iresearch-query]") {
|
|||
|
||||
view = logicalView.get();
|
||||
REQUIRE(nullptr != view);
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -2429,4 +2429,4 @@ TEST_CASE("IResearchQueryTestBooleanTerm", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -251,7 +251,7 @@ TEST_CASE("IResearchQueryTestComplexBoolean", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -477,4 +477,4 @@ TEST_CASE("IResearchQueryTestComplexBoolean", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -259,7 +259,7 @@ TEST_CASE("IResearchQueryTestExists", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
|
|
@ -250,7 +250,7 @@ TEST_CASE("IResearchQueryTestIn", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -523,4 +523,4 @@ TEST_CASE("IResearchQueryTestIn", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -340,9 +340,9 @@ TEST_CASE("IResearchQueryTestJoinDuplicateDataSource", "[iresearch][iresearch-qu
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add logical collection with the same name as view
|
||||
|
@ -365,11 +365,15 @@ TEST_CASE("IResearchQueryTestJoinDuplicateDataSource", "[iresearch][iresearch-qu
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
@ -547,9 +551,9 @@ TEST_CASE("IResearchQueryTestJoin", "[iresearch][iresearch-query]") {
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add link to collection
|
||||
|
@ -565,11 +569,15 @@ TEST_CASE("IResearchQueryTestJoin", "[iresearch][iresearch-query]") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ TEST_CASE("IResearchQueryTestNullTerm", "[iresearch][iresearch-query]") {
|
|||
|
||||
view = logicalView.get();
|
||||
REQUIRE(nullptr != view);
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -1452,4 +1452,4 @@ TEST_CASE("IResearchQueryTestNullTerm", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -210,9 +210,9 @@ TEST_CASE("IResearchQueryTestNumericTerm", "[iresearch][iresearch-query]") {
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add link to collection
|
||||
|
@ -228,11 +228,15 @@ TEST_CASE("IResearchQueryTestNumericTerm", "[iresearch][iresearch-query]") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
@ -3136,4 +3140,4 @@ TEST_CASE("IResearchQueryTestNumericTerm", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -201,9 +201,9 @@ TEST_CASE("IResearchQueryTestOr", "[iresearch][iresearch-query]") {
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add link to collection
|
||||
|
@ -219,11 +219,15 @@ TEST_CASE("IResearchQueryTestOr", "[iresearch][iresearch-query]") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
@ -671,4 +675,4 @@ TEST_CASE("IResearchQueryTestOr", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -251,7 +251,7 @@ TEST_CASE("IResearchQueryTestPhrase", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -912,4 +912,4 @@ TEST_CASE("IResearchQueryTestPhrase", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -201,9 +201,9 @@ TEST_CASE("IResearchQueryTestSelectAll", "[iresearch][iresearch-query]") {
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add link to collection
|
||||
|
@ -219,11 +219,15 @@ TEST_CASE("IResearchQueryTestSelectAll", "[iresearch][iresearch-query]") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
@ -507,4 +511,4 @@ TEST_CASE("IResearchQueryTestSelectAll", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -201,9 +201,9 @@ TEST_CASE("IResearchQueryTestStartsWith", "[iresearch][iresearch-query]") {
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add link to collection
|
||||
|
@ -219,11 +219,15 @@ TEST_CASE("IResearchQueryTestStartsWith", "[iresearch][iresearch-query]") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
@ -417,4 +421,4 @@ TEST_CASE("IResearchQueryTestStartsWith", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -238,9 +238,9 @@ TEST_CASE("IResearchQueryTestStringTerm", "[iresearch][iresearch-query]") {
|
|||
}
|
||||
|
||||
// add view
|
||||
auto logicalView = vocbase.createView(createJson->slice(), 0);
|
||||
REQUIRE((false == !logicalView));
|
||||
auto* view = dynamic_cast<arangodb::iresearch::IResearchView*>(logicalView->getImplementation());
|
||||
auto view = std::dynamic_pointer_cast<arangodb::iresearch::IResearchView>(
|
||||
vocbase.createView(createJson->slice(), 0)
|
||||
);
|
||||
REQUIRE((false == !view));
|
||||
|
||||
// add link to collection
|
||||
|
@ -256,11 +256,15 @@ TEST_CASE("IResearchQueryTestStringTerm", "[iresearch][iresearch-query]") {
|
|||
arangodb::velocypack::Builder builder;
|
||||
|
||||
builder.openObject();
|
||||
view->getPropertiesVPack(builder, false);
|
||||
view->toVelocyPack(builder, true, false);
|
||||
builder.close();
|
||||
|
||||
auto slice = builder.slice();
|
||||
auto tmpSlice = slice.get("links");
|
||||
CHECK(slice.isObject());
|
||||
CHECK(slice.get("name").copyString() == "testView");
|
||||
CHECK(slice.get("type").copyString() == arangodb::iresearch::IResearchView::type().name());
|
||||
CHECK(slice.get("deleted").isNone()); // no system properties
|
||||
auto tmpSlice = slice.get("properties").get("links");
|
||||
CHECK((true == tmpSlice.isObject() && 2 == tmpSlice.length()));
|
||||
}
|
||||
|
||||
|
@ -2764,4 +2768,4 @@ TEST_CASE("IResearchQueryTestStringTerm", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -258,7 +258,7 @@ TEST_CASE("IResearchQueryTestTokens", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -419,4 +419,4 @@ TEST_CASE("IResearchQueryTestTokens", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -292,7 +292,7 @@ TEST_CASE("IResearchQueryTestTraversal", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -376,4 +376,4 @@ TEST_CASE("IResearchQueryTestTraversal", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -251,7 +251,7 @@ TEST_CASE("IResearchQueryTestValue", "[iresearch][iresearch-query]") {
|
|||
REQUIRE((false == !logicalView));
|
||||
|
||||
view = logicalView.get();
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view->getImplementation());
|
||||
auto* impl = dynamic_cast<arangodb::iresearch::IResearchView*>(view);
|
||||
REQUIRE((false == !impl));
|
||||
|
||||
auto updateJson = arangodb::velocypack::Parser::fromJson(
|
||||
|
@ -1000,4 +1000,4 @@ TEST_CASE("IResearchQueryTestValue", "[iresearch][iresearch-query]") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -36,20 +36,26 @@
|
|||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<arangodb::ViewImplementation> makeTestView(
|
||||
arangodb::LogicalView* view,
|
||||
std::unique_ptr<arangodb::LogicalView> makeTestView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
) {
|
||||
struct Impl: public arangodb::ViewImplementation {
|
||||
Impl(): ViewImplementation(nullptr, arangodb::velocypack::Slice::emptyObjectSlice()) {
|
||||
struct Impl: public arangodb::LogicalView{
|
||||
Impl(TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& info)
|
||||
: arangodb::LogicalView(&vocbase, info) {
|
||||
}
|
||||
virtual void drop() override {}
|
||||
virtual void getPropertiesVPack(
|
||||
arangodb::velocypack::Builder&, bool
|
||||
virtual void drop() override {
|
||||
deleted(true);
|
||||
}
|
||||
virtual void toVelocyPack(
|
||||
arangodb::velocypack::Builder&, bool, bool
|
||||
) const override {
|
||||
}
|
||||
virtual void open() override {}
|
||||
virtual arangodb::Result rename(std::string&& newName, bool doSync) {
|
||||
return {};
|
||||
}
|
||||
virtual arangodb::Result updateProperties(
|
||||
arangodb::velocypack::Slice const&, bool, bool
|
||||
) override {
|
||||
|
@ -62,7 +68,7 @@ std::unique_ptr<arangodb::ViewImplementation> makeTestView(
|
|||
}
|
||||
};
|
||||
|
||||
return std::unique_ptr<arangodb::ViewImplementation>(new Impl());
|
||||
return std::make_unique<Impl>(vocbase, info);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -260,4 +266,4 @@ SECTION("test_getDataSource") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -64,14 +64,6 @@ SECTION("test_category") {
|
|||
|
||||
CHECK((arangodb::LogicalCollection::category() == instance.category()));
|
||||
}
|
||||
|
||||
// LogicalView
|
||||
{
|
||||
auto json = arangodb::velocypack::Parser::fromJson("{ \"name\": \"testView\" }");
|
||||
arangodb::LogicalView instance(nullptr, json->slice());
|
||||
|
||||
CHECK((arangodb::LogicalView::category() == instance.category()));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -82,4 +74,4 @@ SECTION("test_category") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -33,22 +33,30 @@
|
|||
#include "VocBase/LogicalView.h"
|
||||
#include "velocypack/Parser.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<arangodb::ViewImplementation> makeTestView(
|
||||
arangodb::LogicalView* view,
|
||||
std::unique_ptr<arangodb::LogicalView> makeTestView(
|
||||
TRI_vocbase_t& vocbase,
|
||||
arangodb::velocypack::Slice const& info,
|
||||
bool isNew
|
||||
) {
|
||||
struct Impl: public arangodb::ViewImplementation {
|
||||
Impl(): ViewImplementation(nullptr, arangodb::velocypack::Slice::emptyObjectSlice()) {
|
||||
struct Impl: public arangodb::LogicalView{
|
||||
Impl(TRI_vocbase_t& vocbase, arangodb::velocypack::Slice const& info)
|
||||
: LogicalView(&vocbase, info) {
|
||||
}
|
||||
virtual void drop() override {}
|
||||
virtual void getPropertiesVPack(
|
||||
arangodb::velocypack::Builder&, bool
|
||||
virtual void drop() override {
|
||||
deleted(true);
|
||||
}
|
||||
virtual void toVelocyPack(
|
||||
arangodb::velocypack::Builder&, bool, bool
|
||||
) const override {
|
||||
}
|
||||
virtual void open() override {}
|
||||
virtual arangodb::Result rename(std::string&& newName, bool doSync) {
|
||||
return {};
|
||||
}
|
||||
virtual arangodb::Result updateProperties(
|
||||
arangodb::velocypack::Slice const&, bool, bool
|
||||
) override {
|
||||
|
@ -61,7 +69,7 @@ std::unique_ptr<arangodb::ViewImplementation> makeTestView(
|
|||
}
|
||||
};
|
||||
|
||||
return std::unique_ptr<arangodb::ViewImplementation>(new Impl());
|
||||
return std::make_unique<Impl>(vocbase, info);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -365,4 +373,4 @@ SECTION("test_lookupDataSource") {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue