Add query/db_accessor.hpp which wraps storage implementation

Reviewers: mferencevic, ipaljak

Reviewed By: mferencevic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2361
This commit is contained in:
Teon Banek 2019-09-06 15:29:26 +02:00
parent 13daf1efd6
commit 85b01f8497

910
src/query/db_accessor.hpp Normal file
View File

@ -0,0 +1,910 @@
#pragma once
#include <optional>
#include <cppitertools/filter.hpp>
#include <cppitertools/imap.hpp>
#include "query/exceptions.hpp"
#include "storage/common/types/property_value.hpp"
#include "storage/common/types/types.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/v2/result.hpp"
#include "storage/v2/view.hpp"
#include "storage/vertex_accessor.hpp"
#include "utils/bound.hpp"
#include "utils/exceptions.hpp"
#ifdef MG_SINGLE_NODE_V2
#include "storage/v2/storage.hpp"
#else
#include "database/graph_db_accessor.hpp"
#endif
namespace query {
class VertexAccessor;
#ifdef MG_SINGLE_NODE_V2
class EdgeAccessor final {
public:
storage::EdgeAccessor impl_;
public:
explicit EdgeAccessor(storage::EdgeAccessor impl) : impl_(std::move(impl)) {}
storage::EdgeType EdgeType() const { return impl_.EdgeType(); }
auto Properties(storage::View view) const { return impl_.Properties(view); }
storage::Result<PropertyValue> GetProperty(storage::View view,
storage::Property key) const {
return impl_.GetProperty(key, view);
}
storage::Result<bool> SetProperty(storage::Property key,
const PropertyValue &value) {
return impl_.SetProperty(key, value);
}
storage::Result<bool> RemoveProperty(storage::Property key) {
return SetProperty(key, PropertyValue());
}
utils::BasicResult<storage::Error, void> ClearProperties() {
throw utils::NotYetImplemented("ClearProperties");
}
VertexAccessor To() const;
VertexAccessor From() const;
bool IsCycle() const;
int64_t CypherId() const { return impl_.Gid().AsInt(); }
auto Gid() const { return impl_.Gid(); }
bool operator==(const EdgeAccessor &e) const { return impl_ == e.impl_; }
bool operator!=(const EdgeAccessor &e) const { return !(*this == e); }
friend std::ostream &operator<<(std::ostream &s, const EdgeAccessor &e) {
throw utils::NotYetImplemented("operator<<");
}
};
class VertexAccessor final {
public:
storage::VertexAccessor impl_;
static EdgeAccessor MakeEdgeAccessor(const storage::EdgeAccessor impl) {
return EdgeAccessor(impl);
}
public:
explicit VertexAccessor(storage::VertexAccessor impl)
: impl_(std::move(impl)) {}
auto Labels(storage::View view) const { return impl_.Labels(view); }
storage::Result<bool> AddLabel(storage::Label label) {
return impl_.AddLabel(label);
}
storage::Result<bool> RemoveLabel(storage::Label label) {
return impl_.RemoveLabel(label);
}
storage::Result<bool> HasLabel(storage::View view,
storage::Label label) const {
return impl_.HasLabel(label, view);
}
auto Properties(storage::View view) const { return impl_.Properties(view); }
storage::Result<PropertyValue> GetProperty(storage::View view,
storage::Property key) const {
return impl_.GetProperty(key, view);
}
storage::Result<bool> SetProperty(storage::Property key,
const PropertyValue &value) {
return impl_.SetProperty(key, value);
}
storage::Result<bool> RemoveProperty(storage::Property key) {
return SetProperty(key, PropertyValue());
}
utils::BasicResult<storage::Error, void> ClearProperties() {
throw utils::NotYetImplemented("ClearProperties");
}
auto InEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types) const
-> storage::Result<decltype(
iter::imap(MakeEdgeAccessor, *impl_.InEdges(edge_types, view)))> {
auto maybe_edges = impl_.InEdges(edge_types, view);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto InEdges(storage::View view) const { return InEdges(view, {}); }
auto InEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types,
const VertexAccessor &dest) const
-> storage::Result<decltype(
iter::imap(MakeEdgeAccessor, *impl_.InEdges(edge_types, view)))> {
throw utils::NotYetImplemented("InEdges with set destination");
}
auto OutEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types) const
-> storage::Result<decltype(
iter::imap(MakeEdgeAccessor, *impl_.OutEdges(edge_types, view)))> {
auto maybe_edges = impl_.OutEdges(edge_types, view);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto OutEdges(storage::View view) const { return OutEdges(view, {}); }
auto OutEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types,
const VertexAccessor &dest) const
-> storage::Result<decltype(
iter::imap(MakeEdgeAccessor, *impl_.OutEdges(edge_types, view)))> {
throw utils::NotYetImplemented("OutEdges with set destination");
}
storage::Result<size_t> InDegree(storage::View view) const {
return impl_.InDegree(view);
}
storage::Result<size_t> OutDegree(storage::View view) const {
return impl_.OutDegree(view);
}
int64_t CypherId() const { return impl_.Gid().AsInt(); }
auto Gid() const { return impl_.Gid(); }
bool operator==(const VertexAccessor &v) const { return impl_ == v.impl_; }
bool operator!=(const VertexAccessor &v) const { return !(*this == v); }
friend std::ostream &operator<<(std::ostream &s, const VertexAccessor &v) {
throw utils::NotYetImplemented("operator<<");
}
};
inline VertexAccessor EdgeAccessor::To() const {
return VertexAccessor(impl_.ToVertex());
}
inline VertexAccessor EdgeAccessor::From() const {
return VertexAccessor(impl_.FromVertex());
}
inline bool EdgeAccessor::IsCycle() const { return To() == From(); }
#else
class EdgeAccessor final {
public:
::EdgeAccessor impl_;
private:
void SwitchToView(storage::View view) const {
if (!const_cast<::EdgeAccessor &>(impl_).Reconstruct())
throw ReconstructionException();
switch (view) {
case storage::View::OLD:
const_cast<::EdgeAccessor &>(impl_).SwitchOld();
break;
case storage::View::NEW:
const_cast<::EdgeAccessor &>(impl_).SwitchNew();
break;
}
}
public:
explicit EdgeAccessor(::EdgeAccessor impl) : impl_(impl) {}
storage::EdgeType EdgeType() const { return impl_.EdgeType(); }
storage::Result<PropertyValueStore> Properties(storage::View view) const {
SwitchToView(view);
return impl_.Properties();
}
storage::Result<PropertyValue> GetProperty(storage::View view,
storage::Property key) const {
SwitchToView(view);
return impl_.PropsAt(key);
}
storage::Result<bool> SetProperty(storage::Property key,
const PropertyValue &value) {
SwitchToView(storage::View::NEW);
try {
impl_.PropsSet(key, value);
return true;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
storage::Result<bool> RemoveProperty(storage::Property key) {
SwitchToView(storage::View::NEW);
try {
impl_.PropsErase(key);
return true;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
utils::BasicResult<storage::Error, void> ClearProperties() {
SwitchToView(storage::View::NEW);
try {
impl_.PropsClear();
return {};
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
VertexAccessor To() const;
VertexAccessor From() const;
bool IsCycle() const;
int64_t CypherId() const { return impl_.CypherId(); }
auto Gid() const { return impl_.gid(); }
bool operator==(const EdgeAccessor &e) const { return impl_ == e.impl_; }
bool operator!=(const EdgeAccessor &e) const { return !(*this == e); }
friend std::ostream &operator<<(std::ostream &s, const EdgeAccessor &e) {
return s << e.impl_;
}
};
class VertexAccessor final {
public:
::VertexAccessor impl_;
private:
void SwitchToView(storage::View view) const {
if (!const_cast<::VertexAccessor &>(impl_).Reconstruct())
throw ReconstructionException();
switch (view) {
case storage::View::OLD:
const_cast<::VertexAccessor &>(impl_).SwitchOld();
break;
case storage::View::NEW:
const_cast<::VertexAccessor &>(impl_).SwitchNew();
break;
}
}
static EdgeAccessor MakeEdgeAccessor(const ::EdgeAccessor impl) {
return EdgeAccessor(impl);
}
public:
explicit VertexAccessor(::VertexAccessor impl) : impl_(impl) {}
storage::Result<std::vector<storage::Label>> Labels(
storage::View view) const {
SwitchToView(view);
return impl_.labels();
}
storage::Result<bool> AddLabel(storage::Label label) {
SwitchToView(storage::View::NEW);
try {
impl_.add_label(label);
return true;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
storage::Result<bool> RemoveLabel(storage::Label label) {
SwitchToView(storage::View::NEW);
try {
impl_.remove_label(label);
return true;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
}
}
storage::Result<bool> HasLabel(storage::View view,
storage::Label label) const {
SwitchToView(view);
return impl_.has_label(label);
}
storage::Result<PropertyValueStore> Properties(storage::View view) const {
SwitchToView(view);
return impl_.Properties();
}
storage::Result<PropertyValue> GetProperty(storage::View view,
storage::Property key) const {
SwitchToView(view);
return impl_.PropsAt(key);
}
storage::Result<bool> SetProperty(storage::Property key,
const PropertyValue &value) {
SwitchToView(storage::View::NEW);
try {
impl_.PropsSet(key, value);
return true;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
storage::Result<bool> RemoveProperty(storage::Property key) {
SwitchToView(storage::View::NEW);
try {
impl_.PropsErase(key);
return true;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
utils::BasicResult<storage::Error, void> ClearProperties() {
SwitchToView(storage::View::NEW);
try {
impl_.PropsClear();
return {};
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const database::ConstraintViolationException &e) {
throw QueryRuntimeException(e.what());
}
}
auto InEdges(storage::View view) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, impl_.in()))> {
SwitchToView(view);
return iter::imap(MakeEdgeAccessor, impl_.in());
}
auto InEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor,
impl_.in(&edge_types)))> {
SwitchToView(view);
return iter::imap(MakeEdgeAccessor, impl_.in(&edge_types));
}
auto InEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types,
const VertexAccessor &dest) const
-> storage::Result<decltype(
iter::imap(MakeEdgeAccessor, impl_.in(dest.impl_, &edge_types)))> {
SwitchToView(view);
return iter::imap(MakeEdgeAccessor, impl_.in(dest.impl_, &edge_types));
}
auto OutEdges(storage::View view) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, impl_.out()))> {
SwitchToView(view);
return iter::imap(MakeEdgeAccessor, impl_.out());
}
auto OutEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor,
impl_.out(&edge_types)))> {
SwitchToView(view);
return iter::imap(MakeEdgeAccessor, impl_.out(&edge_types));
}
auto OutEdges(storage::View view,
const std::vector<storage::EdgeType> &edge_types,
const VertexAccessor &dest) const
-> storage::Result<decltype(
iter::imap(MakeEdgeAccessor, impl_.out(dest.impl_, &edge_types)))> {
SwitchToView(view);
return iter::imap(MakeEdgeAccessor, impl_.out(dest.impl_, &edge_types));
}
storage::Result<size_t> InDegree(storage::View view) const {
SwitchToView(view);
return impl_.in_degree();
}
storage::Result<size_t> OutDegree(storage::View view) const {
SwitchToView(view);
return impl_.out_degree();
}
int64_t CypherId() const { return impl_.CypherId(); }
auto Gid() const { return impl_.gid(); }
bool operator==(const VertexAccessor &v) const { return impl_ == v.impl_; }
bool operator!=(const VertexAccessor &v) const { return !(*this == v); }
friend std::ostream &operator<<(std::ostream &s, const VertexAccessor &v) {
return s << v.impl_;
}
};
inline VertexAccessor EdgeAccessor::To() const {
return VertexAccessor(impl_.to());
}
inline VertexAccessor EdgeAccessor::From() const {
return VertexAccessor(impl_.from());
}
inline bool EdgeAccessor::IsCycle() const { return To() == From(); }
#endif
#ifdef MG_SINGLE_NODE_V2
class DbAccessor final {
storage::Storage::Accessor *accessor_;
class VerticesIterable final {
storage::VerticesIterable iterable_;
public:
class Iterator final {
storage::VerticesIterable::Iterator it_;
public:
explicit Iterator(storage::VerticesIterable::Iterator it) : it_(it) {}
VertexAccessor operator*() const { return VertexAccessor(*it_); }
Iterator &operator++() {
++it_;
return *this;
}
bool operator==(const Iterator &other) const { return it_ == other.it_; }
bool operator!=(const Iterator &other) const { return !(other == *this); }
};
explicit VerticesIterable(storage::VerticesIterable iterable)
: iterable_(std::move(iterable)) {}
Iterator begin() { return Iterator(iterable_.begin()); }
Iterator end() { return Iterator(iterable_.end()); }
};
class EdgesIterable final {
public:
class Iterator final {
public:
EdgeAccessor operator*() const {
throw utils::NotYetImplemented("operator*");
}
Iterator &operator++() { throw utils::NotYetImplemented("operator++"); }
bool operator==(const Iterator &other) const {
throw utils::NotYetImplemented("operator==");
}
bool operator!=(const Iterator &other) const { return !(other == *this); }
};
Iterator begin() { throw utils::NotYetImplemented("begin"); }
Iterator end() { throw utils::NotYetImplemented("end"); }
};
public:
explicit DbAccessor(storage::Storage::Accessor *accessor)
: accessor_(accessor) {}
VerticesIterable Vertices(storage::View view) {
return VerticesIterable(accessor_->Vertices(view));
}
VerticesIterable Vertices(storage::View view, storage::Label label) {
return VerticesIterable(accessor_->Vertices(label, view));
}
VerticesIterable Vertices(storage::View view, storage::Label label,
storage::Property property,
const PropertyValue &value) {
return VerticesIterable(accessor_->Vertices(label, property, value, view));
}
VerticesIterable Vertices(
storage::View view, storage::Label label, storage::Property property,
const std::optional<utils::Bound<PropertyValue>> &lower,
const std::optional<utils::Bound<PropertyValue>> &upper) {
return VerticesIterable(
accessor_->Vertices(label, property, lower, upper, view));
}
EdgesIterable Edges(storage::View view) {
throw utils::NotYetImplemented("Edges");
}
VertexAccessor InsertVertex() {
return VertexAccessor(accessor_->CreateVertex());
}
storage::Result<EdgeAccessor> InsertEdge(VertexAccessor *from,
VertexAccessor *to,
const storage::EdgeType &edge_type) {
auto maybe_edge =
accessor_->CreateEdge(&from->impl_, &to->impl_, edge_type);
if (maybe_edge.HasError())
return storage::Result<EdgeAccessor>(maybe_edge.GetError());
return EdgeAccessor(std::move(*maybe_edge));
}
storage::Result<bool> RemoveEdge(EdgeAccessor *edge) {
return accessor_->DeleteEdge(&edge->impl_);
}
storage::Result<bool> DetachRemoveVertex(VertexAccessor *vertex_accessor) {
return accessor_->DetachDeleteVertex(&vertex_accessor->impl_);
}
storage::Result<bool> RemoveVertex(VertexAccessor *vertex_accessor) {
return accessor_->DeleteVertex(&vertex_accessor->impl_);
}
storage::Property NameToProperty(const std::string_view &name) {
// TODO: New storage should work with string_view to avoid needless
// allocation.
return accessor_->NameToProperty(std::string(name));
}
storage::Label NameToLabel(const std::string_view &name) {
return accessor_->NameToLabel(std::string(name));
}
storage::EdgeType NameToEdgeType(const std::string_view &name) {
return accessor_->NameToEdgeType(std::string(name));
}
const std::string &PropertyToName(storage::Property prop) const {
return accessor_->PropertyToName(prop);
}
const std::string &LabelToName(storage::Label label) const {
return accessor_->LabelToName(label);
}
const std::string &EdgeTypeToName(storage::EdgeType type) const {
return accessor_->EdgeTypeToName(type);
}
void AdvanceCommand() { accessor_->AdvanceCommand(); }
bool MustAbort() const { return false; }
bool CreateIndex(storage::Label label, storage::Property prop) {
return accessor_->CreateIndex(label, prop);
}
bool DropIndex(storage::Label label, storage::Property prop) {
return accessor_->DropIndex(label, prop);
}
// TODO: These should probably be in some kind of StorageInfo class instead of
// here.
bool LabelPropertyIndexExists(storage::Label label,
storage::Property prop) const {
return accessor_->LabelPropertyIndexExists(label, prop);
}
int64_t VerticesCount() const { return accessor_->ApproximateVertexCount(); }
int64_t VerticesCount(storage::Label label) const {
return accessor_->ApproximateVertexCount(label);
}
int64_t VerticesCount(storage::Label label,
storage::Property property) const {
return accessor_->ApproximateVertexCount(label, property);
}
int64_t VerticesCount(storage::Label label, storage::Property property,
const PropertyValue &value) const {
return accessor_->ApproximateVertexCount(label, property, value);
}
int64_t VerticesCount(
storage::Label label, storage::Property property,
const std::optional<utils::Bound<PropertyValue>> &lower,
const std::optional<utils::Bound<PropertyValue>> &upper) const {
return accessor_->ApproximateVertexCount(label, property, lower, upper);
}
auto CreateExistenceConstraint(storage::Label label,
storage::Property property) {
return accessor_->CreateExistenceConstraint(label, property);
}
auto DropExistenceConstraint(storage::Label label,
storage::Property property) {
return accessor_->DropExistenceConstraint(label, property);
}
};
#else
class DbAccessor final {
database::GraphDbAccessor *dba_;
template <class TVertices>
class VerticesIterable final {
TVertices vertices_;
class Iterator final {
decltype(vertices_.begin()) it_;
public:
explicit Iterator(decltype(it_) it) : it_(std::move(it)) {}
VertexAccessor operator*() { return VertexAccessor(*it_); }
Iterator &operator++() {
++it_;
return *this;
}
bool operator==(const Iterator &other) const { return other.it_ == it_; }
bool operator!=(const Iterator &other) const { return !(other == *this); }
};
public:
explicit VerticesIterable(TVertices vertices)
: vertices_(std::move(vertices)) {}
Iterator begin() { return Iterator(vertices_.begin()); }
Iterator end() { return Iterator(vertices_.end()); }
};
public:
explicit DbAccessor(database::GraphDbAccessor *dba) : dba_(dba) {}
VertexAccessor InsertVertex() { return VertexAccessor(dba_->InsertVertex()); }
storage::Result<EdgeAccessor> InsertEdge(VertexAccessor *from,
VertexAccessor *to,
const storage::EdgeType &edge_type) {
try {
return EdgeAccessor(dba_->InsertEdge(from->impl_, to->impl_, edge_type));
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
} catch (const RecordDeletedError &) {
return storage::Error::DELETED_OBJECT;
}
}
storage::Result<bool> RemoveEdge(EdgeAccessor *edge) {
try {
dba_->RemoveEdge(edge->impl_);
return true;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
}
}
storage::Result<bool> DetachRemoveVertex(VertexAccessor *vertex_accessor) {
try {
dba_->DetachRemoveVertex(vertex_accessor->impl_);
return true;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
}
}
storage::Result<bool> RemoveVertex(VertexAccessor *vertex_accessor) {
try {
if (!dba_->RemoveVertex(vertex_accessor->impl_))
return storage::Error::VERTEX_HAS_EDGES;
return true;
} catch (const mvcc::SerializationError &) {
return storage::Error::SERIALIZATION_ERROR;
}
}
auto Vertices(storage::View view) {
auto vertices = dba_->Vertices(view == storage::View::NEW);
return VerticesIterable<decltype(vertices)>(std::move(vertices));
}
auto Vertices(storage::View view, storage::Label label) {
auto vertices = dba_->Vertices(label, view == storage::View::NEW);
return VerticesIterable<decltype(vertices)>(std::move(vertices));
}
auto Vertices(storage::View view, storage::Label label,
storage::Property property, const PropertyValue &value) {
auto vertices =
dba_->Vertices(label, property, value, view == storage::View::NEW);
return VerticesIterable<decltype(vertices)>(std::move(vertices));
}
auto Vertices(storage::View view, storage::Label label,
storage::Property property,
const std::optional<utils::Bound<PropertyValue>> &lower,
const std::optional<utils::Bound<PropertyValue>> &upper) {
auto vertices = dba_->Vertices(label, property, lower, upper,
view == storage::View::NEW);
return VerticesIterable<decltype(vertices)>(std::move(vertices));
}
auto Edges(storage::View view) {
// TODO: Exceptions?
return iter::imap([](const auto &e) { return EdgeAccessor(e); },
dba_->Edges(view == storage::View::NEW));
}
storage::Property NameToProperty(const std::string_view &name) {
return dba_->Property(std::string(name));
}
storage::Label NameToLabel(const std::string_view &name) {
return dba_->Label(std::string(name));
}
storage::EdgeType NameToEdgeType(const std::string_view &name) {
return dba_->EdgeType(std::string(name));
}
const std::string &PropertyToName(storage::Property prop) const {
return dba_->PropertyName(prop);
}
const std::string &LabelToName(storage::Label label) const {
return dba_->LabelName(label);
}
const std::string &EdgeTypeToName(storage::EdgeType type) const {
return dba_->EdgeTypeName(type);
}
void AdvanceCommand() { dba_->AdvanceCommand(); }
bool MustAbort() const { return dba_->should_abort(); }
bool CreateIndex(storage::Label label, storage::Property prop) {
try {
dba_->BuildIndex(label, prop);
return true;
} catch (const database::IndexExistsException &) {
return false;
} catch (const database::TransactionException &) {
// TODO: What do we do with this? This cannot happen in v2
throw;
}
}
bool DropIndex(storage::Label label, storage::Property prop) {
try {
dba_->DeleteIndex(label, prop);
return true;
} catch (const database::TransactionException &) {
// TODO: What do we do with this? This cannot happen in v2
throw;
}
}
bool LabelPropertyIndexExists(storage::Label label,
storage::Property prop) const {
return dba_->LabelPropertyIndexExists(label, prop);
}
int64_t VerticesCount() const { return dba_->VerticesCount(); }
int64_t VerticesCount(storage::Label label) const {
return dba_->VerticesCount(label);
}
int64_t VerticesCount(storage::Label label,
storage::Property property) const {
return dba_->VerticesCount(label, property);
}
int64_t VerticesCount(storage::Label label, storage::Property property,
const PropertyValue &value) const {
return dba_->VerticesCount(label, property, value);
}
int64_t VerticesCount(
storage::Label label, storage::Property property,
const std::optional<utils::Bound<PropertyValue>> &lower,
const std::optional<utils::Bound<PropertyValue>> &upper) const {
return dba_->VerticesCount(label, property, lower, upper);
}
auto StorageInfo() const { return dba_->StorageInfo(); }
auto IndexInfo() const { return dba_->IndexInfo(); }
auto GetIndicesKeys() const { return dba_->GetIndicesKeys(); }
auto ListUniqueConstraints() const { return dba_->ListUniqueConstraints(); }
void BuildUniqueConstraint(storage::Label label,
const std::vector<storage::Property> &properties) {
// TODO: Exceptions?
return dba_->BuildUniqueConstraint(label, properties);
}
void DeleteUniqueConstraint(
storage::Label label, const std::vector<storage::Property> &properties) {
// TODO: Exceptions?
return dba_->DeleteUniqueConstraint(label, properties);
}
#ifdef MG_SINGLE_NODE_HA
auto raft() { return dba_->raft(); }
#endif
};
#endif
} // namespace query
namespace std {
template <>
struct hash<query::VertexAccessor> {
size_t operator()(const query::VertexAccessor &v) const {
return std::hash<decltype(v.impl_)>{}(v.impl_);
}
};
template <>
struct hash<query::EdgeAccessor> {
size_t operator()(const query::EdgeAccessor &e) const {
return std::hash<decltype(e.impl_)>{}(e.impl_);
}
};
} // namespace std