1
0
Fork 0

code cleanup

This commit is contained in:
Andrey Abramov 2018-03-27 18:39:59 +03:00
parent eaa91592e5
commit 65ea2bfbb9
6 changed files with 313 additions and 345 deletions

View 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)

View File

@ -765,10 +765,11 @@ IResearchView::PersistedStore::PersistedStore(irs::utf8_path&& path)
}
IResearchView::IResearchView(
TRI_vocbase_t* vocbase,
arangodb::velocypack::Slice const& info,
irs::utf8_path&& persistedPath
) : DBServerLogicalView(vocbase, 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)),
@ -1038,8 +1039,103 @@ void IResearchView::apply(arangodb::TransactionState& state) {
}
void IResearchView::drop() {
dropImpl();
DBServerLogicalView::drop();
std::unordered_set<TRI_voc_cid_t> collections;
// drop all known links
if (vocbase()) {
arangodb::velocypack::Builder builder;
{
ReadMutex mutex(_mutex);
SCOPED_LOCK(mutex); // '_meta' and '_trackedCids' can be asynchronously updated
builder.openObject();
if (!appendLinkRemoval(builder, _meta)) {
throw std::runtime_error(std::string("failed to construct link removal directive while removing iResearch view '") + std::to_string(id()) + "'");
}
builder.close();
}
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()) + "'");
}
}
{
WriteMutex mutex(_asyncSelf->_mutex);
SCOPED_LOCK(mutex); // wait for all the view users to finish
_asyncSelf->_value.store(nullptr); // the view data-stores are being deallocated, view use is no longer valid
}
_asyncTerminate.store(true); // mark long-running async jobs for terminatation
{
SCOPED_LOCK(_asyncMutex);
_asyncCondition.notify_all(); // trigger reload of settings for async jobs
}
_threadPool.stop();
WriteMutex mutex(_mutex); // members can be asynchronously updated
SCOPED_LOCK(mutex);
collections.insert(_meta._collections.begin(), _meta._collections.end());
if (vocbase()) {
validateLinks(collections, *(vocbase()), *this);
}
// ArangoDB global consistency check, no known dangling links
if (!collections.empty()) {
throw std::runtime_error(std::string("links still present while removing iResearch view '") + std::to_string(id()) + "'");
}
// ...........................................................................
// if an exception occurs below than a drop retry would most likely happen
// ...........................................................................
try {
_storeByTid.clear();
for (size_t i = 0, count = IRESEARCH_COUNTOF(_memoryNodes); i < count; ++i) {
auto& memoryStore = _memoryNodes[i]._store;
memoryStore._writer->close();
memoryStore._writer.reset();
memoryStore._directory->close();
memoryStore._directory.reset();
}
if (_storePersisted) {
_storePersisted._writer->close();
_storePersisted._writer.reset();
_storePersisted._directory->close();
_storePersisted._directory.reset();
}
bool exists;
// 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) {
LOG_TOPIC(WARN, iresearch::IResearchFeature::IRESEARCH)
<< "caught exception while removing iResearch view '" << id() << "': " << e.what();
IR_LOG_EXCEPTION();
throw;
} catch (...) {
LOG_TOPIC(WARN, iresearch::IResearchFeature::IRESEARCH)
<< "caught exception while removing iResearch view '" << id() << "'";
IR_LOG_EXCEPTION();
throw;
}
throw std::runtime_error(std::string("failed to remove iResearch view '") + arangodb::basics::StringUtils::itoa(id()) + "'");
}
int IResearchView::drop(TRI_voc_cid_t cid) {
@ -1199,271 +1295,6 @@ arangodb::Result IResearchView::commit() {
return {TRI_ERROR_INTERNAL};
}
void IResearchView::dropImpl() {
deleted(true);
std::unordered_set<TRI_voc_cid_t> collections;
// drop all known links
if (vocbase()) {
arangodb::velocypack::Builder builder;
{
ReadMutex mutex(_mutex);
SCOPED_LOCK(mutex); // '_meta' and '_trackedCids' can be asynchronously updated
builder.openObject();
if (!appendLinkRemoval(builder, _meta)) {
throw std::runtime_error(std::string("failed to construct link removal directive while removing iResearch view '") + std::to_string(id()) + "'");
}
builder.close();
}
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()) + "'");
}
}
{
WriteMutex mutex(_asyncSelf->_mutex);
SCOPED_LOCK(mutex); // wait for all the view users to finish
_asyncSelf->_value.store(nullptr); // the view data-stores are being deallocated, view use is no longer valid
}
_asyncTerminate.store(true); // mark long-running async jobs for terminatation
{
SCOPED_LOCK(_asyncMutex);
_asyncCondition.notify_all(); // trigger reload of settings for async jobs
}
_threadPool.stop();
WriteMutex mutex(_mutex); // members can be asynchronously updated
SCOPED_LOCK(mutex);
collections.insert(_meta._collections.begin(), _meta._collections.end());
if (vocbase()) {
validateLinks(collections, *(vocbase()), *this);
}
// ArangoDB global consistency check, no known dangling links
if (!collections.empty()) {
throw std::runtime_error(std::string("links still present while removing iResearch view '") + std::to_string(id()) + "'");
}
// ...........................................................................
// if an exception occurs below than a drop retry would most likely happen
// ...........................................................................
try {
_storeByTid.clear();
for (size_t i = 0, count = IRESEARCH_COUNTOF(_memoryNodes); i < count; ++i) {
auto& memoryStore = _memoryNodes[i]._store;
memoryStore._writer->close();
memoryStore._writer.reset();
memoryStore._directory->close();
memoryStore._directory.reset();
}
if (_storePersisted) {
_storePersisted._writer->close();
_storePersisted._writer.reset();
_storePersisted._directory->close();
_storePersisted._directory.reset();
}
bool exists;
// remove persisted data store directory if present
if (_storePersisted._path.exists_directory(exists)
&& (!exists || _storePersisted._path.remove())) {
return; // success
}
} catch (std::exception const& e) {
LOG_TOPIC(WARN, iresearch::IResearchFeature::IRESEARCH)
<< "caught exception while removing iResearch view '" << id() << "': " << e.what();
IR_LOG_EXCEPTION();
throw;
} catch (...) {
LOG_TOPIC(WARN, iresearch::IResearchFeature::IRESEARCH)
<< "caught exception while removing iResearch view '" << id() << "'";
IR_LOG_EXCEPTION();
throw;
}
throw std::runtime_error(std::string("failed to remove iResearch view '") + arangodb::basics::StringUtils::itoa(id()) + "'");
}
arangodb::Result IResearchView::updatePropertiesImpl(
const velocypack::Slice &slice,
bool partialUpdate,
bool doSync
) {
auto* vocbase = this->vocbase();
if (!vocbase) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to find vocbase while updating links for iResearch view '") + std::to_string(id()) + "'"
);
}
std::string error;
IResearchViewMeta meta;
IResearchViewMeta::Mask mask;
WriteMutex mutex(_mutex); // '_meta' can be asynchronously read
arangodb::Result res = arangodb::Result(/*TRI_ERROR_NO_ERROR*/);
{
SCOPED_LOCK(mutex);
arangodb::velocypack::Builder originalMetaJson; // required for reverting links on failure
if (!_meta.json(arangodb::velocypack::ObjectBuilder(&originalMetaJson))) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to generate json definition while updating iResearch view '") + std::to_string(id()) + "'"
);
}
auto& initialMeta = partialUpdate ? _meta : IResearchViewMeta::DEFAULT();
if (!meta.init(slice, error, initialMeta, &mask)) {
return arangodb::Result(TRI_ERROR_BAD_PARAMETER, std::move(error));
}
// FIXME TODO remove once View::updateProperties(...) will be fixed to write
// the update delta into the WAL marker instead of the full persisted state
// below is a very dangerous hack as it allows multiple links from the same
// collection to point to the same view, thus breaking view data consistency
{
auto* engine = arangodb::EngineSelectorFeature::ENGINE;
if (engine && engine->inRecovery()) {
arangodb::velocypack::Builder linksBuilder;
linksBuilder.openObject();
// remove links no longer present in incming update
for (auto& cid: _meta._collections) {
if (meta._collections.find(cid) == meta._collections.end()) {
linksBuilder.add(
std::to_string(cid),
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Null)
);
}
}
for (auto& cid: meta._collections) {
auto collection = vocbase->lookupCollection(cid);
if (collection) {
_meta._collections.emplace(cid);
for (auto& index: collection->getIndexes()) {
if (index && arangodb::Index::TRI_IDX_TYPE_IRESEARCH_LINK == index->type()) {
auto* link = dynamic_cast<arangodb::iresearch::IResearchLink*>(index.get());
if (link && link->_defaultId == id() && !link->view()) {
arangodb::velocypack::Builder linkBuilder;
bool valid;
linkBuilder.openObject();
valid = link->json(linkBuilder, true);
linkBuilder.close();
linksBuilder.add(
std::to_string(cid),
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Null)
);
if (valid) {
linksBuilder.add(std::to_string(cid), linkBuilder.slice());
}
}
}
}
}
}
std::unordered_set<TRI_voc_cid_t> collections;
linksBuilder.close();
updateLinks(collections, *vocbase, *this, linksBuilder.slice());
collections.insert(_meta._collections.begin(), _meta._collections.end());
validateLinks(collections, *vocbase, *this); // remove invalid cids (no such collection or no such link)
_meta._collections = std::move(collections);
}
}
// reset non-updatable values to match current meta
meta._collections = _meta._collections;
if (mask._threadsMaxIdle) {
_threadPool.max_idle(meta._threadsMaxIdle);
}
if (mask._threadsMaxTotal) {
_threadPool.max_threads(meta._threadsMaxTotal);
}
{
SCOPED_LOCK(_asyncMutex);
_asyncCondition.notify_all(); // trigger reload of timeout settings for async jobs
}
_meta = std::move(meta);
}
std::unordered_set<TRI_voc_cid_t> collections;
// update links if requested (on a best-effort basis)
// indexing of collections is done in different threads so no locks can be held and rollback is not possible
// as a result it's also possible for links to be simultaneously modified via a different callflow (e.g. from collections)
if (slice.hasKey(LINKS_FIELD)) {
if (partialUpdate) {
res = updateLinks(collections, *vocbase, *this, slice.get(LINKS_FIELD));
} else {
arangodb::velocypack::Builder builder;
builder.openObject();
if (!appendLinkRemoval(builder, _meta)
|| !mergeSlice(builder, slice.get(LINKS_FIELD))) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to construct link update directive while updating iResearch view '") + std::to_string(id()) + "'"
);
}
builder.close();
res = updateLinks(collections, *vocbase, *this, builder.slice());
}
}
// ...........................................................................
// if an exception occurs below then it would only affect collection linking
// consistency and an update retry would most likely happen
// always re-validate '_collections' because may have had externally triggered
// collection/link drops
// ...........................................................................
{
SCOPED_LOCK(mutex); // '_meta' can be asynchronously read
collections.insert(_meta._collections.begin(), _meta._collections.end());
validateLinks(collections, *vocbase, *this); // remove invalid cids (no such collection or no such link)
_meta._collections = std::move(collections);
}
// FIXME TODO to ensure valid recovery remove the original datapath only if the entire, but under lock to prevent double rename
return res;
}
void IResearchView::getPropertiesVPack(
arangodb::velocypack::Builder& builder, bool forPersistence
) const {
@ -1757,9 +1588,9 @@ arangodb::Result IResearchView::link(
}
/*static*/ std::shared_ptr<LogicalView> IResearchView::make(
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
TRI_vocbase_t& vocbase,
arangodb::velocypack::Slice const& info,
bool isNew
) {
auto const id = readViewId(info);
@ -1793,8 +1624,8 @@ arangodb::Result IResearchView::link(
dataPath += "-";
dataPath += std::to_string(id);
auto ptr = std::unique_ptr<IResearchView>(
new IResearchView(&vocbase, info, std::move(dataPath))
auto view = std::unique_ptr<IResearchView>(
new IResearchView(&vocbase, info, std::move(dataPath), isNew)
);
auto props = info.get("properties");
@ -1806,14 +1637,14 @@ arangodb::Result IResearchView::link(
std::string error;
if (!ptr->_meta.init(props, 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::shared_ptr<IResearchView>(std::move(ptr));
return std::shared_ptr<IResearchView>(std::move(view));
}
size_t IResearchView::memory() const {
@ -1845,6 +1676,8 @@ size_t IResearchView::memory() const {
}
void IResearchView::open() {
DBServerLogicalView::open();
auto* engine = arangodb::EngineSelectorFeature::ENGINE;
if (engine) {
@ -2121,15 +1954,6 @@ bool IResearchView::sync(size_t maxMsec /*= 0*/) {
return type;
}
arangodb::Result IResearchView::updateLogicalProperties(
arangodb::velocypack::Slice const& slice,
bool partialUpdate,
bool doSync
) {
// FIXME remove
return updateProperties(slice, partialUpdate, doSync);
}
void IResearchView::toVelocyPack(
velocypack::Builder& result,
bool includeProperties,
@ -2157,14 +1981,168 @@ void IResearchView::toVelocyPack(
}
arangodb::Result IResearchView::updateProperties(
arangodb::velocypack::Slice const& slice,
bool partialUpdate,
bool doSync
const velocypack::Slice &slice,
bool partialUpdate,
bool doSync
) {
WRITE_LOCKER(writeLocker, _infoLock);
// the implementation may filter/change/react to the changes
auto res = updatePropertiesImpl(slice, partialUpdate, doSync);
auto* vocbase = this->vocbase();
if (!vocbase) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to find vocbase while updating links for iResearch view '") + std::to_string(id()) + "'"
);
}
std::string error;
IResearchViewMeta meta;
IResearchViewMeta::Mask mask;
WriteMutex mutex(_mutex); // '_meta' can be asynchronously read
arangodb::Result res;
{
SCOPED_LOCK(mutex);
arangodb::velocypack::Builder originalMetaJson; // required for reverting links on failure
if (!_meta.json(arangodb::velocypack::ObjectBuilder(&originalMetaJson))) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to generate json definition while updating iResearch view '") + std::to_string(id()) + "'"
);
}
auto& initialMeta = partialUpdate ? _meta : IResearchViewMeta::DEFAULT();
if (!meta.init(slice, error, initialMeta, &mask)) {
return arangodb::Result(TRI_ERROR_BAD_PARAMETER, std::move(error));
}
// FIXME TODO remove once View::updateProperties(...) will be fixed to write
// the update delta into the WAL marker instead of the full persisted state
// below is a very dangerous hack as it allows multiple links from the same
// collection to point to the same view, thus breaking view data consistency
{
auto* engine = arangodb::EngineSelectorFeature::ENGINE;
if (engine && engine->inRecovery()) {
arangodb::velocypack::Builder linksBuilder;
linksBuilder.openObject();
// remove links no longer present in incming update
for (auto& cid: _meta._collections) {
if (meta._collections.find(cid) == meta._collections.end()) {
linksBuilder.add(
std::to_string(cid),
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Null)
);
}
}
for (auto& cid: meta._collections) {
auto collection = vocbase->lookupCollection(cid);
if (collection) {
_meta._collections.emplace(cid);
for (auto& index: collection->getIndexes()) {
if (index && arangodb::Index::TRI_IDX_TYPE_IRESEARCH_LINK == index->type()) {
auto* link = dynamic_cast<arangodb::iresearch::IResearchLink*>(index.get());
if (link && link->_defaultId == id() && !link->view()) {
arangodb::velocypack::Builder linkBuilder;
bool valid;
linkBuilder.openObject();
valid = link->json(linkBuilder, true);
linkBuilder.close();
linksBuilder.add(
std::to_string(cid),
arangodb::velocypack::Value(arangodb::velocypack::ValueType::Null)
);
if (valid) {
linksBuilder.add(std::to_string(cid), linkBuilder.slice());
}
}
}
}
}
}
std::unordered_set<TRI_voc_cid_t> collections;
linksBuilder.close();
updateLinks(collections, *vocbase, *this, linksBuilder.slice());
collections.insert(_meta._collections.begin(), _meta._collections.end());
validateLinks(collections, *vocbase, *this); // remove invalid cids (no such collection or no such link)
_meta._collections = std::move(collections);
}
}
// reset non-updatable values to match current meta
meta._collections = _meta._collections;
if (mask._threadsMaxIdle) {
_threadPool.max_idle(meta._threadsMaxIdle);
}
if (mask._threadsMaxTotal) {
_threadPool.max_threads(meta._threadsMaxTotal);
}
{
SCOPED_LOCK(_asyncMutex);
_asyncCondition.notify_all(); // trigger reload of timeout settings for async jobs
}
_meta = std::move(meta);
}
std::unordered_set<TRI_voc_cid_t> collections;
// update links if requested (on a best-effort basis)
// indexing of collections is done in different threads so no locks can be held and rollback is not possible
// as a result it's also possible for links to be simultaneously modified via a different callflow (e.g. from collections)
if (slice.hasKey(LINKS_FIELD)) {
if (partialUpdate) {
res = updateLinks(collections, *vocbase, *this, slice.get(LINKS_FIELD));
} else {
arangodb::velocypack::Builder builder;
builder.openObject();
if (!appendLinkRemoval(builder, _meta)
|| !mergeSlice(builder, slice.get(LINKS_FIELD))) {
return arangodb::Result(
TRI_ERROR_INTERNAL,
std::string("failed to construct link update directive while updating iResearch view '") + std::to_string(id()) + "'"
);
}
builder.close();
res = updateLinks(collections, *vocbase, *this, builder.slice());
}
}
// ...........................................................................
// if an exception occurs below then it would only affect collection linking
// consistency and an update retry would most likely happen
// always re-validate '_collections' because may have had externally triggered
// collection/link drops
// ...........................................................................
{
SCOPED_LOCK(mutex); // '_meta' can be asynchronously read
collections.insert(_meta._collections.begin(), _meta._collections.end());
validateLinks(collections, *vocbase, *this); // remove invalid cids (no such collection or no such link)
_meta._collections = std::move(collections);
}
// 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);

View File

@ -246,16 +246,6 @@ class IResearchView final: public arangodb::DBServerLogicalView,
////////////////////////////////////////////////////////////////////////////////
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,
@ -327,15 +317,8 @@ class IResearchView final: public arangodb::DBServerLogicalView,
IResearchView(
TRI_vocbase_t* vocbase,
arangodb::velocypack::Slice const& info,
irs::utf8_path&& persistedPath
);
// FIXME remove
void dropImpl();
arangodb::Result updatePropertiesImpl(
arangodb::velocypack::Slice const& slice,
bool partialUpdate,
bool doSync
irs::utf8_path&& persistedPath,
bool isNew
);
///////////////////////////////////////////////////////////////////////////////

View File

@ -115,26 +115,16 @@ LogicalView::LogicalView(TRI_vocbase_t* vocbase, VPackSlice const& info)
TRI_UpdateTickServer(static_cast<TRI_voc_tick_t>(id()));
}
/// @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);
}
// -----------------------------------------------------------------------------
// --SECTION-- DBServerLogicalView
// -----------------------------------------------------------------------------
DBServerLogicalView::DBServerLogicalView(
TRI_vocbase_t* vocbase,
VPackSlice const& info
) : LogicalView(vocbase, info) {
VPackSlice const& info,
bool isNew
) : LogicalView(vocbase, info),
_isNew(isNew) {
}
DBServerLogicalView::~DBServerLogicalView() {
@ -145,6 +135,20 @@ DBServerLogicalView::~DBServerLogicalView() {
}
}
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;

View File

@ -93,12 +93,6 @@ class LogicalView : public LogicalDataSource {
bool doSync
) = 0;
//FIXME remove
/// @brief Persist the connected physical view.
/// This should be called AFTER the view is successfully
/// created and only on Sinlge/DBServer
void persistPhysicalView();
protected:
static TRI_voc_cid_t readViewId(velocypack::Slice slice);
@ -132,6 +126,8 @@ class DBServerLogicalView : public LogicalView {
public:
~DBServerLogicalView() override;
void open() override;
void drop() override;
Result rename(
@ -152,7 +148,14 @@ class DBServerLogicalView : public LogicalView {
) override;
protected:
DBServerLogicalView(TRI_vocbase_t* vocbase, velocypack::Slice const& definition);
DBServerLogicalView(
TRI_vocbase_t* vocbase,
velocypack::Slice const& definition,
bool isNew
);
private:
bool _isNew;
}; // LogicalView
} // namespace arangodb

View File

@ -314,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);
@ -391,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);
@ -1590,8 +1594,6 @@ std::shared_ptr<arangodb::LogicalView> TRI_vocbase_t::createViewWorker(
);
}
// FIXME first check for existence???
// Try to create a new view. This is not registered yet
auto view = viewFactory(*this, parameters, true);
@ -1609,27 +1611,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();
// Let's try to persist it.
view->persistPhysicalView();
// And lets open it.
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