Move GraphDbAccessor to stack in SN and HA

Reviewers: msantl

Reviewed By: msantl

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1944
This commit is contained in:
Matej Ferencevic 2019-04-15 11:36:43 +02:00
parent 6b62145a59
commit 026c796e06
51 changed files with 1777 additions and 1726 deletions

View File

@ -64,7 +64,7 @@ GraphDb::GraphDb(Config config) : config_(config) {
snapshot_creator_->Run( snapshot_creator_->Run(
"Snapshot", std::chrono::seconds(config_.snapshot_cycle_sec), [this] { "Snapshot", std::chrono::seconds(config_.snapshot_cycle_sec), [this] {
auto dba = this->Access(); auto dba = this->Access();
this->MakeSnapshot(*dba); this->MakeSnapshot(dba);
}); });
} }
@ -95,26 +95,21 @@ GraphDb::~GraphDb() {
if (config_.snapshot_on_exit) { if (config_.snapshot_on_exit) {
auto dba = this->Access(); auto dba = this->Access();
MakeSnapshot(*dba); MakeSnapshot(dba);
} }
} }
std::unique_ptr<GraphDbAccessor> GraphDb::Access() { GraphDbAccessor GraphDb::Access() {
// NOTE: We are doing a heap allocation to allow polymorphism. If this poses return GraphDbAccessor(this);
// performance issues, we may want to have a stack allocated GraphDbAccessor
// which is constructed with a pointer to some global implementation struct
// which contains only pure functions (without any state).
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this));
} }
std::unique_ptr<GraphDbAccessor> GraphDb::Access(tx::TransactionId tx_id) { GraphDbAccessor GraphDb::Access(tx::TransactionId tx_id) {
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this, tx_id)); return GraphDbAccessor(this, tx_id);
} }
std::unique_ptr<GraphDbAccessor> GraphDb::AccessBlocking( GraphDbAccessor GraphDb::AccessBlocking(
std::experimental::optional<tx::TransactionId> parent_tx) { std::experimental::optional<tx::TransactionId> parent_tx) {
return std::unique_ptr<GraphDbAccessor>( return GraphDbAccessor(this, parent_tx);
new GraphDbAccessor(*this, parent_tx));
} }
Storage &GraphDb::storage() { return *storage_; } Storage &GraphDb::storage() { return *storage_; }

View File

@ -92,12 +92,12 @@ class GraphDb {
GraphDb &operator=(GraphDb &&) = delete; GraphDb &operator=(GraphDb &&) = delete;
/// Create a new accessor by starting a new transaction. /// Create a new accessor by starting a new transaction.
std::unique_ptr<GraphDbAccessor> Access(); GraphDbAccessor Access();
std::unique_ptr<GraphDbAccessor> AccessBlocking( GraphDbAccessor AccessBlocking(
std::experimental::optional<tx::TransactionId> parent_tx = std::experimental::optional<tx::TransactionId> parent_tx =
std::experimental::nullopt); std::experimental::nullopt);
/// Create an accessor for a running transaction. /// Create an accessor for a running transaction.
std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId); GraphDbAccessor Access(tx::TransactionId);
Storage &storage(); Storage &storage();
durability::WriteAheadLog &wal(); durability::WriteAheadLog &wal();

View File

@ -16,22 +16,47 @@
namespace database { namespace database {
GraphDbAccessor::GraphDbAccessor(GraphDb &db) GraphDbAccessor::GraphDbAccessor(GraphDb *db)
: db_(db), : db_(db),
transaction_(*db.tx_engine().Begin()), transaction_(db->tx_engine().Begin()),
transaction_starter_{true} {} transaction_starter_{true} {}
GraphDbAccessor::GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id) GraphDbAccessor::GraphDbAccessor(GraphDb *db, tx::TransactionId tx_id)
: db_(db), : db_(db),
transaction_(*db.tx_engine().RunningTransaction(tx_id)), transaction_(db->tx_engine().RunningTransaction(tx_id)),
transaction_starter_{false} {} transaction_starter_{false} {}
GraphDbAccessor::GraphDbAccessor( GraphDbAccessor::GraphDbAccessor(
GraphDb &db, std::experimental::optional<tx::TransactionId> parent_tx) GraphDb *db, std::experimental::optional<tx::TransactionId> parent_tx)
: db_(db), : db_(db),
transaction_(*db.tx_engine().BeginBlocking(parent_tx)), transaction_(db->tx_engine().BeginBlocking(parent_tx)),
transaction_starter_{true} {} transaction_starter_{true} {}
GraphDbAccessor::GraphDbAccessor(GraphDbAccessor &&other)
: db_(other.db_),
transaction_(other.transaction_),
transaction_starter_(other.transaction_starter_),
commited_(other.commited_),
aborted_(other.aborted_) {
// Make sure that the other transaction isn't a transaction starter so that
// its destructor doesn't close the transaction.
other.transaction_starter_ = false;
}
GraphDbAccessor &GraphDbAccessor::operator=(GraphDbAccessor &&other) {
db_ = other.db_;
transaction_ = other.transaction_;
transaction_starter_ = other.transaction_starter_;
commited_ = other.commited_;
aborted_ = other.aborted_;
// Make sure that the other transaction isn't a transaction starter so that
// its destructor doesn't close the transaction.
other.transaction_starter_ = false;
return *this;
}
GraphDbAccessor::~GraphDbAccessor() { GraphDbAccessor::~GraphDbAccessor() {
if (transaction_starter_ && !commited_ && !aborted_) { if (transaction_starter_ && !commited_ && !aborted_) {
this->Abort(); this->Abort();
@ -39,53 +64,53 @@ GraphDbAccessor::~GraphDbAccessor() {
} }
tx::TransactionId GraphDbAccessor::transaction_id() const { tx::TransactionId GraphDbAccessor::transaction_id() const {
return transaction_.id_; return transaction_->id_;
} }
void GraphDbAccessor::AdvanceCommand() { void GraphDbAccessor::AdvanceCommand() {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
db_.tx_engine().Advance(transaction_.id_); db_->tx_engine().Advance(transaction_->id_);
} }
void GraphDbAccessor::Commit() { void GraphDbAccessor::Commit() {
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction."; DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
db_.tx_engine().Commit(transaction_); db_->tx_engine().Commit(*transaction_);
commited_ = true; commited_ = true;
} }
void GraphDbAccessor::Abort() { void GraphDbAccessor::Abort() {
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction."; DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
db_.tx_engine().Abort(transaction_); db_->tx_engine().Abort(*transaction_);
aborted_ = true; aborted_ = true;
} }
bool GraphDbAccessor::should_abort() const { bool GraphDbAccessor::should_abort() const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return transaction_.should_abort(); return transaction_->should_abort();
} }
durability::WriteAheadLog &GraphDbAccessor::wal() { return db_.wal(); } durability::WriteAheadLog &GraphDbAccessor::wal() { return db_->wal(); }
VertexAccessor GraphDbAccessor::InsertVertex( VertexAccessor GraphDbAccessor::InsertVertex(
std::experimental::optional<gid::Gid> requested_gid) { std::experimental::optional<gid::Gid> requested_gid) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto gid = db_.storage().vertex_generator_.Next(requested_gid); auto gid = db_->storage().vertex_generator_.Next(requested_gid);
auto vertex_vlist = new mvcc::VersionList<Vertex>(transaction_, gid); auto vertex_vlist = new mvcc::VersionList<Vertex>(*transaction_, gid);
bool success = bool success =
db_.storage().vertices_.access().insert(gid, vertex_vlist).second; db_->storage().vertices_.access().insert(gid, vertex_vlist).second;
CHECK(success) << "Attempting to insert a vertex with an existing GID: " CHECK(success) << "Attempting to insert a vertex with an existing GID: "
<< gid; << gid;
wal().Emplace( wal().Emplace(
database::StateDelta::CreateVertex(transaction_.id_, vertex_vlist->gid_)); database::StateDelta::CreateVertex(transaction_->id_, vertex_vlist->gid_));
auto va = VertexAccessor(vertex_vlist, *this); auto va = VertexAccessor(vertex_vlist, *this);
return va; return va;
} }
std::experimental::optional<VertexAccessor> GraphDbAccessor::FindVertexOptional( std::experimental::optional<VertexAccessor> GraphDbAccessor::FindVertexOptional(
gid::Gid gid, bool current_state) { gid::Gid gid, bool current_state) {
VertexAccessor record_accessor(db_.storage().LocalAddress<Vertex>(gid), VertexAccessor record_accessor(db_->storage().LocalAddress<Vertex>(gid),
*this); *this);
if (!record_accessor.Visible(transaction(), current_state)) if (!record_accessor.Visible(transaction(), current_state))
return std::experimental::nullopt; return std::experimental::nullopt;
@ -100,7 +125,7 @@ VertexAccessor GraphDbAccessor::FindVertex(gid::Gid gid, bool current_state) {
std::experimental::optional<EdgeAccessor> GraphDbAccessor::FindEdgeOptional( std::experimental::optional<EdgeAccessor> GraphDbAccessor::FindEdgeOptional(
gid::Gid gid, bool current_state) { gid::Gid gid, bool current_state) {
EdgeAccessor record_accessor(db_.storage().LocalAddress<Edge>(gid), *this); EdgeAccessor record_accessor(db_->storage().LocalAddress<Edge>(gid), *this);
if (!record_accessor.Visible(transaction(), current_state)) if (!record_accessor.Visible(transaction(), current_state))
return std::experimental::nullopt; return std::experimental::nullopt;
return record_accessor; return record_accessor;
@ -118,7 +143,7 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
// Create the index // Create the index
const LabelPropertyIndex::Key key(label, property, unique); const LabelPropertyIndex::Key key(label, property, unique);
if (db_.storage().label_property_index_.CreateIndex(key) == false) { if (db_->storage().label_property_index_.CreateIndex(key) == false) {
throw IndexExistsException( throw IndexExistsException(
"Index is either being created by another transaction or already " "Index is either being created by another transaction or already "
"exists."); "exists.");
@ -126,16 +151,16 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
try { try {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction_.id_)); db_->AccessBlocking(std::experimental::make_optional(transaction_->id_));
dba->PopulateIndex(key); dba.PopulateIndex(key);
dba->EnableIndex(key); dba.EnableIndex(key);
dba->Commit(); dba.Commit();
} catch (const IndexConstraintViolationException &) { } catch (const IndexConstraintViolationException &) {
db_.storage().label_property_index_.DeleteIndex(key); db_->storage().label_property_index_.DeleteIndex(key);
throw; throw;
} catch (const tx::TransactionEngineError &e) { } catch (const tx::TransactionEngineError &e) {
db_.storage().label_property_index_.DeleteIndex(key); db_->storage().label_property_index_.DeleteIndex(key);
throw IndexTransactionException(e.what()); throw IndexTransactionException(e.what());
} }
} }
@ -154,7 +179,7 @@ void GraphDbAccessor::PopulateIndex(const LabelPropertyIndex::Key &key) {
for (auto vertex : Vertices(key.label_, false)) { for (auto vertex : Vertices(key.label_, false)) {
if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null) if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null)
continue; continue;
if (!db_.storage().label_property_index_.UpdateOnLabelProperty( if (!db_->storage().label_property_index_.UpdateOnLabelProperty(
vertex.address(), vertex.current_)) { vertex.address(), vertex.current_)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Index couldn't be created due to constraint violation!"); "Index couldn't be created due to constraint violation!");
@ -169,14 +194,14 @@ void GraphDbAccessor::DeleteIndex(storage::Label label,
LabelPropertyIndex::Key key(label, property); LabelPropertyIndex::Key key(label, property);
try { try {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction_.id_)); db_->AccessBlocking(std::experimental::make_optional(transaction_->id_));
db_.storage().label_property_index_.DeleteIndex(key); db_->storage().label_property_index_.DeleteIndex(key);
dba->wal().Emplace(database::StateDelta::DropIndex( dba.wal().Emplace(database::StateDelta::DropIndex(
dba->transaction_id(), key.label_, LabelName(key.label_), key.property_, dba.transaction_id(), key.label_, LabelName(key.label_), key.property_,
PropertyName(key.property_))); PropertyName(key.property_)));
dba->Commit(); dba.Commit();
} catch (const tx::TransactionEngineError &e) { } catch (const tx::TransactionEngineError &e) {
throw IndexTransactionException(e.what()); throw IndexTransactionException(e.what());
} }
@ -186,37 +211,37 @@ void GraphDbAccessor::BuildUniqueConstraint(storage::Label label,
storage::Property property) { storage::Property property) {
try { try {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction().id_)); db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
if (!db_.storage().unique_label_property_constraints_.AddConstraint( if (!db_->storage().unique_label_property_constraints_.AddConstraint(
label, property, dba->transaction())) { label, property, dba.transaction())) {
// Already exists // Already exists
return; return;
} }
for (auto v : dba->Vertices(false)) { for (auto v : dba.Vertices(false)) {
if (std::find(v.labels().begin(), v.labels().end(), label) != if (std::find(v.labels().begin(), v.labels().end(), label) !=
v.labels().end()) { v.labels().end()) {
db_.storage().unique_label_property_constraints_.Update( db_->storage().unique_label_property_constraints_.Update(
v, dba->transaction()); v, dba.transaction());
} }
} }
dba->wal().Emplace(database::StateDelta::BuildUniqueConstraint( dba.wal().Emplace(database::StateDelta::BuildUniqueConstraint(
dba->transaction().id_, label, dba->LabelName(label), dba.transaction().id_, label, dba.LabelName(label),
std::vector<storage::Property>{property}, std::vector<storage::Property>{property},
std::vector<std::string>{dba->PropertyName(property)})); std::vector<std::string>{dba.PropertyName(property)}));
dba->Commit(); dba.Commit();
} catch (const IndexConstraintViolationException &) { } catch (const IndexConstraintViolationException &) {
db_.storage().unique_label_property_constraints_.RemoveConstraint(label, db_->storage().unique_label_property_constraints_.RemoveConstraint(label,
property); property);
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Constraint cannot be built due to existing unique constraint " "Constraint cannot be built due to existing unique constraint "
"violation!"); "violation!");
} catch (const tx::TransactionEngineError &e) { } catch (const tx::TransactionEngineError &e) {
db_.storage().unique_label_property_constraints_.RemoveConstraint(label, db_->storage().unique_label_property_constraints_.RemoveConstraint(label,
property); property);
throw IndexTransactionException(e.what()); throw IndexTransactionException(e.what());
} catch (...) { } catch (...) {
db_.storage().unique_label_property_constraints_.RemoveConstraint(label, db_->storage().unique_label_property_constraints_.RemoveConstraint(label,
property); property);
throw; throw;
} }
@ -226,19 +251,19 @@ void GraphDbAccessor::DeleteUniqueConstraint(storage::Label label,
storage::Property property) { storage::Property property) {
try { try {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction().id_)); db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
if (!db_.storage().unique_label_property_constraints_.RemoveConstraint( if (!db_->storage().unique_label_property_constraints_.RemoveConstraint(
label, property)) { label, property)) {
// Nothing to do // Nothing to do
return; return;
} }
dba->wal().Emplace(database::StateDelta::DropUniqueConstraint( dba.wal().Emplace(database::StateDelta::DropUniqueConstraint(
dba->transaction().id_, label, dba->LabelName(label), dba.transaction().id_, label, dba.LabelName(label),
std::vector<storage::Property>{property}, std::vector<storage::Property>{property},
std::vector<std::string>{dba->PropertyName(property)})); std::vector<std::string>{dba.PropertyName(property)}));
dba->Commit(); dba.Commit();
} catch (const tx::TransactionEngineError &e) { } catch (const tx::TransactionEngineError &e) {
throw IndexTransactionException(e.what()); throw IndexTransactionException(e.what());
} }
@ -246,13 +271,13 @@ void GraphDbAccessor::DeleteUniqueConstraint(storage::Label label,
bool GraphDbAccessor::UniqueConstraintExists(storage::Label label, bool GraphDbAccessor::UniqueConstraintExists(storage::Label label,
storage::Property property) const { storage::Property property) const {
return db_.storage().unique_label_property_constraints_.Exists(label, return db_->storage().unique_label_property_constraints_.Exists(label,
property); property);
} }
std::vector<storage::constraints::LabelProperty> std::vector<storage::constraints::LabelProperty>
GraphDbAccessor::ListUniqueLabelPropertyConstraints() const { GraphDbAccessor::ListUniqueLabelPropertyConstraints() const {
return db_.storage().unique_label_property_constraints_.ListConstraints(); return db_->storage().unique_label_property_constraints_.ListConstraints();
} }
void GraphDbAccessor::UpdateOnAddLabel(storage::Label label, void GraphDbAccessor::UpdateOnAddLabel(storage::Label label,
@ -261,26 +286,26 @@ void GraphDbAccessor::UpdateOnAddLabel(storage::Label label,
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto *vlist_ptr = vertex_accessor.address(); auto *vlist_ptr = vertex_accessor.address();
db_.storage().unique_label_property_constraints_.UpdateOnAddLabel( db_->storage().unique_label_property_constraints_.UpdateOnAddLabel(
label, vertex_accessor, transaction()); label, vertex_accessor, transaction());
if (!db_.storage().label_property_index_.UpdateOnLabel(label, vlist_ptr, if (!db_->storage().label_property_index_.UpdateOnLabel(label, vlist_ptr,
vertex)) { vertex)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Node couldn't be updated due to index constraint violation!"); "Node couldn't be updated due to index constraint violation!");
} }
if (!db_.storage().existence_constraints_.CheckOnAddLabel(vertex, label)) { if (!db_->storage().existence_constraints_.CheckOnAddLabel(vertex, label)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Node couldn't be updated due to existence constraint violation!"); "Node couldn't be updated due to existence constraint violation!");
} }
db_.storage().labels_index_.Update(label, vlist_ptr, vertex); db_->storage().labels_index_.Update(label, vlist_ptr, vertex);
} }
void GraphDbAccessor::UpdateOnRemoveLabel( void GraphDbAccessor::UpdateOnRemoveLabel(
storage::Label label, const RecordAccessor<Vertex> &accessor) { storage::Label label, const RecordAccessor<Vertex> &accessor) {
db_.storage().unique_label_property_constraints_.UpdateOnRemoveLabel( db_->storage().unique_label_property_constraints_.UpdateOnRemoveLabel(
label, accessor, transaction()); label, accessor, transaction());
} }
@ -289,10 +314,10 @@ void GraphDbAccessor::UpdateOnAddProperty(
const RecordAccessor<Vertex> &vertex_accessor, const Vertex *vertex) { const RecordAccessor<Vertex> &vertex_accessor, const Vertex *vertex) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
db_.storage().unique_label_property_constraints_.UpdateOnAddProperty( db_->storage().unique_label_property_constraints_.UpdateOnAddProperty(
property, value, vertex_accessor, transaction()); property, value, vertex_accessor, transaction());
if (!db_.storage().label_property_index_.UpdateOnProperty( if (!db_->storage().label_property_index_.UpdateOnProperty(
property, vertex_accessor.address(), vertex)) { property, vertex_accessor.address(), vertex)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Node couldn't be updated due to unique index violation!"); "Node couldn't be updated due to unique index violation!");
@ -302,10 +327,10 @@ void GraphDbAccessor::UpdateOnAddProperty(
void GraphDbAccessor::UpdateOnRemoveProperty( void GraphDbAccessor::UpdateOnRemoveProperty(
storage::Property property, const RecordAccessor<Vertex> &accessor, storage::Property property, const RecordAccessor<Vertex> &accessor,
const Vertex *vertex) { const Vertex *vertex) {
db_.storage().unique_label_property_constraints_.UpdateOnRemoveProperty( db_->storage().unique_label_property_constraints_.UpdateOnRemoveProperty(
property, accessor, transaction()); property, accessor, transaction());
if (!db_.storage().existence_constraints_.CheckOnRemoveProperty(vertex, if (!db_->storage().existence_constraints_.CheckOnRemoveProperty(vertex,
property)) { property)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Node couldn't be updated due to existence constraint violation!"); "Node couldn't be updated due to existence constraint violation!");
@ -315,10 +340,10 @@ void GraphDbAccessor::UpdateOnRemoveProperty(
void GraphDbAccessor::BuildExistenceConstraint( void GraphDbAccessor::BuildExistenceConstraint(
storage::Label label, const std::vector<storage::Property> &properties) { storage::Label label, const std::vector<storage::Property> &properties) {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction().id_)); db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
storage::constraints::ExistenceRule rule{label, properties}; storage::constraints::ExistenceRule rule{label, properties};
for (auto v : dba->Vertices(false)) { for (auto v : dba.Vertices(false)) {
if (!CheckIfSatisfiesExistenceRule(v.GetOld(), rule)) { if (!CheckIfSatisfiesExistenceRule(v.GetOld(), rule)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Existence constraint couldn't be built because existing data is " "Existence constraint couldn't be built because existing data is "
@ -326,70 +351,70 @@ void GraphDbAccessor::BuildExistenceConstraint(
} }
} }
if (!db_.storage().existence_constraints_.AddConstraint(rule)) { if (!db_->storage().existence_constraints_.AddConstraint(rule)) {
// Already exists // Already exists
return; return;
} }
std::vector<std::string> property_names(properties.size()); std::vector<std::string> property_names(properties.size());
std::transform(properties.begin(), properties.end(), property_names.begin(), std::transform(properties.begin(), properties.end(), property_names.begin(),
[&dba](auto p) { return dba->PropertyName(p); }); [&dba](auto p) { return dba.PropertyName(p); });
dba->wal().Emplace(database::StateDelta::BuildExistenceConstraint( dba.wal().Emplace(database::StateDelta::BuildExistenceConstraint(
dba->transaction().id_, label, dba->LabelName(label), properties, dba.transaction().id_, label, dba.LabelName(label), properties,
property_names)); property_names));
dba->Commit(); dba.Commit();
} }
void GraphDbAccessor::DeleteExistenceConstraint( void GraphDbAccessor::DeleteExistenceConstraint(
storage::Label label, const std::vector<storage::Property> &properties) { storage::Label label, const std::vector<storage::Property> &properties) {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction().id_)); db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
storage::constraints::ExistenceRule rule{label, properties}; storage::constraints::ExistenceRule rule{label, properties};
if (!db_.storage().existence_constraints_.RemoveConstraint(rule)) { if (!db_->storage().existence_constraints_.RemoveConstraint(rule)) {
// Nothing was deleted // Nothing was deleted
return; return;
} }
std::vector<std::string> property_names(properties.size()); std::vector<std::string> property_names(properties.size());
std::transform(properties.begin(), properties.end(), property_names.begin(), std::transform(properties.begin(), properties.end(), property_names.begin(),
[&dba](auto p) { return dba->PropertyName(p); }); [&dba](auto p) { return dba.PropertyName(p); });
dba->wal().Emplace(database::StateDelta::DropExistenceConstraint( dba.wal().Emplace(database::StateDelta::DropExistenceConstraint(
dba->transaction().id_, label, dba->LabelName(label), properties, dba.transaction().id_, label, dba.LabelName(label), properties,
property_names)); property_names));
dba->Commit(); dba.Commit();
} }
bool GraphDbAccessor::ExistenceConstraintExists( bool GraphDbAccessor::ExistenceConstraintExists(
storage::Label label, storage::Label label,
const std::vector<storage::Property> &properties) const { const std::vector<storage::Property> &properties) const {
storage::constraints::ExistenceRule rule{label, properties}; storage::constraints::ExistenceRule rule{label, properties};
return db_.storage().existence_constraints_.Exists(rule); return db_->storage().existence_constraints_.Exists(rule);
} }
std::vector<storage::constraints::ExistenceRule> std::vector<storage::constraints::ExistenceRule>
GraphDbAccessor::ListExistenceConstraints() const { GraphDbAccessor::ListExistenceConstraints() const {
return db_.storage().existence_constraints_.ListConstraints(); return db_->storage().existence_constraints_.ListConstraints();
} }
int64_t GraphDbAccessor::VerticesCount() const { int64_t GraphDbAccessor::VerticesCount() const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().vertices_.access().size(); return db_->storage().vertices_.access().size();
} }
int64_t GraphDbAccessor::VerticesCount(storage::Label label) const { int64_t GraphDbAccessor::VerticesCount(storage::Label label) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().labels_index_.Count(label); return db_->storage().labels_index_.Count(label);
} }
int64_t GraphDbAccessor::VerticesCount(storage::Label label, int64_t GraphDbAccessor::VerticesCount(storage::Label label,
storage::Property property) const { storage::Property property) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
DCHECK(db_.storage().label_property_index_.IndexExists(key)) DCHECK(db_->storage().label_property_index_.IndexExists(key))
<< "Index doesn't exist."; << "Index doesn't exist.";
return db_.storage().label_property_index_.Count(key); return db_->storage().label_property_index_.Count(key);
} }
int64_t GraphDbAccessor::VerticesCount(storage::Label label, int64_t GraphDbAccessor::VerticesCount(storage::Label label,
@ -397,9 +422,9 @@ int64_t GraphDbAccessor::VerticesCount(storage::Label label,
const PropertyValue &value) const { const PropertyValue &value) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
DCHECK(db_.storage().label_property_index_.IndexExists(key)) DCHECK(db_->storage().label_property_index_.IndexExists(key))
<< "Index doesn't exist."; << "Index doesn't exist.";
return db_.storage() return db_->storage()
.label_property_index_.PositionAndCount(key, value) .label_property_index_.PositionAndCount(key, value)
.second; .second;
} }
@ -411,7 +436,7 @@ int64_t GraphDbAccessor::VerticesCount(
const { const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
DCHECK(db_.storage().label_property_index_.IndexExists(key)) DCHECK(db_->storage().label_property_index_.IndexExists(key))
<< "Index doesn't exist."; << "Index doesn't exist.";
CHECK(lower || upper) << "At least one bound must be provided"; CHECK(lower || upper) << "At least one bound must be provided";
CHECK(!lower || lower.value().value().type() != PropertyValue::Type::Null) CHECK(!lower || lower.value().value().type() != PropertyValue::Type::Null)
@ -420,23 +445,23 @@ int64_t GraphDbAccessor::VerticesCount(
<< "Null value is not a valid index bound"; << "Null value is not a valid index bound";
if (!upper) { if (!upper) {
auto lower_pac = db_.storage().label_property_index_.PositionAndCount( auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
key, lower.value().value()); key, lower.value().value());
int64_t size = db_.storage().label_property_index_.Count(key); int64_t size = db_->storage().label_property_index_.Count(key);
return std::max(0l, return std::max(0l,
size - lower_pac.first - size - lower_pac.first -
(lower.value().IsInclusive() ? 0l : lower_pac.second)); (lower.value().IsInclusive() ? 0l : lower_pac.second));
} else if (!lower) { } else if (!lower) {
auto upper_pac = db_.storage().label_property_index_.PositionAndCount( auto upper_pac = db_->storage().label_property_index_.PositionAndCount(
key, upper.value().value()); key, upper.value().value());
return upper.value().IsInclusive() ? upper_pac.first + upper_pac.second return upper.value().IsInclusive() ? upper_pac.first + upper_pac.second
: upper_pac.first; : upper_pac.first;
} else { } else {
auto lower_pac = db_.storage().label_property_index_.PositionAndCount( auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
key, lower.value().value()); key, lower.value().value());
auto upper_pac = db_.storage().label_property_index_.PositionAndCount( auto upper_pac = db_->storage().label_property_index_.PositionAndCount(
key, upper.value().value()); key, upper.value().value());
auto result = upper_pac.first - lower_pac.first; auto result = upper_pac.first - lower_pac.first;
if (lower.value().IsExclusive()) result -= lower_pac.second; if (lower.value().IsExclusive()) result -= lower_pac.second;
@ -452,15 +477,15 @@ bool GraphDbAccessor::RemoveVertex(VertexAccessor &vertex_accessor,
// it's possible the vertex was removed already in this transaction // it's possible the vertex was removed already in this transaction
// due to it getting matched multiple times by some patterns // due to it getting matched multiple times by some patterns
// we can only delete it once, so check if it's already deleted // we can only delete it once, so check if it's already deleted
if (vertex_accessor.current().is_expired_by(transaction_)) return true; if (vertex_accessor.current().is_expired_by(*transaction_)) return true;
if (check_empty && if (check_empty &&
vertex_accessor.out_degree() + vertex_accessor.in_degree() > 0) vertex_accessor.out_degree() + vertex_accessor.in_degree() > 0)
return false; return false;
auto *vlist_ptr = vertex_accessor.address(); auto *vlist_ptr = vertex_accessor.address();
wal().Emplace(database::StateDelta::RemoveVertex( wal().Emplace(database::StateDelta::RemoveVertex(
transaction_.id_, vlist_ptr->gid_, check_empty)); transaction_->id_, vlist_ptr->gid_, check_empty));
vlist_ptr->remove(vertex_accessor.current_, transaction_); vlist_ptr->remove(vertex_accessor.current_, *transaction_);
return true; return true;
} }
@ -485,13 +510,13 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
VertexAccessor &from, VertexAccessor &to, storage::EdgeType edge_type, VertexAccessor &from, VertexAccessor &to, storage::EdgeType edge_type,
std::experimental::optional<gid::Gid> requested_gid) { std::experimental::optional<gid::Gid> requested_gid) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto gid = db_.storage().edge_generator_.Next(requested_gid); auto gid = db_->storage().edge_generator_.Next(requested_gid);
auto edge_vlist = new mvcc::VersionList<Edge>( auto edge_vlist = new mvcc::VersionList<Edge>(
transaction_, gid, from.address(), to.address(), edge_type); *transaction_, gid, from.address(), to.address(), edge_type);
// We need to insert edge_vlist to edges_ before calling update since update // We need to insert edge_vlist to edges_ before calling update since update
// can throw and edge_vlist will not be garbage collected if it is not in // can throw and edge_vlist will not be garbage collected if it is not in
// edges_ skiplist. // edges_ skiplist.
bool success = db_.storage().edges_.access().insert(gid, edge_vlist).second; bool success = db_->storage().edges_.access().insert(gid, edge_vlist).second;
CHECK(success) << "Attempting to insert an edge with an existing GID: " CHECK(success) << "Attempting to insert an edge with an existing GID: "
<< gid; << gid;
@ -506,7 +531,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
to.update().in_.emplace(from.address(), edge_vlist, edge_type); to.update().in_.emplace(from.address(), edge_vlist, edge_type);
wal().Emplace(database::StateDelta::CreateEdge( wal().Emplace(database::StateDelta::CreateEdge(
transaction_.id_, edge_vlist->gid_, from.gid(), to.gid(), edge_type, transaction_->id_, edge_vlist->gid_, from.gid(), to.gid(), edge_type,
EdgeTypeName(edge_type))); EdgeTypeName(edge_type)));
return EdgeAccessor(edge_vlist, *this, from.address(), to.address(), return EdgeAccessor(edge_vlist, *this, from.address(), to.address(),
@ -515,7 +540,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
int64_t GraphDbAccessor::EdgesCount() const { int64_t GraphDbAccessor::EdgesCount() const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().edges_.access().size(); return db_->storage().edges_.access().size();
} }
void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge, void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge,
@ -525,61 +550,61 @@ void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge,
// due to it getting matched multiple times by some patterns // due to it getting matched multiple times by some patterns
// we can only delete it once, so check if it's already deleted // we can only delete it once, so check if it's already deleted
edge.SwitchNew(); edge.SwitchNew();
if (edge.current().is_expired_by(transaction_)) return; if (edge.current().is_expired_by(*transaction_)) return;
if (remove_out_edge) edge.from().RemoveOutEdge(edge.address()); if (remove_out_edge) edge.from().RemoveOutEdge(edge.address());
if (remove_in_edge) edge.to().RemoveInEdge(edge.address()); if (remove_in_edge) edge.to().RemoveInEdge(edge.address());
edge.address()->remove(edge.current_, transaction_); edge.address()->remove(edge.current_, *transaction_);
wal().Emplace(database::StateDelta::RemoveEdge(transaction_.id_, edge.gid())); wal().Emplace(database::StateDelta::RemoveEdge(transaction_->id_, edge.gid()));
} }
storage::Label GraphDbAccessor::Label(const std::string &label_name) { storage::Label GraphDbAccessor::Label(const std::string &label_name) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.label_mapper().value_to_id(label_name); return db_->label_mapper().value_to_id(label_name);
} }
const std::string &GraphDbAccessor::LabelName(storage::Label label) const { const std::string &GraphDbAccessor::LabelName(storage::Label label) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.label_mapper().id_to_value(label); return db_->label_mapper().id_to_value(label);
} }
storage::EdgeType GraphDbAccessor::EdgeType(const std::string &edge_type_name) { storage::EdgeType GraphDbAccessor::EdgeType(const std::string &edge_type_name) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.edge_type_mapper().value_to_id(edge_type_name); return db_->edge_type_mapper().value_to_id(edge_type_name);
} }
const std::string &GraphDbAccessor::EdgeTypeName( const std::string &GraphDbAccessor::EdgeTypeName(
storage::EdgeType edge_type) const { storage::EdgeType edge_type) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.edge_type_mapper().id_to_value(edge_type); return db_->edge_type_mapper().id_to_value(edge_type);
} }
storage::Property GraphDbAccessor::Property(const std::string &property_name) { storage::Property GraphDbAccessor::Property(const std::string &property_name) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.property_mapper().value_to_id(property_name); return db_->property_mapper().value_to_id(property_name);
} }
const std::string &GraphDbAccessor::PropertyName( const std::string &GraphDbAccessor::PropertyName(
storage::Property property) const { storage::Property property) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.property_mapper().id_to_value(property); return db_->property_mapper().id_to_value(property);
} }
int64_t GraphDbAccessor::Counter(const std::string &name) { int64_t GraphDbAccessor::Counter(const std::string &name) {
return db_.counters().Get(name); return db_->counters().Get(name);
} }
void GraphDbAccessor::CounterSet(const std::string &name, int64_t value) { void GraphDbAccessor::CounterSet(const std::string &name, int64_t value) {
db_.counters().Set(name, value); db_->counters().Set(name, value);
} }
std::vector<std::string> GraphDbAccessor::IndexInfo() const { std::vector<std::string> GraphDbAccessor::IndexInfo() const {
std::vector<std::string> info; std::vector<std::string> info;
for (storage::Label label : db_.storage().labels_index_.Keys()) { for (storage::Label label : db_->storage().labels_index_.Keys()) {
info.emplace_back(":" + LabelName(label)); info.emplace_back(":" + LabelName(label));
} }
for (LabelPropertyIndex::Key key : for (LabelPropertyIndex::Key key :
db_.storage().label_property_index_.Keys()) { db_->storage().label_property_index_.Keys()) {
info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_), info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_),
PropertyName(key.property_), PropertyName(key.property_),
key.unique_ ? " unique" : "")); key.unique_ ? " unique" : ""));
@ -591,14 +616,14 @@ std::vector<std::pair<std::string, std::string>> GraphDbAccessor::StorageInfo()
const { const {
std::vector<std::pair<std::string, std::string>> info; std::vector<std::pair<std::string, std::string>> info;
db_.RefreshStat(); db_->RefreshStat();
auto &stat = db_.GetStat(); auto &stat = db_->GetStat();
info.emplace_back("vertex_count", std::to_string(stat.vertex_count)); info.emplace_back("vertex_count", std::to_string(stat.vertex_count));
info.emplace_back("edge_count", std::to_string(stat.edge_count)); info.emplace_back("edge_count", std::to_string(stat.edge_count));
info.emplace_back("average_degree", std::to_string(stat.avg_degree)); info.emplace_back("average_degree", std::to_string(stat.avg_degree));
info.emplace_back("memory_usage", std::to_string(utils::GetMemoryUsage())); info.emplace_back("memory_usage", std::to_string(utils::GetMemoryUsage()));
info.emplace_back("disk_usage", std::to_string(db_.GetDurabilityDirDiskUsage())); info.emplace_back("disk_usage", std::to_string(db_->GetDurabilityDirDiskUsage()));
return info; return info;
} }

View File

@ -42,20 +42,21 @@ class GraphDbAccessor {
// concrete GraphDbAccessor type. // concrete GraphDbAccessor type.
/// Creates a new accessor by starting a new transaction. /// Creates a new accessor by starting a new transaction.
explicit GraphDbAccessor(GraphDb &db); explicit GraphDbAccessor(GraphDb *db);
/// Creates an accessor for a running transaction. /// Creates an accessor for a running transaction.
GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id); GraphDbAccessor(GraphDb *db, tx::TransactionId tx_id);
GraphDbAccessor(GraphDb &db, GraphDbAccessor(GraphDb *db,
std::experimental::optional<tx::TransactionId> parent_tx); std::experimental::optional<tx::TransactionId> parent_tx);
public: public:
~GraphDbAccessor(); ~GraphDbAccessor();
GraphDbAccessor(const GraphDbAccessor &other) = delete; GraphDbAccessor(const GraphDbAccessor &other) = delete;
GraphDbAccessor(GraphDbAccessor &&other) = delete;
GraphDbAccessor &operator=(const GraphDbAccessor &other) = delete; GraphDbAccessor &operator=(const GraphDbAccessor &other) = delete;
GraphDbAccessor &operator=(GraphDbAccessor &&other) = delete;
GraphDbAccessor(GraphDbAccessor &&other);
GraphDbAccessor &operator=(GraphDbAccessor &&other);
/** /**
* Creates a new Vertex and returns an accessor to it. If the ID is * Creates a new Vertex and returns an accessor to it. If the ID is
@ -142,7 +143,7 @@ class GraphDbAccessor {
[this](auto id_vlist) { [this](auto id_vlist) {
return VertexAccessor(id_vlist.second, *this); return VertexAccessor(id_vlist.second, *this);
}, },
db_.storage().vertices_.access()); db_->storage().vertices_.access());
// filter out the accessors not visible to the current transaction // filter out the accessors not visible to the current transaction
return iter::filter( return iter::filter(
@ -168,7 +169,7 @@ class GraphDbAccessor {
[this](auto vlist) { [this](auto vlist) {
return VertexAccessor(vlist, *this); return VertexAccessor(vlist, *this);
}, },
db_.storage().labels_index_.GetVlists(label, transaction_, db_->storage().labels_index_.GetVlists(label, *transaction_,
current_state)); current_state));
} }
@ -187,15 +188,15 @@ class GraphDbAccessor {
auto Vertices(storage::Label label, storage::Property property, auto Vertices(storage::Label label, storage::Property property,
bool current_state) { bool current_state) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
DCHECK(db_.storage().label_property_index_.IndexExists( DCHECK(db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property))) LabelPropertyIndex::Key(label, property)))
<< "Label+property index doesn't exist."; << "Label+property index doesn't exist.";
return iter::imap( return iter::imap(
[this](auto vlist) { [this](auto vlist) {
return VertexAccessor(vlist, *this); return VertexAccessor(vlist, *this);
}, },
db_.storage().label_property_index_.GetVlists( db_->storage().label_property_index_.GetVlists(
LabelPropertyIndex::Key(label, property), transaction_, LabelPropertyIndex::Key(label, property), *transaction_,
current_state)); current_state));
} }
@ -215,7 +216,7 @@ class GraphDbAccessor {
auto Vertices(storage::Label label, storage::Property property, auto Vertices(storage::Label label, storage::Property property,
const PropertyValue &value, bool current_state) { const PropertyValue &value, bool current_state) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
DCHECK(db_.storage().label_property_index_.IndexExists( DCHECK(db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property))) LabelPropertyIndex::Key(label, property)))
<< "Label+property index doesn't exist."; << "Label+property index doesn't exist.";
CHECK(value.type() != PropertyValue::Type::Null) CHECK(value.type() != PropertyValue::Type::Null)
@ -224,8 +225,8 @@ class GraphDbAccessor {
[this](auto vlist) { [this](auto vlist) {
return VertexAccessor(vlist, *this); return VertexAccessor(vlist, *this);
}, },
db_.storage().label_property_index_.GetVlists( db_->storage().label_property_index_.GetVlists(
LabelPropertyIndex::Key(label, property), value, transaction_, LabelPropertyIndex::Key(label, property), value, *transaction_,
current_state)); current_state));
} }
@ -262,16 +263,16 @@ class GraphDbAccessor {
const std::experimental::optional<utils::Bound<PropertyValue>> upper, const std::experimental::optional<utils::Bound<PropertyValue>> upper,
bool current_state) { bool current_state) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
DCHECK(db_.storage().label_property_index_.IndexExists( DCHECK(db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property))) LabelPropertyIndex::Key(label, property)))
<< "Label+property index doesn't exist."; << "Label+property index doesn't exist.";
return iter::imap( return iter::imap(
[this](auto vlist) { [this](auto vlist) {
return VertexAccessor(vlist, *this); return VertexAccessor(vlist, *this);
}, },
db_.storage().label_property_index_.GetVlists( db_->storage().label_property_index_.GetVlists(
LabelPropertyIndex::Key(label, property), lower, upper, LabelPropertyIndex::Key(label, property), lower, upper,
transaction_, current_state)); *transaction_, current_state));
} }
/** /**
@ -357,7 +358,7 @@ class GraphDbAccessor {
[this](auto id_vlist) { [this](auto id_vlist) {
return EdgeAccessor(id_vlist.second, *this); return EdgeAccessor(id_vlist.second, *this);
}, },
db_.storage().edges_.access()); db_->storage().edges_.access());
// filter out the accessors not visible to the current transaction // filter out the accessors not visible to the current transaction
return iter::filter( return iter::filter(
@ -463,7 +464,7 @@ class GraphDbAccessor {
bool LabelPropertyIndexExists(storage::Label label, bool LabelPropertyIndexExists(storage::Label label,
storage::Property property) const { storage::Property property) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().label_property_index_.IndexExists( return db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property)); LabelPropertyIndex::Key(label, property));
} }
@ -472,7 +473,7 @@ class GraphDbAccessor {
*/ */
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() { std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().label_property_index_.Keys(); return db_->storage().label_property_index_.Keys();
} }
/** /**
@ -614,10 +615,10 @@ class GraphDbAccessor {
/** Return true if transaction is hinted to abort. */ /** Return true if transaction is hinted to abort. */
bool should_abort() const; bool should_abort() const;
const tx::Transaction &transaction() const { return transaction_; } const tx::Transaction &transaction() const { return *transaction_; }
durability::WriteAheadLog &wal(); durability::WriteAheadLog &wal();
auto &db() { return db_; } GraphDb &db() { return *db_; }
const auto &db() const { return db_; } const GraphDb &db() const { return *db_; }
/** /**
* Returns the current value of the counter with the given name, and * Returns the current value of the counter with the given name, and
@ -649,8 +650,8 @@ class GraphDbAccessor {
std::vector<std::pair<std::string, std::string>> StorageInfo() const; std::vector<std::pair<std::string, std::string>> StorageInfo() const;
private: private:
GraphDb &db_; GraphDb *db_;
tx::Transaction &transaction_; tx::Transaction *transaction_;
// Indicates if this db-accessor started the transaction and should Abort it // Indicates if this db-accessor started the transaction and should Abort it
// upon destruction. // upon destruction.
bool transaction_starter_; bool transaction_starter_;

View File

@ -51,22 +51,17 @@ void GraphDb::AwaitShutdown(std::function<void(void)> call_before_shutdown) {
void GraphDb::Shutdown() { coordination_.Shutdown(); } void GraphDb::Shutdown() { coordination_.Shutdown(); }
std::unique_ptr<GraphDbAccessor> GraphDb::Access() { GraphDbAccessor GraphDb::Access() {
// NOTE: We are doing a heap allocation to allow polymorphism. If this poses return GraphDbAccessor(this);
// performance issues, we may want to have a stack allocated GraphDbAccessor
// which is constructed with a pointer to some global implementation struct
// which contains only pure functions (without any state).
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this));
} }
std::unique_ptr<GraphDbAccessor> GraphDb::Access(tx::TransactionId tx_id) { GraphDbAccessor GraphDb::Access(tx::TransactionId tx_id) {
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this, tx_id)); return GraphDbAccessor(this, tx_id);
} }
std::unique_ptr<GraphDbAccessor> GraphDb::AccessBlocking( GraphDbAccessor GraphDb::AccessBlocking(
std::experimental::optional<tx::TransactionId> parent_tx) { std::experimental::optional<tx::TransactionId> parent_tx) {
return std::unique_ptr<GraphDbAccessor>( return GraphDbAccessor(this, parent_tx);
new GraphDbAccessor(*this, parent_tx));
} }
Storage &GraphDb::storage() { return *storage_; } Storage &GraphDb::storage() { return *storage_; }

View File

@ -100,11 +100,11 @@ class GraphDb {
void Shutdown(); void Shutdown();
/// Create a new accessor by starting a new transaction. /// Create a new accessor by starting a new transaction.
std::unique_ptr<GraphDbAccessor> Access(); GraphDbAccessor Access();
std::unique_ptr<GraphDbAccessor> AccessBlocking( GraphDbAccessor AccessBlocking(
std::experimental::optional<tx::TransactionId> parent_tx); std::experimental::optional<tx::TransactionId> parent_tx);
/// Create an accessor for a running transaction. /// Create an accessor for a running transaction.
std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId); GraphDbAccessor Access(tx::TransactionId);
Storage &storage(); Storage &storage();
raft::RaftInterface *raft(); raft::RaftInterface *raft();

View File

@ -16,22 +16,47 @@
namespace database { namespace database {
GraphDbAccessor::GraphDbAccessor(GraphDb &db) GraphDbAccessor::GraphDbAccessor(GraphDb *db)
: db_(db), : db_(db),
transaction_(*db.tx_engine().Begin()), transaction_(db->tx_engine().Begin()),
transaction_starter_{true} {} transaction_starter_{true} {}
GraphDbAccessor::GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id) GraphDbAccessor::GraphDbAccessor(GraphDb *db, tx::TransactionId tx_id)
: db_(db), : db_(db),
transaction_(*db.tx_engine().RunningTransaction(tx_id)), transaction_(db->tx_engine().RunningTransaction(tx_id)),
transaction_starter_{false} {} transaction_starter_{false} {}
GraphDbAccessor::GraphDbAccessor( GraphDbAccessor::GraphDbAccessor(
GraphDb &db, std::experimental::optional<tx::TransactionId> parent_tx) GraphDb *db, std::experimental::optional<tx::TransactionId> parent_tx)
: db_(db), : db_(db),
transaction_(*db.tx_engine().BeginBlocking(parent_tx)), transaction_(db->tx_engine().BeginBlocking(parent_tx)),
transaction_starter_{true} {} transaction_starter_{true} {}
GraphDbAccessor::GraphDbAccessor(GraphDbAccessor &&other)
: db_(other.db_),
transaction_(other.transaction_),
transaction_starter_(other.transaction_starter_),
commited_(other.commited_),
aborted_(other.aborted_) {
// Make sure that the other transaction isn't a transaction starter so that
// its destructor doesn't close the transaction.
other.transaction_starter_ = false;
}
GraphDbAccessor &GraphDbAccessor::operator=(GraphDbAccessor &&other) {
db_ = other.db_;
transaction_ = other.transaction_;
transaction_starter_ = other.transaction_starter_;
commited_ = other.commited_;
aborted_ = other.aborted_;
// Make sure that the other transaction isn't a transaction starter so that
// its destructor doesn't close the transaction.
other.transaction_starter_ = false;
return *this;
}
GraphDbAccessor::~GraphDbAccessor() { GraphDbAccessor::~GraphDbAccessor() {
if (transaction_starter_ && !commited_ && !aborted_) { if (transaction_starter_ && !commited_ && !aborted_) {
this->Abort(); this->Abort();
@ -39,53 +64,53 @@ GraphDbAccessor::~GraphDbAccessor() {
} }
tx::TransactionId GraphDbAccessor::transaction_id() const { tx::TransactionId GraphDbAccessor::transaction_id() const {
return transaction_.id_; return transaction_->id_;
} }
void GraphDbAccessor::AdvanceCommand() { void GraphDbAccessor::AdvanceCommand() {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
db_.tx_engine().Advance(transaction_.id_); db_->tx_engine().Advance(transaction_->id_);
} }
void GraphDbAccessor::Commit() { void GraphDbAccessor::Commit() {
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction."; DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
db_.tx_engine().Commit(transaction_); db_->tx_engine().Commit(*transaction_);
commited_ = true; commited_ = true;
} }
void GraphDbAccessor::Abort() { void GraphDbAccessor::Abort() {
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction."; DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
db_.tx_engine().Abort(transaction_); db_->tx_engine().Abort(*transaction_);
aborted_ = true; aborted_ = true;
} }
bool GraphDbAccessor::should_abort() const { bool GraphDbAccessor::should_abort() const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return transaction_.should_abort(); return transaction_->should_abort();
} }
raft::RaftInterface *GraphDbAccessor::raft() { return db_.raft(); } raft::RaftInterface *GraphDbAccessor::raft() { return db_->raft(); }
VertexAccessor GraphDbAccessor::InsertVertex( VertexAccessor GraphDbAccessor::InsertVertex(
std::experimental::optional<gid::Gid> requested_gid) { std::experimental::optional<gid::Gid> requested_gid) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto gid = db_.storage().vertex_generator_.Next(requested_gid); auto gid = db_->storage().vertex_generator_.Next(requested_gid);
auto vertex_vlist = new mvcc::VersionList<Vertex>(transaction_, gid); auto vertex_vlist = new mvcc::VersionList<Vertex>(*transaction_, gid);
bool success = bool success =
db_.storage().vertices_.access().insert(gid, vertex_vlist).second; db_->storage().vertices_.access().insert(gid, vertex_vlist).second;
CHECK(success) << "Attempting to insert a vertex with an existing GID: " CHECK(success) << "Attempting to insert a vertex with an existing GID: "
<< gid; << gid;
raft()->Emplace( raft()->Emplace(
database::StateDelta::CreateVertex(transaction_.id_, vertex_vlist->gid_)); database::StateDelta::CreateVertex(transaction_->id_, vertex_vlist->gid_));
auto va = VertexAccessor(vertex_vlist, *this); auto va = VertexAccessor(vertex_vlist, *this);
return va; return va;
} }
std::experimental::optional<VertexAccessor> GraphDbAccessor::FindVertexOptional( std::experimental::optional<VertexAccessor> GraphDbAccessor::FindVertexOptional(
gid::Gid gid, bool current_state) { gid::Gid gid, bool current_state) {
VertexAccessor record_accessor(db_.storage().LocalAddress<Vertex>(gid), VertexAccessor record_accessor(db_->storage().LocalAddress<Vertex>(gid),
*this); *this);
if (!record_accessor.Visible(transaction(), current_state)) if (!record_accessor.Visible(transaction(), current_state))
return std::experimental::nullopt; return std::experimental::nullopt;
@ -100,7 +125,7 @@ VertexAccessor GraphDbAccessor::FindVertex(gid::Gid gid, bool current_state) {
std::experimental::optional<EdgeAccessor> GraphDbAccessor::FindEdgeOptional( std::experimental::optional<EdgeAccessor> GraphDbAccessor::FindEdgeOptional(
gid::Gid gid, bool current_state) { gid::Gid gid, bool current_state) {
EdgeAccessor record_accessor(db_.storage().LocalAddress<Edge>(gid), *this); EdgeAccessor record_accessor(db_->storage().LocalAddress<Edge>(gid), *this);
if (!record_accessor.Visible(transaction(), current_state)) if (!record_accessor.Visible(transaction(), current_state))
return std::experimental::nullopt; return std::experimental::nullopt;
return record_accessor; return record_accessor;
@ -118,7 +143,7 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
// Create the index // Create the index
const LabelPropertyIndex::Key key(label, property, unique); const LabelPropertyIndex::Key key(label, property, unique);
if (db_.storage().label_property_index_.CreateIndex(key) == false) { if (db_->storage().label_property_index_.CreateIndex(key) == false) {
throw IndexExistsException( throw IndexExistsException(
"Index is either being created by another transaction or already " "Index is either being created by another transaction or already "
"exists."); "exists.");
@ -126,16 +151,16 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
try { try {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction_.id_)); db_->AccessBlocking(std::experimental::make_optional(transaction_->id_));
dba->PopulateIndex(key); dba.PopulateIndex(key);
dba->EnableIndex(key); dba.EnableIndex(key);
dba->Commit(); dba.Commit();
} catch (const IndexConstraintViolationException &) { } catch (const IndexConstraintViolationException &) {
db_.storage().label_property_index_.DeleteIndex(key); db_->storage().label_property_index_.DeleteIndex(key);
throw; throw;
} catch (const tx::TransactionEngineError &e) { } catch (const tx::TransactionEngineError &e) {
db_.storage().label_property_index_.DeleteIndex(key); db_->storage().label_property_index_.DeleteIndex(key);
throw IndexTransactionException(e.what()); throw IndexTransactionException(e.what());
} }
} }
@ -153,7 +178,7 @@ void GraphDbAccessor::PopulateIndex(const LabelPropertyIndex::Key &key) {
for (auto vertex : Vertices(key.label_, false)) { for (auto vertex : Vertices(key.label_, false)) {
if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null) if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null)
continue; continue;
if (!db_.storage().label_property_index_.UpdateOnLabelProperty( if (!db_->storage().label_property_index_.UpdateOnLabelProperty(
vertex.address(), vertex.current_)) { vertex.address(), vertex.current_)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Index couldn't be created due to constraint violation!"); "Index couldn't be created due to constraint violation!");
@ -168,14 +193,14 @@ void GraphDbAccessor::DeleteIndex(storage::Label label,
LabelPropertyIndex::Key key(label, property); LabelPropertyIndex::Key key(label, property);
try { try {
auto dba = auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction_.id_)); db_->AccessBlocking(std::experimental::make_optional(transaction_->id_));
db_.storage().label_property_index_.DeleteIndex(key); db_->storage().label_property_index_.DeleteIndex(key);
dba->raft()->Emplace(database::StateDelta::DropIndex( dba.raft()->Emplace(database::StateDelta::DropIndex(
dba->transaction_id(), key.label_, LabelName(key.label_), key.property_, dba.transaction_id(), key.label_, LabelName(key.label_), key.property_,
PropertyName(key.property_))); PropertyName(key.property_)));
dba->Commit(); dba.Commit();
} catch (const tx::TransactionEngineError &e) { } catch (const tx::TransactionEngineError &e) {
throw IndexTransactionException(e.what()); throw IndexTransactionException(e.what());
} }
@ -187,19 +212,19 @@ void GraphDbAccessor::UpdateLabelIndices(storage::Label label,
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto *vlist_ptr = vertex_accessor.address(); auto *vlist_ptr = vertex_accessor.address();
if (!db_.storage().label_property_index_.UpdateOnLabel(label, vlist_ptr, if (!db_->storage().label_property_index_.UpdateOnLabel(label, vlist_ptr,
vertex)) { vertex)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Node couldn't be updated due to index constraint violation!"); "Node couldn't be updated due to index constraint violation!");
} }
db_.storage().labels_index_.Update(label, vlist_ptr, vertex); db_->storage().labels_index_.Update(label, vlist_ptr, vertex);
} }
void GraphDbAccessor::UpdatePropertyIndex( void GraphDbAccessor::UpdatePropertyIndex(
storage::Property property, const RecordAccessor<Vertex> &vertex_accessor, storage::Property property, const RecordAccessor<Vertex> &vertex_accessor,
const Vertex *const vertex) { const Vertex *const vertex) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
if (!db_.storage().label_property_index_.UpdateOnProperty( if (!db_->storage().label_property_index_.UpdateOnProperty(
property, vertex_accessor.address(), vertex)) { property, vertex_accessor.address(), vertex)) {
throw IndexConstraintViolationException( throw IndexConstraintViolationException(
"Node couldn't be updated due to index constraint violation!"); "Node couldn't be updated due to index constraint violation!");
@ -208,21 +233,21 @@ void GraphDbAccessor::UpdatePropertyIndex(
int64_t GraphDbAccessor::VerticesCount() const { int64_t GraphDbAccessor::VerticesCount() const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().vertices_.access().size(); return db_->storage().vertices_.access().size();
} }
int64_t GraphDbAccessor::VerticesCount(storage::Label label) const { int64_t GraphDbAccessor::VerticesCount(storage::Label label) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().labels_index_.Count(label); return db_->storage().labels_index_.Count(label);
} }
int64_t GraphDbAccessor::VerticesCount(storage::Label label, int64_t GraphDbAccessor::VerticesCount(storage::Label label,
storage::Property property) const { storage::Property property) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
DCHECK(db_.storage().label_property_index_.IndexExists(key)) DCHECK(db_->storage().label_property_index_.IndexExists(key))
<< "Index doesn't exist."; << "Index doesn't exist.";
return db_.storage().label_property_index_.Count(key); return db_->storage().label_property_index_.Count(key);
} }
int64_t GraphDbAccessor::VerticesCount(storage::Label label, int64_t GraphDbAccessor::VerticesCount(storage::Label label,
@ -230,9 +255,9 @@ int64_t GraphDbAccessor::VerticesCount(storage::Label label,
const PropertyValue &value) const { const PropertyValue &value) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
DCHECK(db_.storage().label_property_index_.IndexExists(key)) DCHECK(db_->storage().label_property_index_.IndexExists(key))
<< "Index doesn't exist."; << "Index doesn't exist.";
return db_.storage() return db_->storage()
.label_property_index_.PositionAndCount(key, value) .label_property_index_.PositionAndCount(key, value)
.second; .second;
} }
@ -244,7 +269,7 @@ int64_t GraphDbAccessor::VerticesCount(
const { const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
const LabelPropertyIndex::Key key(label, property); const LabelPropertyIndex::Key key(label, property);
DCHECK(db_.storage().label_property_index_.IndexExists(key)) DCHECK(db_->storage().label_property_index_.IndexExists(key))
<< "Index doesn't exist."; << "Index doesn't exist.";
CHECK(lower || upper) << "At least one bound must be provided"; CHECK(lower || upper) << "At least one bound must be provided";
CHECK(!lower || lower.value().value().type() != PropertyValue::Type::Null) CHECK(!lower || lower.value().value().type() != PropertyValue::Type::Null)
@ -253,23 +278,23 @@ int64_t GraphDbAccessor::VerticesCount(
<< "Null value is not a valid index bound"; << "Null value is not a valid index bound";
if (!upper) { if (!upper) {
auto lower_pac = db_.storage().label_property_index_.PositionAndCount( auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
key, lower.value().value()); key, lower.value().value());
int64_t size = db_.storage().label_property_index_.Count(key); int64_t size = db_->storage().label_property_index_.Count(key);
return std::max(0l, return std::max(0l,
size - lower_pac.first - size - lower_pac.first -
(lower.value().IsInclusive() ? 0l : lower_pac.second)); (lower.value().IsInclusive() ? 0l : lower_pac.second));
} else if (!lower) { } else if (!lower) {
auto upper_pac = db_.storage().label_property_index_.PositionAndCount( auto upper_pac = db_->storage().label_property_index_.PositionAndCount(
key, upper.value().value()); key, upper.value().value());
return upper.value().IsInclusive() ? upper_pac.first + upper_pac.second return upper.value().IsInclusive() ? upper_pac.first + upper_pac.second
: upper_pac.first; : upper_pac.first;
} else { } else {
auto lower_pac = db_.storage().label_property_index_.PositionAndCount( auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
key, lower.value().value()); key, lower.value().value());
auto upper_pac = db_.storage().label_property_index_.PositionAndCount( auto upper_pac = db_->storage().label_property_index_.PositionAndCount(
key, upper.value().value()); key, upper.value().value());
auto result = upper_pac.first - lower_pac.first; auto result = upper_pac.first - lower_pac.first;
if (lower.value().IsExclusive()) result -= lower_pac.second; if (lower.value().IsExclusive()) result -= lower_pac.second;
@ -285,15 +310,15 @@ bool GraphDbAccessor::RemoveVertex(VertexAccessor &vertex_accessor,
// it's possible the vertex was removed already in this transaction // it's possible the vertex was removed already in this transaction
// due to it getting matched multiple times by some patterns // due to it getting matched multiple times by some patterns
// we can only delete it once, so check if it's already deleted // we can only delete it once, so check if it's already deleted
if (vertex_accessor.current().is_expired_by(transaction_)) return true; if (vertex_accessor.current().is_expired_by(*transaction_)) return true;
if (check_empty && if (check_empty &&
vertex_accessor.out_degree() + vertex_accessor.in_degree() > 0) vertex_accessor.out_degree() + vertex_accessor.in_degree() > 0)
return false; return false;
auto *vlist_ptr = vertex_accessor.address(); auto *vlist_ptr = vertex_accessor.address();
raft()->Emplace(database::StateDelta::RemoveVertex( raft()->Emplace(database::StateDelta::RemoveVertex(
transaction_.id_, vlist_ptr->gid_, check_empty)); transaction_->id_, vlist_ptr->gid_, check_empty));
vlist_ptr->remove(vertex_accessor.current_, transaction_); vlist_ptr->remove(vertex_accessor.current_, *transaction_);
return true; return true;
} }
@ -318,13 +343,13 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
VertexAccessor &from, VertexAccessor &to, storage::EdgeType edge_type, VertexAccessor &from, VertexAccessor &to, storage::EdgeType edge_type,
std::experimental::optional<gid::Gid> requested_gid) { std::experimental::optional<gid::Gid> requested_gid) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto gid = db_.storage().edge_generator_.Next(requested_gid); auto gid = db_->storage().edge_generator_.Next(requested_gid);
auto edge_vlist = new mvcc::VersionList<Edge>( auto edge_vlist = new mvcc::VersionList<Edge>(
transaction_, gid, from.address(), to.address(), edge_type); *transaction_, gid, from.address(), to.address(), edge_type);
// We need to insert edge_vlist to edges_ before calling update since update // We need to insert edge_vlist to edges_ before calling update since update
// can throw and edge_vlist will not be garbage collected if it is not in // can throw and edge_vlist will not be garbage collected if it is not in
// edges_ skiplist. // edges_ skiplist.
bool success = db_.storage().edges_.access().insert(gid, edge_vlist).second; bool success = db_->storage().edges_.access().insert(gid, edge_vlist).second;
CHECK(success) << "Attempting to insert an edge with an existing GID: " CHECK(success) << "Attempting to insert an edge with an existing GID: "
<< gid; << gid;
@ -339,7 +364,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
to.update().in_.emplace(from.address(), edge_vlist, edge_type); to.update().in_.emplace(from.address(), edge_vlist, edge_type);
raft()->Emplace(database::StateDelta::CreateEdge( raft()->Emplace(database::StateDelta::CreateEdge(
transaction_.id_, edge_vlist->gid_, from.gid(), to.gid(), edge_type, transaction_->id_, edge_vlist->gid_, from.gid(), to.gid(), edge_type,
EdgeTypeName(edge_type))); EdgeTypeName(edge_type)));
return EdgeAccessor(edge_vlist, *this, from.address(), to.address(), return EdgeAccessor(edge_vlist, *this, from.address(), to.address(),
@ -348,7 +373,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
int64_t GraphDbAccessor::EdgesCount() const { int64_t GraphDbAccessor::EdgesCount() const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().edges_.access().size(); return db_->storage().edges_.access().size();
} }
void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge, void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge,
@ -358,61 +383,61 @@ void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge,
// due to it getting matched multiple times by some patterns // due to it getting matched multiple times by some patterns
// we can only delete it once, so check if it's already deleted // we can only delete it once, so check if it's already deleted
edge.SwitchNew(); edge.SwitchNew();
if (edge.current().is_expired_by(transaction_)) return; if (edge.current().is_expired_by(*transaction_)) return;
if (remove_out_edge) edge.from().RemoveOutEdge(edge.address()); if (remove_out_edge) edge.from().RemoveOutEdge(edge.address());
if (remove_in_edge) edge.to().RemoveInEdge(edge.address()); if (remove_in_edge) edge.to().RemoveInEdge(edge.address());
edge.address()->remove(edge.current_, transaction_); edge.address()->remove(edge.current_, *transaction_);
raft()->Emplace(database::StateDelta::RemoveEdge(transaction_.id_, edge.gid())); raft()->Emplace(database::StateDelta::RemoveEdge(transaction_->id_, edge.gid()));
} }
storage::Label GraphDbAccessor::Label(const std::string &label_name) { storage::Label GraphDbAccessor::Label(const std::string &label_name) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.label_mapper().value_to_id(label_name); return db_->label_mapper().value_to_id(label_name);
} }
const std::string &GraphDbAccessor::LabelName(storage::Label label) const { const std::string &GraphDbAccessor::LabelName(storage::Label label) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.label_mapper().id_to_value(label); return db_->label_mapper().id_to_value(label);
} }
storage::EdgeType GraphDbAccessor::EdgeType(const std::string &edge_type_name) { storage::EdgeType GraphDbAccessor::EdgeType(const std::string &edge_type_name) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.edge_type_mapper().value_to_id(edge_type_name); return db_->edge_type_mapper().value_to_id(edge_type_name);
} }
const std::string &GraphDbAccessor::EdgeTypeName( const std::string &GraphDbAccessor::EdgeTypeName(
storage::EdgeType edge_type) const { storage::EdgeType edge_type) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.edge_type_mapper().id_to_value(edge_type); return db_->edge_type_mapper().id_to_value(edge_type);
} }
storage::Property GraphDbAccessor::Property(const std::string &property_name) { storage::Property GraphDbAccessor::Property(const std::string &property_name) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.property_mapper().value_to_id(property_name); return db_->property_mapper().value_to_id(property_name);
} }
const std::string &GraphDbAccessor::PropertyName( const std::string &GraphDbAccessor::PropertyName(
storage::Property property) const { storage::Property property) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.property_mapper().id_to_value(property); return db_->property_mapper().id_to_value(property);
} }
int64_t GraphDbAccessor::Counter(const std::string &name) { int64_t GraphDbAccessor::Counter(const std::string &name) {
return db_.counters().Get(name); return db_->counters().Get(name);
} }
void GraphDbAccessor::CounterSet(const std::string &name, int64_t value) { void GraphDbAccessor::CounterSet(const std::string &name, int64_t value) {
db_.counters().Set(name, value); db_->counters().Set(name, value);
} }
std::vector<std::string> GraphDbAccessor::IndexInfo() const { std::vector<std::string> GraphDbAccessor::IndexInfo() const {
std::vector<std::string> info; std::vector<std::string> info;
for (storage::Label label : db_.storage().labels_index_.Keys()) { for (storage::Label label : db_->storage().labels_index_.Keys()) {
info.emplace_back(":" + LabelName(label)); info.emplace_back(":" + LabelName(label));
} }
for (LabelPropertyIndex::Key key : for (LabelPropertyIndex::Key key :
db_.storage().label_property_index_.Keys()) { db_->storage().label_property_index_.Keys()) {
info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_), info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_),
PropertyName(key.property_), PropertyName(key.property_),
key.unique_ ? " unique" : "")); key.unique_ ? " unique" : ""));
@ -422,7 +447,7 @@ std::vector<std::string> GraphDbAccessor::IndexInfo() const {
std::map<std::string, std::vector<std::pair<std::string, std::string>>> std::map<std::string, std::vector<std::pair<std::string, std::string>>>
GraphDbAccessor::StorageInfo() const { GraphDbAccessor::StorageInfo() const {
return db_.storage_info()->GetStorageInfo(); return db_->storage_info()->GetStorageInfo();
} }
} // namespace database } // namespace database

View File

@ -64,20 +64,21 @@ class GraphDbAccessor {
// concrete GraphDbAccessor type. // concrete GraphDbAccessor type.
/// Creates a new accessor by starting a new transaction. /// Creates a new accessor by starting a new transaction.
explicit GraphDbAccessor(GraphDb &db); explicit GraphDbAccessor(GraphDb *db);
/// Creates an accessor for a running transaction. /// Creates an accessor for a running transaction.
GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id); GraphDbAccessor(GraphDb *db, tx::TransactionId tx_id);
GraphDbAccessor(GraphDb &db, GraphDbAccessor(GraphDb *db,
std::experimental::optional<tx::TransactionId> parent_tx); std::experimental::optional<tx::TransactionId> parent_tx);
public: public:
~GraphDbAccessor(); ~GraphDbAccessor();
GraphDbAccessor(const GraphDbAccessor &other) = delete; GraphDbAccessor(const GraphDbAccessor &other) = delete;
GraphDbAccessor(GraphDbAccessor &&other) = delete;
GraphDbAccessor &operator=(const GraphDbAccessor &other) = delete; GraphDbAccessor &operator=(const GraphDbAccessor &other) = delete;
GraphDbAccessor &operator=(GraphDbAccessor &&other) = delete;
GraphDbAccessor(GraphDbAccessor &&other);
GraphDbAccessor &operator=(GraphDbAccessor &&other);
/** /**
* Creates a new Vertex and returns an accessor to it. If the ID is * Creates a new Vertex and returns an accessor to it. If the ID is
@ -164,7 +165,7 @@ class GraphDbAccessor {
[this](auto id_vlist) { [this](auto id_vlist) {
return VertexAccessor(id_vlist.second, *this); return VertexAccessor(id_vlist.second, *this);
}, },
db_.storage().vertices_.access()); db_->storage().vertices_.access());
// filter out the accessors not visible to the current transaction // filter out the accessors not visible to the current transaction
return iter::filter( return iter::filter(
@ -188,7 +189,7 @@ class GraphDbAccessor {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(vlist, *this); }, [this](auto vlist) { return VertexAccessor(vlist, *this); },
db_.storage().labels_index_.GetVlists(label, transaction_, db_->storage().labels_index_.GetVlists(label, *transaction_,
current_state)); current_state));
} }
@ -207,13 +208,13 @@ class GraphDbAccessor {
auto Vertices(storage::Label label, storage::Property property, auto Vertices(storage::Label label, storage::Property property,
bool current_state) { bool current_state) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
DCHECK(db_.storage().label_property_index_.IndexExists( DCHECK(db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property))) LabelPropertyIndex::Key(label, property)))
<< "Label+property index doesn't exist."; << "Label+property index doesn't exist.";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(vlist, *this); }, [this](auto vlist) { return VertexAccessor(vlist, *this); },
db_.storage().label_property_index_.GetVlists( db_->storage().label_property_index_.GetVlists(
LabelPropertyIndex::Key(label, property), transaction_, LabelPropertyIndex::Key(label, property), *transaction_,
current_state)); current_state));
} }
@ -233,15 +234,15 @@ class GraphDbAccessor {
auto Vertices(storage::Label label, storage::Property property, auto Vertices(storage::Label label, storage::Property property,
const PropertyValue &value, bool current_state) { const PropertyValue &value, bool current_state) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
DCHECK(db_.storage().label_property_index_.IndexExists( DCHECK(db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property))) LabelPropertyIndex::Key(label, property)))
<< "Label+property index doesn't exist."; << "Label+property index doesn't exist.";
CHECK(value.type() != PropertyValue::Type::Null) CHECK(value.type() != PropertyValue::Type::Null)
<< "Can't query index for propery value type null."; << "Can't query index for propery value type null.";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(vlist, *this); }, [this](auto vlist) { return VertexAccessor(vlist, *this); },
db_.storage().label_property_index_.GetVlists( db_->storage().label_property_index_.GetVlists(
LabelPropertyIndex::Key(label, property), value, transaction_, LabelPropertyIndex::Key(label, property), value, *transaction_,
current_state)); current_state));
} }
@ -278,14 +279,14 @@ class GraphDbAccessor {
const std::experimental::optional<utils::Bound<PropertyValue>> upper, const std::experimental::optional<utils::Bound<PropertyValue>> upper,
bool current_state) { bool current_state) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
DCHECK(db_.storage().label_property_index_.IndexExists( DCHECK(db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property))) LabelPropertyIndex::Key(label, property)))
<< "Label+property index doesn't exist."; << "Label+property index doesn't exist.";
return iter::imap( return iter::imap(
[this](auto vlist) { return VertexAccessor(vlist, *this); }, [this](auto vlist) { return VertexAccessor(vlist, *this); },
db_.storage().label_property_index_.GetVlists( db_->storage().label_property_index_.GetVlists(
LabelPropertyIndex::Key(label, property), lower, upper, LabelPropertyIndex::Key(label, property), lower, upper,
transaction_, current_state)); *transaction_, current_state));
} }
/** /**
@ -369,7 +370,7 @@ class GraphDbAccessor {
// wrap version lists into accessors, which will look for visible versions // wrap version lists into accessors, which will look for visible versions
auto accessors = iter::imap( auto accessors = iter::imap(
[this](auto id_vlist) { return EdgeAccessor(id_vlist.second, *this); }, [this](auto id_vlist) { return EdgeAccessor(id_vlist.second, *this); },
db_.storage().edges_.access()); db_->storage().edges_.access());
// filter out the accessors not visible to the current transaction // filter out the accessors not visible to the current transaction
return iter::filter( return iter::filter(
@ -448,7 +449,7 @@ class GraphDbAccessor {
bool LabelPropertyIndexExists(storage::Label label, bool LabelPropertyIndexExists(storage::Label label,
storage::Property property) const { storage::Property property) const {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().label_property_index_.IndexExists( return db_->storage().label_property_index_.IndexExists(
LabelPropertyIndex::Key(label, property)); LabelPropertyIndex::Key(label, property));
} }
@ -457,7 +458,7 @@ class GraphDbAccessor {
*/ */
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() { std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted"; DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
return db_.storage().label_property_index_.Keys(); return db_->storage().label_property_index_.Keys();
} }
/** /**
@ -574,7 +575,7 @@ class GraphDbAccessor {
/** Return true if transaction is hinted to abort. */ /** Return true if transaction is hinted to abort. */
bool should_abort() const; bool should_abort() const;
const tx::Transaction &transaction() const { return transaction_; } const tx::Transaction &transaction() const { return *transaction_; }
raft::RaftInterface *raft(); raft::RaftInterface *raft();
auto &db() { return db_; } auto &db() { return db_; }
const auto &db() const { return db_; } const auto &db() const { return db_; }
@ -622,8 +623,8 @@ class GraphDbAccessor {
const Vertex *const vertex); const Vertex *const vertex);
private: private:
GraphDb &db_; GraphDb *db_;
tx::Transaction &transaction_; tx::Transaction *transaction_;
// Indicates if this db-accessor started the transaction and should Abort it // Indicates if this db-accessor started the transaction and should Abort it
// upon destruction. // upon destruction.
bool transaction_starter_; bool transaction_starter_;

View File

@ -206,13 +206,13 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
Value vertex_dv; Value vertex_dv;
RETURN_IF_NOT(decoder.ReadValue(&vertex_dv, Value::Type::Vertex)); RETURN_IF_NOT(decoder.ReadValue(&vertex_dv, Value::Type::Vertex));
auto &vertex = vertex_dv.ValueVertex(); auto &vertex = vertex_dv.ValueVertex();
auto vertex_accessor = dba->InsertVertex(vertex.id.AsUint()); auto vertex_accessor = dba.InsertVertex(vertex.id.AsUint());
for (const auto &label : vertex.labels) { for (const auto &label : vertex.labels) {
vertex_accessor.add_label(dba->Label(label)); vertex_accessor.add_label(dba.Label(label));
} }
for (const auto &property_pair : vertex.properties) { for (const auto &property_pair : vertex.properties) {
vertex_accessor.PropsSet(dba->Property(property_pair.first), vertex_accessor.PropsSet(dba.Property(property_pair.first),
glue::ToPropertyValue(property_pair.second)); glue::ToPropertyValue(property_pair.second));
} }
vertices.insert({vertex.id.AsUint(), vertex_accessor}); vertices.insert({vertex.id.AsUint(), vertex_accessor});
@ -226,11 +226,11 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
auto it_to = vertices.find(edge.to.AsUint()); auto it_to = vertices.find(edge.to.AsUint());
RETURN_IF_NOT(it_from != vertices.end() && it_to != vertices.end()); RETURN_IF_NOT(it_from != vertices.end() && it_to != vertices.end());
auto edge_accessor = auto edge_accessor =
dba->InsertEdge(it_from->second, it_to->second, dba.InsertEdge(it_from->second, it_to->second,
dba->EdgeType(edge.type), edge.id.AsUint()); dba.EdgeType(edge.type), edge.id.AsUint());
for (const auto &property_pair : edge.properties) for (const auto &property_pair : edge.properties)
edge_accessor.PropsSet(dba->Property(property_pair.first), edge_accessor.PropsSet(dba.Property(property_pair.first),
glue::ToPropertyValue(property_pair.second)); glue::ToPropertyValue(property_pair.second));
} }
@ -239,7 +239,7 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
reader.ReadType(vertex_count); reader.ReadType(vertex_count);
reader.ReadType(edge_count); reader.ReadType(edge_count);
if (!reader.Close() || reader.hash() != hash) { if (!reader.Close() || reader.hash() != hash) {
dba->Abort(); dba.Abort();
return false; return false;
} }
@ -250,8 +250,8 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
tx::TransactionId max_id = recovery_data->snapshooter_tx_id; tx::TransactionId max_id = recovery_data->snapshooter_tx_id;
auto &snap = recovery_data->snapshooter_tx_snapshot; auto &snap = recovery_data->snapshooter_tx_snapshot;
if (!snap.empty()) max_id = *std::max_element(snap.begin(), snap.end()); if (!snap.empty()) max_id = *std::max_element(snap.begin(), snap.end());
dba->db().tx_engine().EnsureNextIdGreater(max_id); dba.db().tx_engine().EnsureNextIdGreater(max_id);
dba->Commit(); dba.Commit();
return true; return true;
} }
@ -384,7 +384,7 @@ RecoveryTransactions::RecoveryTransactions(database::GraphDb *db) : db_(db) {}
void RecoveryTransactions::Begin(const tx::TransactionId &tx_id) { void RecoveryTransactions::Begin(const tx::TransactionId &tx_id) {
CHECK(accessors_.find(tx_id) == accessors_.end()) CHECK(accessors_.find(tx_id) == accessors_.end())
<< "Double transaction start"; << "Double transaction start";
accessors_.emplace(tx_id, db_->Access()); accessors_.emplace(tx_id, std::make_unique<database::GraphDbAccessor>(db_->Access()));
} }
void RecoveryTransactions::Abort(const tx::TransactionId &tx_id) { void RecoveryTransactions::Abort(const tx::TransactionId &tx_id) {
@ -599,15 +599,15 @@ void RecoverIndexes(database::GraphDb *db,
const std::vector<IndexRecoveryData> &indexes) { const std::vector<IndexRecoveryData> &indexes) {
auto dba = db->Access(); auto dba = db->Access();
for (const auto &index : indexes) { for (const auto &index : indexes) {
auto label = dba->Label(index.label); auto label = dba.Label(index.label);
auto property = dba->Property(index.property); auto property = dba.Property(index.property);
if (index.create) { if (index.create) {
dba->BuildIndex(label, property, index.unique); dba.BuildIndex(label, property, index.unique);
} else { } else {
dba->DeleteIndex(label, property); dba.DeleteIndex(label, property);
} }
} }
dba->Commit(); dba.Commit();
} }
void RecoverExistenceConstraints( void RecoverExistenceConstraints(
@ -615,17 +615,17 @@ void RecoverExistenceConstraints(
const std::vector<ExistenceConstraintRecoveryData> &constraints) { const std::vector<ExistenceConstraintRecoveryData> &constraints) {
auto dba = db->Access(); auto dba = db->Access();
for (auto &constraint : constraints) { for (auto &constraint : constraints) {
auto label = dba->Label(constraint.label); auto label = dba.Label(constraint.label);
std::vector<storage::Property> properties; std::vector<storage::Property> properties;
properties.reserve(constraint.properties.size()); properties.reserve(constraint.properties.size());
for (auto &prop : constraint.properties) { for (auto &prop : constraint.properties) {
properties.push_back(dba->Property(prop)); properties.push_back(dba.Property(prop));
} }
if (constraint.create) { if (constraint.create) {
dba->BuildExistenceConstraint(label, properties); dba.BuildExistenceConstraint(label, properties);
} else { } else {
dba->DeleteExistenceConstraint(label, properties); dba.DeleteExistenceConstraint(label, properties);
} }
} }
} }
@ -635,19 +635,19 @@ void RecoverUniqueConstraints(
const std::vector<UniqueConstraintRecoveryData> &constraints) { const std::vector<UniqueConstraintRecoveryData> &constraints) {
auto dba = db->Access(); auto dba = db->Access();
for (auto &constraint : constraints) { for (auto &constraint : constraints) {
auto label = dba->Label(constraint.label); auto label = dba.Label(constraint.label);
std::vector<storage::Property> properties; std::vector<storage::Property> properties;
properties.reserve(constraint.properties.size()); properties.reserve(constraint.properties.size());
for (auto &prop : constraint.properties) { for (auto &prop : constraint.properties) {
properties.push_back(dba->Property(prop)); properties.push_back(dba.Property(prop));
} }
DCHECK(properties.size() == 1) DCHECK(properties.size() == 1)
<< "Unique constraint with multiple properties is not supported"; << "Unique constraint with multiple properties is not supported";
if (constraint.create) { if (constraint.create) {
dba->BuildUniqueConstraint(label, properties[0]); dba.BuildUniqueConstraint(label, properties[0]);
} else { } else {
dba->DeleteUniqueConstraint(label, properties[0]); dba.DeleteUniqueConstraint(label, properties[0]);
} }
} }
} }

View File

@ -94,13 +94,13 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
Value vertex_dv; Value vertex_dv;
RETURN_IF_NOT(decoder.ReadValue(&vertex_dv, Value::Type::Vertex)); RETURN_IF_NOT(decoder.ReadValue(&vertex_dv, Value::Type::Vertex));
auto &vertex = vertex_dv.ValueVertex(); auto &vertex = vertex_dv.ValueVertex();
auto vertex_accessor = dba->InsertVertex(vertex.id.AsUint()); auto vertex_accessor = dba.InsertVertex(vertex.id.AsUint());
for (const auto &label : vertex.labels) { for (const auto &label : vertex.labels) {
vertex_accessor.add_label(dba->Label(label)); vertex_accessor.add_label(dba.Label(label));
} }
for (const auto &property_pair : vertex.properties) { for (const auto &property_pair : vertex.properties) {
vertex_accessor.PropsSet(dba->Property(property_pair.first), vertex_accessor.PropsSet(dba.Property(property_pair.first),
glue::ToPropertyValue(property_pair.second)); glue::ToPropertyValue(property_pair.second));
} }
vertices.insert({vertex.id.AsUint(), vertex_accessor}); vertices.insert({vertex.id.AsUint(), vertex_accessor});
@ -114,11 +114,11 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
auto it_to = vertices.find(edge.to.AsUint()); auto it_to = vertices.find(edge.to.AsUint());
RETURN_IF_NOT(it_from != vertices.end() && it_to != vertices.end()); RETURN_IF_NOT(it_from != vertices.end() && it_to != vertices.end());
auto edge_accessor = auto edge_accessor =
dba->InsertEdge(it_from->second, it_to->second, dba.InsertEdge(it_from->second, it_to->second,
dba->EdgeType(edge.type), edge.id.AsUint()); dba.EdgeType(edge.type), edge.id.AsUint());
for (const auto &property_pair : edge.properties) for (const auto &property_pair : edge.properties)
edge_accessor.PropsSet(dba->Property(property_pair.first), edge_accessor.PropsSet(dba.Property(property_pair.first),
glue::ToPropertyValue(property_pair.second)); glue::ToPropertyValue(property_pair.second));
} }
@ -127,7 +127,7 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
reader.ReadType(vertex_count); reader.ReadType(vertex_count);
reader.ReadType(edge_count); reader.ReadType(edge_count);
if (!reader.Close() || reader.hash() != hash) { if (!reader.Close() || reader.hash() != hash) {
dba->Abort(); dba.Abort();
return false; return false;
} }
@ -138,8 +138,8 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
tx::TransactionId max_id = recovery_data->snapshooter_tx_id; tx::TransactionId max_id = recovery_data->snapshooter_tx_id;
auto &snap = recovery_data->snapshooter_tx_snapshot; auto &snap = recovery_data->snapshooter_tx_snapshot;
if (!snap.empty()) max_id = *std::max_element(snap.begin(), snap.end()); if (!snap.empty()) max_id = *std::max_element(snap.begin(), snap.end());
dba->db().tx_engine().EnsureNextIdGreater(max_id); dba.db()->tx_engine().EnsureNextIdGreater(max_id);
dba->Commit(); dba.Commit();
return true; return true;
} }
@ -176,15 +176,15 @@ void RecoverIndexes(database::GraphDb *db,
const std::vector<IndexRecoveryData> &indexes) { const std::vector<IndexRecoveryData> &indexes) {
auto dba = db->Access(); auto dba = db->Access();
for (const auto &index : indexes) { for (const auto &index : indexes) {
auto label = dba->Label(index.label); auto label = dba.Label(index.label);
auto property = dba->Property(index.property); auto property = dba.Property(index.property);
if (index.create) { if (index.create) {
dba->BuildIndex(label, property, index.unique); dba.BuildIndex(label, property, index.unique);
} else { } else {
dba->DeleteIndex(label, property); dba.DeleteIndex(label, property);
} }
} }
dba->Commit(); dba.Commit();
} }
} // namespace durability } // namespace durability

View File

@ -131,7 +131,7 @@ void SingleNodeMain() {
durability_directory / "telemetry", std::chrono::minutes(10)); durability_directory / "telemetry", std::chrono::minutes(10));
telemetry->AddCollector("db", [&db]() -> nlohmann::json { telemetry->AddCollector("db", [&db]() -> nlohmann::json {
auto dba = db.Access(); auto dba = db.Access();
return {{"vertices", dba->VerticesCount()}, {"edges", dba->EdgesCount()}}; return {{"vertices", dba.VerticesCount()}, {"edges", dba.EdgesCount()}};
}); });
} }

View File

@ -124,12 +124,21 @@ void KafkaStreamWriter(
for (const auto &kv : params) for (const auto &kv : params)
params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second)); params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
try { try {
#ifndef MG_DISTRIBUTED
(*session_data.interpreter)(query, dba, params_pv, false).PullAll(stream);
dba.Commit();
#else
(*session_data.interpreter)(query, *dba, params_pv, false).PullAll(stream); (*session_data.interpreter)(query, *dba, params_pv, false).PullAll(stream);
dba->Commit(); dba->Commit();
#endif
} catch (const utils::BasicException &e) { } catch (const utils::BasicException &e) {
LOG(WARNING) << "[Kafka] query execution failed with an exception: " LOG(WARNING) << "[Kafka] query execution failed with an exception: "
<< e.what(); << e.what();
#ifndef MG_DISTRIBUTED
dba.Abort();
#else
dba->Abort(); dba->Abort();
#endif
} }
}; };

View File

@ -63,12 +63,20 @@ void query::Repl(database::GraphDb *db, query::Interpreter *interpreter) {
try { try {
auto dba = db->Access(); auto dba = db->Access();
ResultStreamFaker<query::TypedValue> stream; ResultStreamFaker<query::TypedValue> stream;
#ifndef MG_DISTRIBUTED
auto results = (*interpreter)(command, dba, {}, false);
#else
auto results = (*interpreter)(command, *dba, {}, false); auto results = (*interpreter)(command, *dba, {}, false);
#endif
stream.Header(results.header()); stream.Header(results.header());
results.PullAll(stream); results.PullAll(stream);
stream.Summary(results.summary()); stream.Summary(results.summary());
std::cout << stream; std::cout << stream;
#ifndef MG_DISTRIBUTED
dba.Commit();
#else
dba->Commit(); dba->Commit();
#endif
} catch (const query::SyntaxException &e) { } catch (const query::SyntaxException &e) {
std::cout << "SYNTAX EXCEPTION: " << e.what() << std::endl; std::cout << "SYNTAX EXCEPTION: " << e.what() << std::endl;
} catch (const query::LexingException &e) { } catch (const query::LexingException &e) {

View File

@ -58,7 +58,11 @@ class TransactionEngine final {
if (in_explicit_transaction_ && db_accessor_) AdvanceCommand(); if (in_explicit_transaction_ && db_accessor_) AdvanceCommand();
// Create a DB accessor if we don't yet have one. // Create a DB accessor if we don't yet have one.
#ifndef MG_DISTRIBUTED
if (!db_accessor_) db_accessor_.emplace(db_->Access());
#else
if (!db_accessor_) db_accessor_ = db_->Access(); if (!db_accessor_) db_accessor_ = db_->Access();
#endif
// Interpret the query and return the headers. // Interpret the query and return the headers.
try { try {
@ -104,13 +108,21 @@ class TransactionEngine final {
in_explicit_transaction_ = false; in_explicit_transaction_ = false;
if (!db_accessor_) return; if (!db_accessor_) return;
db_accessor_->Abort(); db_accessor_->Abort();
#ifndef MG_DISTRIBUTED
db_accessor_ = std::experimental::nullopt;
#else
db_accessor_ = nullptr; db_accessor_ = nullptr;
#endif
} }
private: private:
database::GraphDb *db_{nullptr}; database::GraphDb *db_{nullptr};
Interpreter *interpreter_{nullptr}; Interpreter *interpreter_{nullptr};
#ifndef MG_DISTRIBUTED
std::experimental::optional<database::GraphDbAccessor> db_accessor_;
#else
std::unique_ptr<database::GraphDbAccessor> db_accessor_; std::unique_ptr<database::GraphDbAccessor> db_accessor_;
#endif
// The `query::Interpreter::Results` object MUST be destroyed before the // The `query::Interpreter::Results` object MUST be destroyed before the
// `database::GraphDbAccessor` is destroyed because the `Results` object holds // `database::GraphDbAccessor` is destroyed because the `Results` object holds
// references to the `GraphDb` object and will crash the database when // references to the `GraphDb` object and will crash the database when
@ -123,7 +135,11 @@ class TransactionEngine final {
results_ = std::experimental::nullopt; results_ = std::experimental::nullopt;
if (!db_accessor_) return; if (!db_accessor_) return;
db_accessor_->Commit(); db_accessor_->Commit();
#ifndef MG_DISTRIBUTED
db_accessor_ = std::experimental::nullopt;
#else
db_accessor_ = nullptr; db_accessor_ = nullptr;
#endif
} }
void AdvanceCommand() { void AdvanceCommand() {

View File

@ -3,6 +3,7 @@
#include <kj/std/iostream.h> #include <kj/std/iostream.h>
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <experimental/optional>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
@ -982,20 +983,28 @@ void RaftServer::SnapshotThread() {
// Compare the log size to the config // Compare the log size to the config
if (config_.log_size_snapshot_threshold < committed_log_size) { if (config_.log_size_snapshot_threshold < committed_log_size) {
VLOG(40) << "[LogCompaction] Starting log compaction."; VLOG(40) << "[LogCompaction] Starting log compaction.";
// Create a DB accessor for snapshot creation
std::unique_ptr<database::GraphDbAccessor> dba = db_->Access();
uint64_t last_included_term = GetLogEntry(last_applied_).term;
uint64_t last_included_index = last_applied_;
std::string snapshot_filename =
durability::GetSnapshotFilename(dba->transaction_id());
lock.unlock(); uint64_t last_included_term = 0;
VLOG(40) << "[LogCompaction] Creating snapshot."; uint64_t last_included_index = 0;
bool status = durability::MakeSnapshot(*db_, *dba, durability_dir_, std::string snapshot_filename;
snapshot_filename); bool status = false;
// Raft lock must be released when destroying dba object. {
dba = nullptr; // Create a DB accessor for snapshot creation
auto dba = db_->Access();
last_included_term = GetLogEntry(last_applied_).term;
last_included_index = last_applied_;
snapshot_filename =
durability::GetSnapshotFilename(dba.transaction_id());
lock.unlock();
VLOG(40) << "[LogCompaction] Creating snapshot.";
status = durability::MakeSnapshot(*db_, dba, durability_dir_,
snapshot_filename);
// Raft lock must be released when destroying dba object.
// Destroy the db accessor
}
lock.lock(); lock.lock();
@ -1187,13 +1196,13 @@ void RaftServer::RecoverSnapshot(const std::string &snapshot_filename) {
void RaftServer::NoOpCreate() { void RaftServer::NoOpCreate() {
auto dba = db_->Access(); auto dba = db_->Access();
Emplace(database::StateDelta::NoOp(dba->transaction_id())); Emplace(database::StateDelta::NoOp(dba.transaction_id()));
dba->Commit(); dba.Commit();
} }
void RaftServer::ApplyStateDeltas( void RaftServer::ApplyStateDeltas(
const std::vector<database::StateDelta> &deltas) { const std::vector<database::StateDelta> &deltas) {
std::unique_ptr<database::GraphDbAccessor> dba = nullptr; std::experimental::optional<database::GraphDbAccessor> dba;
for (auto &delta : deltas) { for (auto &delta : deltas) {
switch (delta.type) { switch (delta.type) {
case database::StateDelta::Type::TRANSACTION_BEGIN: case database::StateDelta::Type::TRANSACTION_BEGIN:
@ -1204,7 +1213,7 @@ void RaftServer::ApplyStateDeltas(
CHECK(dba) << "Missing accessor for transaction" CHECK(dba) << "Missing accessor for transaction"
<< delta.transaction_id; << delta.transaction_id;
dba->Commit(); dba->Commit();
dba = nullptr; dba = std::experimental::nullopt;
break; break;
case database::StateDelta::Type::TRANSACTION_ABORT: case database::StateDelta::Type::TRANSACTION_ABORT:
LOG(FATAL) << "ApplyStateDeltas shouldn't know about aborted " LOG(FATAL) << "ApplyStateDeltas shouldn't know about aborted "

View File

@ -59,15 +59,15 @@ void Run(benchmark::State &state, bool enable_constraint) {
state.PauseTiming(); state.PauseTiming();
for (size_t i = 0; i < kNumOfConstraints; ++i) { for (size_t i = 0; i < kNumOfConstraints; ++i) {
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label(test_set.constraint_labels.at(i)); auto label = dba.Label(test_set.constraint_labels.at(i));
std::vector<storage::Property> props; std::vector<storage::Property> props;
props.reserve(kNumOfPropsInConstraint); props.reserve(kNumOfPropsInConstraint);
for (size_t j = 0; j < kNumOfPropsInConstraint; ++j) { for (size_t j = 0; j < kNumOfPropsInConstraint; ++j) {
props.push_back(dba->Property( props.push_back(dba.Property(
test_set.constraint_props.at(kNumOfPropsInConstraint * i + j))); test_set.constraint_props.at(kNumOfPropsInConstraint * i + j)));
} }
dba->BuildExistenceConstraint(label, props); dba.BuildExistenceConstraint(label, props);
dba->Commit(); dba.Commit();
} }
state.ResumeTiming(); state.ResumeTiming();
} }
@ -77,37 +77,37 @@ void Run(benchmark::State &state, bool enable_constraint) {
vertices.reserve(kNumOfVertices); vertices.reserve(kNumOfVertices);
for (size_t k = 0; k < kNumOfVertices; ++k) { for (size_t k = 0; k < kNumOfVertices; ++k) {
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
vertices.push_back(v.gid()); vertices.push_back(v.gid());
// Labels and properties that define constraints // Labels and properties that define constraints
for (size_t i = 0; i < kNumOfConstraints; ++i) { for (size_t i = 0; i < kNumOfConstraints; ++i) {
for (size_t j = 0; j < kNumOfPropsInConstraint; ++j) { for (size_t j = 0; j < kNumOfPropsInConstraint; ++j) {
v.PropsSet(dba->Property(test_set.constraint_props.at( v.PropsSet(dba.Property(test_set.constraint_props.at(
kNumOfPropsInConstraint * i + j)), kNumOfPropsInConstraint * i + j)),
test_set.short_prop_value); test_set.short_prop_value);
} }
auto label = dba->Label(test_set.constraint_labels.at(i)); auto label = dba.Label(test_set.constraint_labels.at(i));
v.add_label(label); v.add_label(label);
} }
// Add other labels // Add other labels
for (auto label : test_set.labels) { for (auto label : test_set.labels) {
v.add_label(dba->Label(label)); v.add_label(dba.Label(label));
} }
// Add other properties // Add other properties
for (auto prop : test_set.props) { for (auto prop : test_set.props) {
v.PropsSet(dba->Property(prop), test_set.short_prop_value); v.PropsSet(dba.Property(prop), test_set.short_prop_value);
} }
dba->Commit(); dba.Commit();
} }
// Delete all properties and labels // Delete all properties and labels
for (auto gid : vertices) { for (auto gid : vertices) {
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
std::vector<storage::Label> labels_to_del(v.labels()); std::vector<storage::Label> labels_to_del(v.labels());
for (auto &label : labels_to_del) { for (auto &label : labels_to_del) {
v.remove_label(label); v.remove_label(label);
@ -119,9 +119,9 @@ void Run(benchmark::State &state, bool enable_constraint) {
// Delete all vertices // Delete all vertices
for (auto gid : vertices) { for (auto gid : vertices) {
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
dba->RemoveVertex(v); dba.RemoveVertex(v);
dba->Commit(); dba.Commit();
} }
} }
} }

View File

@ -18,23 +18,23 @@ class ExpansionBenchFixture : public benchmark::Fixture {
void SetUp(const benchmark::State &state) override { void SetUp(const benchmark::State &state) override {
db_.emplace(); db_.emplace();
auto dba = db_->Access(); auto dba = db_->Access();
for (int i = 0; i < state.range(0); i++) dba->InsertVertex(); for (int i = 0; i < state.range(0); i++) dba.InsertVertex();
// the fixed part is one vertex expanding to 1000 others // the fixed part is one vertex expanding to 1000 others
auto start = dba->InsertVertex(); auto start = dba.InsertVertex();
start.add_label(dba->Label("Starting")); start.add_label(dba.Label("Starting"));
auto edge_type = dba->EdgeType("edge_type"); auto edge_type = dba.EdgeType("edge_type");
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
auto dest = dba->InsertVertex(); auto dest = dba.InsertVertex();
dba->InsertEdge(start, dest, edge_type); dba.InsertEdge(start, dest, edge_type);
} }
dba->Commit(); dba.Commit();
} }
void TearDown(const benchmark::State &) override { void TearDown(const benchmark::State &) override {
auto dba = db_->Access(); auto dba = db_->Access();
for (auto vertex : dba->Vertices(false)) dba->DetachRemoveVertex(vertex); for (auto vertex : dba.Vertices(false)) dba.DetachRemoveVertex(vertex);
dba->Commit(); dba.Commit();
db_ = std::experimental::nullopt; db_ = std::experimental::nullopt;
} }
@ -46,7 +46,7 @@ BENCHMARK_DEFINE_F(ExpansionBenchFixture, Match)(benchmark::State &state) {
auto dba = db_->Access(); auto dba = db_->Access();
while (state.KeepRunning()) { while (state.KeepRunning()) {
ResultStreamFaker<query::TypedValue> results; ResultStreamFaker<query::TypedValue> results;
interpreter()(query, *dba, {}, false).PullAll(results); interpreter()(query, dba, {}, false).PullAll(results);
} }
} }
@ -60,7 +60,7 @@ BENCHMARK_DEFINE_F(ExpansionBenchFixture, Expand)(benchmark::State &state) {
auto dba = db_->Access(); auto dba = db_->Access();
while (state.KeepRunning()) { while (state.KeepRunning()) {
ResultStreamFaker<query::TypedValue> results; ResultStreamFaker<query::TypedValue> results;
interpreter()(query, *dba, {}, false).PullAll(results); interpreter()(query, dba, {}, false).PullAll(results);
} }
} }

View File

@ -43,7 +43,7 @@ static void BM_PlanChainedMatches(benchmark::State &state) {
auto *query = AddChainedMatches(num_matches, storage); auto *query = AddChainedMatches(num_matches, storage);
auto symbol_table = query::MakeSymbolTable(query); auto symbol_table = query::MakeSymbolTable(query);
auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query, auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query,
dba.get()); &dba);
state.ResumeTiming(); state.ResumeTiming();
auto query_parts = auto query_parts =
query::plan::CollectQueryParts(symbol_table, storage, query); query::plan::CollectQueryParts(symbol_table, storage, query);
@ -91,18 +91,18 @@ static query::CypherQuery *AddIndexedMatches(int num_matches,
static auto CreateIndexedVertices(int index_count, int vertex_count, static auto CreateIndexedVertices(int index_count, int vertex_count,
database::GraphDb &db) { database::GraphDb &db) {
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
auto dba = db.Access(); auto dba = db.Access();
for (int vi = 0; vi < vertex_count; ++vi) { for (int vi = 0; vi < vertex_count; ++vi) {
for (int index = 0; index < index_count; ++index) { for (int index = 0; index < index_count; ++index) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
vertex.PropsSet(prop, index); vertex.PropsSet(prop, index);
} }
} }
dba->Commit(); dba.Commit();
return std::make_pair("label", "prop"); return std::make_pair("label", "prop");
} }
@ -122,7 +122,7 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
auto symbol_table = query::MakeSymbolTable(query); auto symbol_table = query::MakeSymbolTable(query);
state.ResumeTiming(); state.ResumeTiming();
auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query, auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query,
dba.get()); &dba);
auto query_parts = auto query_parts =
query::plan::CollectQueryParts(symbol_table, storage, query); query::plan::CollectQueryParts(symbol_table, storage, query);
if (query_parts.query_parts.size() == 0) { if (query_parts.query_parts.size() == 0) {
@ -132,7 +132,7 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
auto plans = query::plan::MakeLogicalPlanForSingleQuery< auto plans = query::plan::MakeLogicalPlanForSingleQuery<
query::plan::VariableStartPlanner>(single_query_parts, &ctx); query::plan::VariableStartPlanner>(single_query_parts, &ctx);
for (auto plan : plans) { for (auto plan : plans) {
query::plan::EstimatePlanCost(dba.get(), parameters, *plan); query::plan::EstimatePlanCost(&dba, parameters, *plan);
} }
} }
} }
@ -146,7 +146,7 @@ static void BM_PlanAndEstimateIndexedMatchingWithCachedCounts(
int vertex_count = state.range(1); int vertex_count = state.range(1);
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db); std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db);
auto dba = db.Access(); auto dba = db.Access();
auto vertex_counts = query::plan::MakeVertexCountCache(dba.get()); auto vertex_counts = query::plan::MakeVertexCountCache(&dba);
query::Parameters parameters; query::Parameters parameters;
while (state.KeepRunning()) { while (state.KeepRunning()) {
state.PauseTiming(); state.PauseTiming();

View File

@ -14,6 +14,6 @@ int main(int argc, char *argv[]) {
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
RunInteractivePlanning(dba.get()); RunInteractivePlanning(&dba);
return 0; return 0;
} }

View File

@ -59,7 +59,7 @@ class RandomGraphGenerator {
auto dba = db_.Access(); auto dba = db_.Access();
std::vector<storage::Label> labels; std::vector<storage::Label> labels;
for (const auto &label_name : label_names) for (const auto &label_name : label_names)
labels.push_back(dba->Label(label_name)); labels.push_back(dba.Label(label_name));
Map( Map(
[&labels, this](database::GraphDbAccessor &dba) { [&labels, this](database::GraphDbAccessor &dba) {
@ -77,7 +77,7 @@ class RandomGraphGenerator {
*/ */
int64_t VertexCount() const { int64_t VertexCount() const {
auto accessor = db_.Access(); auto accessor = db_.Access();
return CountIterable(accessor->Vertices(true)); return CountIterable(accessor.Vertices(true));
} }
/** /**
@ -102,11 +102,11 @@ class RandomGraphGenerator {
auto vertices_to = FilterVertices(to_filter); auto vertices_to = FilterVertices(to_filter);
auto dba = db_.Access(); auto dba = db_.Access();
auto edge_type = dba->EdgeType(edge_type_name); auto edge_type = dba.EdgeType(edge_type_name);
// for small vertex counts reduce the batch size // for small vertex counts reduce the batch size
batch_size = batch_size =
std::min(batch_size, static_cast<int>(dba->VerticesCount() / 1000 + 1)); std::min(batch_size, static_cast<int>(dba.VerticesCount() / 1000 + 1));
Map( Map(
[&vertices_from, &vertices_to, edge_type, [&vertices_from, &vertices_to, edge_type,
@ -129,7 +129,7 @@ class RandomGraphGenerator {
*/ */
int64_t EdgeCount() const { int64_t EdgeCount() const {
auto accessor = db_.Access(); auto accessor = db_.Access();
return CountIterable(accessor->Edges(true)); return CountIterable(accessor.Edges(true));
} }
/** /**
@ -147,10 +147,10 @@ class RandomGraphGenerator {
std::function<bool(VertexAccessor &va)> predicate = {}) { std::function<bool(VertexAccessor &va)> predicate = {}) {
if (!predicate) predicate = [](VertexAccessor &) { return true; }; if (!predicate) predicate = [](VertexAccessor &) { return true; };
auto dba = db_.Access(); auto dba = db_.Access();
auto property = dba->Property(prop_name); auto property = dba.Property(prop_name);
for (VertexAccessor va : dba->Vertices(false)) for (VertexAccessor va : dba.Vertices(false))
if (predicate(va)) va.PropsSet(property, value_generator()); if (predicate(va)) va.PropsSet(property, value_generator());
dba->Commit(); dba.Commit();
} }
private: private:
@ -176,7 +176,7 @@ class RandomGraphGenerator {
if (!predicate) predicate = [](VertexAccessor &) { return true; }; if (!predicate) predicate = [](VertexAccessor &) { return true; };
std::vector<VertexAccessor> r_val; std::vector<VertexAccessor> r_val;
auto dba = db_.Access(); auto dba = db_.Access();
for (VertexAccessor &item : dba->Vertices(false)) for (VertexAccessor &item : dba.Vertices(false))
if (predicate(item)) r_val.emplace_back(item); if (predicate(item)) r_val.emplace_back(item);
return r_val; return r_val;
@ -211,9 +211,9 @@ class RandomGraphGenerator {
int apply_count = int apply_count =
std::min(elements_per_commit, count_per_thread - i); std::min(elements_per_commit, count_per_thread - i);
while (apply_count--) { while (apply_count--) {
f(*dba); f(dba);
} }
dba->Commit(); dba.Commit();
break; break;
} catch (...) { } catch (...) {
} }

View File

@ -14,7 +14,7 @@ int main(int argc, char *argv[]) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
ResultStreamFaker<query::TypedValue> stream; ResultStreamFaker<query::TypedValue> stream;
auto results = query::Interpreter()(argv[1], *dba, {}, false); auto results = query::Interpreter()(argv[1], dba, {}, false);
stream.Header(results.header()); stream.Header(results.header());
results.PullAll(stream); results.PullAll(stream);
stream.Summary(results.summary()); stream.Summary(results.summary());

View File

@ -32,8 +32,8 @@ RC_GTEST_PROP(RandomGraph, RandomGraph, (std::vector<std::string> vertex_labels,
auto dba = db.Access(); auto dba = db.Access();
for (auto label : vertex_labels) { for (auto label : vertex_labels) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(dba->Label(label)); vertex_accessor.add_label(dba.Label(label));
vertex_label_map.insert({vertex_accessor, label}); vertex_label_map.insert({vertex_accessor, label});
vertices.push_back(vertex_accessor); vertices.push_back(vertex_accessor);
} }
@ -41,23 +41,23 @@ RC_GTEST_PROP(RandomGraph, RandomGraph, (std::vector<std::string> vertex_labels,
for (auto type : edge_types) { for (auto type : edge_types) {
auto from = vertices[*rc::gen::inRange(0, vertices_num)]; auto from = vertices[*rc::gen::inRange(0, vertices_num)];
auto to = vertices[*rc::gen::inRange(0, vertices_num)]; auto to = vertices[*rc::gen::inRange(0, vertices_num)];
auto edge_accessor = dba->InsertEdge(from, to, dba->EdgeType(type)); auto edge_accessor = dba.InsertEdge(from, to, dba.EdgeType(type));
edge_type_map.insert({edge_accessor, type}); edge_type_map.insert({edge_accessor, type});
} }
dba->AdvanceCommand(); dba.AdvanceCommand();
int edges_num_check = 0; int edges_num_check = 0;
int vertices_num_check = 0; int vertices_num_check = 0;
for (const auto &vertex : dba->Vertices(false)) { for (const auto &vertex : dba.Vertices(false)) {
auto label = vertex_label_map.at(vertex); auto label = vertex_label_map.at(vertex);
RC_ASSERT(vertex.labels().size() == 1); RC_ASSERT(vertex.labels().size() == 1);
RC_ASSERT(dba->LabelName(vertex.labels()[0]) == label); RC_ASSERT(dba.LabelName(vertex.labels()[0]) == label);
vertices_num_check++; vertices_num_check++;
} }
for (const auto &edge : dba->Edges(false)) { for (const auto &edge : dba.Edges(false)) {
auto type = edge_type_map.at(edge); auto type = edge_type_map.at(edge);
RC_ASSERT(dba->EdgeTypeName(edge.EdgeType()) == type); RC_ASSERT(dba.EdgeTypeName(edge.EdgeType()) == type);
edges_num_check++; edges_num_check++;
} }
RC_ASSERT(vertices_num_check == vertices_num); RC_ASSERT(vertices_num_check == vertices_num);

View File

@ -8,12 +8,14 @@ class SingleNodeDb : public Database {
SingleNodeDb() : db_() {} SingleNodeDb() : db_() {}
std::unique_ptr<database::GraphDbAccessor> Access() override { std::unique_ptr<database::GraphDbAccessor> Access() override {
return db_.Access(); std::unique_ptr<database::GraphDbAccessor> dba =
std::make_unique<database::GraphDbAccessor>(db_.Access());
return dba;
} }
void AdvanceCommand(tx::TransactionId tx_id) override { void AdvanceCommand(tx::TransactionId tx_id) override {
auto dba = db_.Access(tx_id); auto dba = db_.Access(tx_id);
dba->AdvanceCommand(); dba.AdvanceCommand();
} }
std::unique_ptr<LogicalOperator> MakeBfsOperator( std::unique_ptr<LogicalOperator> MakeBfsOperator(

View File

@ -166,23 +166,23 @@ TEST(BoltEncoder, VertexAndEdge) {
// create vertex // create vertex
database::GraphDb db; database::GraphDb db;
auto db_accessor = db.Access(); auto db_accessor = db.Access();
auto va1 = db_accessor->InsertVertex(); auto va1 = db_accessor.InsertVertex();
auto va2 = db_accessor->InsertVertex(); auto va2 = db_accessor.InsertVertex();
auto l1 = db_accessor->Label("label1"); auto l1 = db_accessor.Label("label1");
auto l2 = db_accessor->Label("label2"); auto l2 = db_accessor.Label("label2");
va1.add_label(l1); va1.add_label(l1);
va1.add_label(l2); va1.add_label(l2);
auto p1 = db_accessor->Property("prop1"); auto p1 = db_accessor.Property("prop1");
auto p2 = db_accessor->Property("prop2"); auto p2 = db_accessor.Property("prop2");
PropertyValue pv1(12), pv2(200); PropertyValue pv1(12), pv2(200);
va1.PropsSet(p1, pv1); va1.PropsSet(p1, pv1);
va1.PropsSet(p2, pv2); va1.PropsSet(p2, pv2);
// create edge // create edge
auto et = db_accessor->EdgeType("edgetype"); auto et = db_accessor.EdgeType("edgetype");
auto ea = db_accessor->InsertEdge(va1, va2, et); auto ea = db_accessor.InsertEdge(va1, va2, et);
auto p3 = db_accessor->Property("prop3"); auto p3 = db_accessor.Property("prop3");
auto p4 = db_accessor->Property("prop4"); auto p4 = db_accessor.Property("prop4");
PropertyValue pv3(42), pv4(1234); PropertyValue pv3(42), pv4(1234);
ea.PropsSet(p3, pv3); ea.PropsSet(p3, pv3);
ea.PropsSet(p4, pv4); ea.PropsSet(p4, pv4);

View File

@ -23,21 +23,21 @@ TEST(LabelsIndex, UniqueInsert) {
engine.Commit(*t1); engine.Commit(*t1);
auto t2 = engine.Begin(); auto t2 = engine.Begin();
vlist.find(*t2)->labels_.push_back(dba->Label("1")); vlist.find(*t2)->labels_.push_back(dba.Label("1"));
index.Update(dba->Label("1"), &vlist, vlist.find(*t2)); index.Update(dba.Label("1"), &vlist, vlist.find(*t2));
// Try multiple inserts // Try multiple inserts
index.Update(dba->Label("1"), &vlist, vlist.find(*t2)); index.Update(dba.Label("1"), &vlist, vlist.find(*t2));
vlist.find(*t2)->labels_.push_back(dba->Label("2")); vlist.find(*t2)->labels_.push_back(dba.Label("2"));
index.Update(dba->Label("2"), &vlist, vlist.find(*t2)); index.Update(dba.Label("2"), &vlist, vlist.find(*t2));
vlist.find(*t2)->labels_.push_back(dba->Label("3")); vlist.find(*t2)->labels_.push_back(dba.Label("3"));
index.Update(dba->Label("3"), &vlist, vlist.find(*t2)); index.Update(dba.Label("3"), &vlist, vlist.find(*t2));
engine.Commit(*t2); engine.Commit(*t2);
EXPECT_EQ(index.Count(dba->Label("1")), 1); EXPECT_EQ(index.Count(dba.Label("1")), 1);
EXPECT_EQ(index.Count(dba->Label("2")), 1); EXPECT_EQ(index.Count(dba.Label("2")), 1);
EXPECT_EQ(index.Count(dba->Label("3")), 1); EXPECT_EQ(index.Count(dba.Label("3")), 1);
} }
// Check if index filters duplicates. // Check if index filters duplicates.
@ -55,7 +55,7 @@ TEST(LabelsIndex, UniqueFilter) {
auto r1v2 = vlist2.find(*t1); auto r1v2 = vlist2.find(*t1);
EXPECT_NE(vlist1.find(*t1), nullptr); EXPECT_NE(vlist1.find(*t1), nullptr);
auto label1 = dba->Label("1"); auto label1 = dba.Label("1");
vlist1.find(*t1)->labels_.push_back(label1); vlist1.find(*t1)->labels_.push_back(label1);
vlist2.find(*t1)->labels_.push_back(label1); vlist2.find(*t1)->labels_.push_back(label1);
index.Update(label1, &vlist1, r1v1); index.Update(label1, &vlist1, r1v1);
@ -98,7 +98,7 @@ TEST(LabelsIndex, Refresh) {
EXPECT_NE(v1r1, nullptr); EXPECT_NE(v1r1, nullptr);
EXPECT_NE(v2r1, nullptr); EXPECT_NE(v2r1, nullptr);
auto label = access->Label("label"); auto label = access.Label("label");
v1r1->labels_.push_back(label); v1r1->labels_.push_back(label);
v2r1->labels_.push_back(label); v2r1->labels_.push_back(label);
index.Update(label, &vlist1, v1r1); index.Update(label, &vlist1, v1r1);
@ -124,9 +124,9 @@ TEST(LabelsIndex, Refresh) {
TEST(LabelsIndexDb, AddGetZeroLabels) { TEST(LabelsIndexDb, AddGetZeroLabels) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(dba->Label("test")); vertex.add_label(dba.Label("test"));
auto collection = dba->Vertices(dba->Label("test"), false); auto collection = dba.Vertices(dba.Label("test"), false);
std::vector<VertexAccessor> collection_vector(collection.begin(), std::vector<VertexAccessor> collection_vector(collection.begin(),
collection.end()); collection.end());
EXPECT_EQ(collection_vector.size(), (size_t)0); EXPECT_EQ(collection_vector.size(), (size_t)0);
@ -139,59 +139,59 @@ TEST(LabelsIndexDb, AddGetRemoveLabel) {
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex1 = dba->InsertVertex(); auto vertex1 = dba.InsertVertex();
vertex1.add_label(dba->Label("test")); vertex1.add_label(dba.Label("test"));
auto vertex2 = dba->InsertVertex(); auto vertex2 = dba.InsertVertex();
vertex2.add_label(dba->Label("test2")); vertex2.add_label(dba.Label("test2"));
auto vertex3 = dba->InsertVertex(); auto vertex3 = dba.InsertVertex();
vertex3.add_label(dba->Label("test")); vertex3.add_label(dba.Label("test"));
dba->Commit(); dba.Commit();
} // Finish transaction. } // Finish transaction.
{ {
auto dba = db.Access(); auto dba = db.Access();
auto filtered = dba->Vertices(dba->Label("test"), false); auto filtered = dba.Vertices(dba.Label("test"), false);
std::vector<VertexAccessor> collection(filtered.begin(), filtered.end()); std::vector<VertexAccessor> collection(filtered.begin(), filtered.end());
auto vertices = dba->Vertices(false); auto vertices = dba.Vertices(false);
std::vector<VertexAccessor> expected_collection; std::vector<VertexAccessor> expected_collection;
for (auto vertex : vertices) { for (auto vertex : vertices) {
if (vertex.has_label(dba->Label("test"))) { if (vertex.has_label(dba.Label("test"))) {
expected_collection.push_back(vertex); expected_collection.push_back(vertex);
} else { } else {
EXPECT_TRUE(vertex.has_label(dba->Label("test2"))); EXPECT_TRUE(vertex.has_label(dba.Label("test2")));
} }
} }
EXPECT_EQ(expected_collection.size(), collection.size()); EXPECT_EQ(expected_collection.size(), collection.size());
EXPECT_TRUE(collection[0].has_label(dba->Label("test"))); EXPECT_TRUE(collection[0].has_label(dba.Label("test")));
EXPECT_TRUE(collection[1].has_label(dba->Label("test"))); EXPECT_TRUE(collection[1].has_label(dba.Label("test")));
EXPECT_FALSE(collection[0].has_label(dba->Label("test2"))); EXPECT_FALSE(collection[0].has_label(dba.Label("test2")));
EXPECT_FALSE(collection[1].has_label(dba->Label("test2"))); EXPECT_FALSE(collection[1].has_label(dba.Label("test2")));
dba->RemoveVertex(collection[0]); // Remove from database and test if dba.RemoveVertex(collection[0]); // Remove from database and test if
// index won't return it. // index won't return it.
// Remove label from the vertex and add new label. // Remove label from the vertex and add new label.
collection[1].remove_label(dba->Label("test")); collection[1].remove_label(dba.Label("test"));
collection[1].add_label(dba->Label("test2")); collection[1].add_label(dba.Label("test2"));
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto filtered = dba->Vertices(dba->Label("test"), false); auto filtered = dba.Vertices(dba.Label("test"), false);
std::vector<VertexAccessor> collection(filtered.begin(), filtered.end()); std::vector<VertexAccessor> collection(filtered.begin(), filtered.end());
auto vertices = dba->Vertices(false); auto vertices = dba.Vertices(false);
std::vector<VertexAccessor> expected_collection; std::vector<VertexAccessor> expected_collection;
for (auto vertex : vertices) { for (auto vertex : vertices) {
if (vertex.has_label(dba->Label("test"))) { if (vertex.has_label(dba.Label("test"))) {
expected_collection.push_back(vertex); expected_collection.push_back(vertex);
} else { } else {
EXPECT_TRUE(vertex.has_label(dba->Label("test2"))); EXPECT_TRUE(vertex.has_label(dba.Label("test2")));
} }
} }

View File

@ -15,10 +15,10 @@ class LabelPropertyIndexComplexTest : public ::testing::Test {
virtual void SetUp() { virtual void SetUp() {
auto accessor = db_.Access(); auto accessor = db_.Access();
label = accessor->Label("label"); label = accessor.Label("label");
property = accessor->Property("property"); property = accessor.Property("property");
label2 = accessor->Label("label2"); label2 = accessor.Label("label2");
property2 = accessor->Property("property2"); property2 = accessor.Property("property2");
key = new LabelPropertyIndex::Key(label, property); key = new LabelPropertyIndex::Key(label, property);
EXPECT_EQ(index.CreateIndex(*key), true); EXPECT_EQ(index.CreateIndex(*key), true);
@ -60,8 +60,8 @@ class LabelPropertyIndexComplexTest : public ::testing::Test {
TEST(LabelPropertyIndex, CreateIndex) { TEST(LabelPropertyIndex, CreateIndex) {
GraphDb db; GraphDb db;
auto accessor = db.Access(); auto accessor = db.Access();
LabelPropertyIndex::Key key(accessor->Label("test"), LabelPropertyIndex::Key key(accessor.Label("test"),
accessor->Property("test2")); accessor.Property("test2"));
LabelPropertyIndex index; LabelPropertyIndex index;
EXPECT_EQ(index.CreateIndex(key), true); EXPECT_EQ(index.CreateIndex(key), true);
EXPECT_EQ(index.CreateIndex(key), false); EXPECT_EQ(index.CreateIndex(key), false);
@ -70,8 +70,8 @@ TEST(LabelPropertyIndex, CreateIndex) {
TEST(LabelPropertyIndex, DeleteIndex) { TEST(LabelPropertyIndex, DeleteIndex) {
GraphDb db; GraphDb db;
auto accessor = db.Access(); auto accessor = db.Access();
LabelPropertyIndex::Key key(accessor->Label("test"), LabelPropertyIndex::Key key(accessor.Label("test"),
accessor->Property("test2")); accessor.Property("test2"));
LabelPropertyIndex index; LabelPropertyIndex index;
EXPECT_EQ(index.CreateIndex(key), true); EXPECT_EQ(index.CreateIndex(key), true);
EXPECT_EQ(index.CreateIndex(key), false); EXPECT_EQ(index.CreateIndex(key), false);
@ -82,8 +82,8 @@ TEST(LabelPropertyIndex, DeleteIndex) {
TEST(LabelPropertyIndex, IndexExistance) { TEST(LabelPropertyIndex, IndexExistance) {
GraphDb db; GraphDb db;
auto accessor = db.Access(); auto accessor = db.Access();
LabelPropertyIndex::Key key(accessor->Label("test"), LabelPropertyIndex::Key key(accessor.Label("test"),
accessor->Property("test2")); accessor.Property("test2"));
LabelPropertyIndex index; LabelPropertyIndex index;
EXPECT_EQ(index.CreateIndex(key), true); EXPECT_EQ(index.CreateIndex(key), true);
// Index doesn't exist - and can't be used untill it's been notified as built. // Index doesn't exist - and can't be used untill it's been notified as built.
@ -93,8 +93,8 @@ TEST(LabelPropertyIndex, IndexExistance) {
TEST(LabelPropertyIndex, Count) { TEST(LabelPropertyIndex, Count) {
GraphDb db; GraphDb db;
auto accessor = db.Access(); auto accessor = db.Access();
auto label = accessor->Label("label"); auto label = accessor.Label("label");
auto property = accessor->Property("property"); auto property = accessor.Property("property");
LabelPropertyIndex::Key key(label, property); LabelPropertyIndex::Key key(label, property);
LabelPropertyIndex index; LabelPropertyIndex index;
EXPECT_EQ(index.CreateIndex(key), true); EXPECT_EQ(index.CreateIndex(key), true);

View File

@ -17,16 +17,16 @@ TEST(TransactionTimeout, TransactionTimeout) {
}; };
{ {
auto dba = db.Access(); auto dba = db.Access();
interpret(*dba, "MATCH (n) RETURN n"); interpret(dba, "MATCH (n) RETURN n");
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
std::this_thread::sleep_for(std::chrono::seconds(5)); std::this_thread::sleep_for(std::chrono::seconds(5));
ASSERT_THROW(interpret(*dba, "MATCH (n) RETURN n"), ASSERT_THROW(interpret(dba, "MATCH (n) RETURN n"),
query::HintedAbortError); query::HintedAbortError);
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
interpret(*dba, "MATCH (n) RETURN n"); interpret(dba, "MATCH (n) RETURN n");
} }
} }

View File

@ -218,24 +218,24 @@ void CompareDbs(database::GraphDb &a, database::GraphDb &b) {
auto dba_b = b.Access(); auto dba_b = b.Access();
{ {
auto index_a = dba_a->IndexInfo(); auto index_a = dba_a.IndexInfo();
auto index_b = dba_b->IndexInfo(); auto index_b = dba_b.IndexInfo();
EXPECT_TRUE( EXPECT_TRUE(
index_a.size() == index_b.size() && index_a.size() == index_b.size() &&
std::is_permutation(index_a.begin(), index_a.end(), index_b.begin())) std::is_permutation(index_a.begin(), index_a.end(), index_b.begin()))
<< "Indexes not equal [" << utils::Join(index_a, ", ") << "] != [" << "Indexes not equal [" << utils::Join(index_a, ", ") << "] != ["
<< utils::Join(index_b, ", "); << utils::Join(index_b, ", ");
} }
EXPECT_TRUE(CompareExistenceConstraints(*dba_a, *dba_b)); EXPECT_TRUE(CompareExistenceConstraints(dba_a, dba_b));
EXPECT_TRUE(CompareUniqueConstraints(*dba_a, *dba_b)); EXPECT_TRUE(CompareUniqueConstraints(dba_a, dba_b));
auto is_permutation_props = [&dba_a, &dba_b](const auto &p1_id, auto is_permutation_props = [&dba_a, &dba_b](const auto &p1_id,
const auto &p2_id) { const auto &p2_id) {
std::vector<std::pair<std::string, query::TypedValue>> p1; std::vector<std::pair<std::string, query::TypedValue>> p1;
std::vector<std::pair<std::string, query::TypedValue>> p2; std::vector<std::pair<std::string, query::TypedValue>> p2;
for (auto x : p1_id) p1.push_back({dba_a->PropertyName(x.first), x.second}); for (auto x : p1_id) p1.push_back({dba_a.PropertyName(x.first), x.second});
for (auto x : p2_id) p2.push_back({dba_b->PropertyName(x.first), x.second}); for (auto x : p2_id) p2.push_back({dba_b.PropertyName(x.first), x.second});
// Don't use a binary predicate which depends on different value getters // Don't use a binary predicate which depends on different value getters
// semantics for two containers because is_permutation might call the // semantics for two containers because is_permutation might call the
@ -251,37 +251,37 @@ void CompareDbs(database::GraphDb &a, database::GraphDb &b) {
{ {
int vertices_a_count = 0; int vertices_a_count = 0;
for (auto v_a : dba_a->Vertices(false)) { for (auto v_a : dba_a.Vertices(false)) {
vertices_a_count++; vertices_a_count++;
auto v_b = dba_b->FindVertexOptional(v_a.gid(), false); auto v_b = dba_b.FindVertexOptional(v_a.gid(), false);
ASSERT_TRUE(v_b) << "Vertex not found, id: " << v_a.gid(); ASSERT_TRUE(v_b) << "Vertex not found, id: " << v_a.gid();
ASSERT_EQ(v_a.labels().size(), v_b->labels().size()); ASSERT_EQ(v_a.labels().size(), v_b->labels().size());
std::vector<std::string> v_a_labels; std::vector<std::string> v_a_labels;
std::vector<std::string> v_b_labels; std::vector<std::string> v_b_labels;
for (auto x : v_a.labels()) v_a_labels.push_back(dba_a->LabelName(x)); for (auto x : v_a.labels()) v_a_labels.push_back(dba_a.LabelName(x));
for (auto x : v_b->labels()) v_b_labels.push_back(dba_b->LabelName(x)); for (auto x : v_b->labels()) v_b_labels.push_back(dba_b.LabelName(x));
EXPECT_TRUE(std::is_permutation(v_a_labels.begin(), v_a_labels.end(), EXPECT_TRUE(std::is_permutation(v_a_labels.begin(), v_a_labels.end(),
v_b_labels.begin())); v_b_labels.begin()));
EXPECT_TRUE(is_permutation_props(v_a.Properties(), v_b->Properties())); EXPECT_TRUE(is_permutation_props(v_a.Properties(), v_b->Properties()));
} }
auto vertices_b = dba_b->Vertices(false); auto vertices_b = dba_b.Vertices(false);
EXPECT_EQ(std::distance(vertices_b.begin(), vertices_b.end()), EXPECT_EQ(std::distance(vertices_b.begin(), vertices_b.end()),
vertices_a_count); vertices_a_count);
} }
{ {
int edges_a_count = 0; int edges_a_count = 0;
for (auto e_a : dba_a->Edges(false)) { for (auto e_a : dba_a.Edges(false)) {
edges_a_count++; edges_a_count++;
auto e_b = dba_b->FindEdgeOptional(e_a.gid(), false); auto e_b = dba_b.FindEdgeOptional(e_a.gid(), false);
ASSERT_TRUE(e_b); ASSERT_TRUE(e_b);
ASSERT_TRUE(e_b) << "Edge not found, id: " << e_a.gid(); ASSERT_TRUE(e_b) << "Edge not found, id: " << e_a.gid();
EXPECT_EQ(dba_a->EdgeTypeName(e_a.EdgeType()), EXPECT_EQ(dba_a.EdgeTypeName(e_a.EdgeType()),
dba_b->EdgeTypeName(e_b->EdgeType())); dba_b.EdgeTypeName(e_b->EdgeType()));
EXPECT_EQ(e_a.from().gid(), e_b->from().gid()); EXPECT_EQ(e_a.from().gid(), e_b->from().gid());
EXPECT_EQ(e_a.to().gid(), e_b->to().gid()); EXPECT_EQ(e_a.to().gid(), e_b->to().gid());
EXPECT_TRUE(is_permutation_props(e_a.Properties(), e_b->Properties())); EXPECT_TRUE(is_permutation_props(e_a.Properties(), e_b->Properties()));
} }
auto edges_b = dba_b->Edges(false); auto edges_b = dba_b.Edges(false);
EXPECT_EQ(std::distance(edges_b.begin(), edges_b.end()), edges_a_count); EXPECT_EQ(std::distance(edges_b.begin(), edges_b.end()), edges_a_count);
} }
} }
@ -327,8 +327,8 @@ void MakeDb(database::GraphDbAccessor &dba, int scale,
void MakeDb(database::GraphDb &db, int scale, std::vector<int> indices = {}) { void MakeDb(database::GraphDb &db, int scale, std::vector<int> indices = {}) {
auto dba = db.Access(); auto dba = db.Access();
MakeDb(*dba, scale, indices); MakeDb(dba, scale, indices);
dba->Commit(); dba.Commit();
} }
class Durability : public ::testing::Test { class Durability : public ::testing::Test {
@ -365,7 +365,7 @@ class Durability : public ::testing::Test {
void MakeSnapshot(database::GraphDb &db, int snapshot_max_retained = -1) { void MakeSnapshot(database::GraphDb &db, int snapshot_max_retained = -1) {
auto dba = db.Access(); auto dba = db.Access();
ASSERT_TRUE(durability::MakeSnapshot(db, *dba, durability_dir_, ASSERT_TRUE(durability::MakeSnapshot(db, dba, durability_dir_,
snapshot_max_retained)); snapshot_max_retained));
} }
@ -393,18 +393,18 @@ TEST_F(Durability, WalEncoding) {
config.durability_enabled = true; config.durability_enabled = true;
database::GraphDb db{config}; database::GraphDb db{config};
auto dba = db.Access(); auto dba = db.Access();
auto v0 = dba->InsertVertex(); auto v0 = dba.InsertVertex();
ASSERT_EQ(v0.gid(), gid0); ASSERT_EQ(v0.gid(), gid0);
v0.add_label(dba->Label("l0")); v0.add_label(dba.Label("l0"));
v0.PropsSet(dba->Property("p0"), 42); v0.PropsSet(dba.Property("p0"), 42);
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
ASSERT_EQ(v1.gid(), gid1); ASSERT_EQ(v1.gid(), gid1);
auto e0 = dba->InsertEdge(v0, v1, dba->EdgeType("et0")); auto e0 = dba.InsertEdge(v0, v1, dba.EdgeType("et0"));
ASSERT_EQ(e0.gid(), gid0); ASSERT_EQ(e0.gid(), gid0);
e0.PropsSet(dba->Property("p0"), std::vector<PropertyValue>{1, 2, 3}); e0.PropsSet(dba.Property("p0"), std::vector<PropertyValue>{1, 2, 3});
dba->BuildIndex(dba->Label("l1"), dba->Property("p1"), false); dba.BuildIndex(dba.Label("l1"), dba.Property("p1"), false);
dba->DeleteIndex(dba->Label("l1"), dba->Property("p1")); dba.DeleteIndex(dba.Label("l1"), dba.Property("p1"));
dba->Commit(); dba.Commit();
db.wal().Flush(); db.wal().Flush();
} }
@ -478,25 +478,25 @@ TEST_F(Durability, SnapshotEncoding) {
{ {
database::GraphDb db{DbConfig()}; database::GraphDb db{DbConfig()};
auto dba = db.Access(); auto dba = db.Access();
auto v0 = dba->InsertVertex(); auto v0 = dba.InsertVertex();
ASSERT_EQ(v0.gid(), gid0); ASSERT_EQ(v0.gid(), gid0);
v0.add_label(dba->Label("l0")); v0.add_label(dba.Label("l0"));
v0.PropsSet(dba->Property("p0"), 42); v0.PropsSet(dba.Property("p0"), 42);
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
ASSERT_EQ(v1.gid(), gid1); ASSERT_EQ(v1.gid(), gid1);
v1.add_label(dba->Label("l0")); v1.add_label(dba.Label("l0"));
v1.add_label(dba->Label("l1")); v1.add_label(dba.Label("l1"));
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
ASSERT_EQ(v2.gid(), gid2); ASSERT_EQ(v2.gid(), gid2);
v2.PropsSet(dba->Property("p0"), true); v2.PropsSet(dba.Property("p0"), true);
v2.PropsSet(dba->Property("p1"), "Johnny"); v2.PropsSet(dba.Property("p1"), "Johnny");
auto e0 = dba->InsertEdge(v0, v1, dba->EdgeType("et0")); auto e0 = dba.InsertEdge(v0, v1, dba.EdgeType("et0"));
ASSERT_EQ(e0.gid(), gid0); ASSERT_EQ(e0.gid(), gid0);
e0.PropsSet(dba->Property("p0"), std::vector<PropertyValue>{1, 2, 3}); e0.PropsSet(dba.Property("p0"), std::vector<PropertyValue>{1, 2, 3});
auto e1 = dba->InsertEdge(v2, v1, dba->EdgeType("et1")); auto e1 = dba.InsertEdge(v2, v1, dba.EdgeType("et1"));
ASSERT_EQ(e1.gid(), gid1); ASSERT_EQ(e1.gid(), gid1);
dba->BuildIndex(dba->Label("l1"), dba->Property("p1"), false); dba.BuildIndex(dba.Label("l1"), dba.Property("p1"), false);
dba->Commit(); dba.Commit();
MakeSnapshot(db); MakeSnapshot(db);
} }
@ -665,33 +665,33 @@ TEST_F(Durability, SnapshotAndWalRecoveryAfterComplexTxSituation) {
// The first transaction modifies and commits. // The first transaction modifies and commits.
auto dba_1 = db.Access(); auto dba_1 = db.Access();
MakeDb(*dba_1, 100); MakeDb(dba_1, 100);
dba_1->Commit(); dba_1.Commit();
// The second transaction will commit after snapshot. // The second transaction will commit after snapshot.
auto dba_2 = db.Access(); auto dba_2 = db.Access();
MakeDb(*dba_2, 100); MakeDb(dba_2, 100);
// The third transaction modifies and commits. // The third transaction modifies and commits.
auto dba_3 = db.Access(); auto dba_3 = db.Access();
MakeDb(*dba_3, 100); MakeDb(dba_3, 100);
dba_3->Commit(); dba_3.Commit();
MakeSnapshot(db); // Snapshooter takes the fourth transaction. MakeSnapshot(db); // Snapshooter takes the fourth transaction.
dba_2->Commit(); dba_2.Commit();
// The fifth transaction starts and commits after snapshot. // The fifth transaction starts and commits after snapshot.
auto dba_5 = db.Access(); auto dba_5 = db.Access();
MakeDb(*dba_5, 100); MakeDb(dba_5, 100);
dba_5->Commit(); dba_5.Commit();
// The sixth transaction will not commit at all. // The sixth transaction will not commit at all.
auto dba_6 = db.Access(); auto dba_6 = db.Access();
MakeDb(*dba_6, 100); MakeDb(dba_6, 100);
auto VisibleVertexCount = [](database::GraphDb &db) { auto VisibleVertexCount = [](database::GraphDb &db) {
auto dba = db.Access(); auto dba = db.Access();
auto vertices = dba->Vertices(false); auto vertices = dba.Vertices(false);
return std::distance(vertices.begin(), vertices.end()); return std::distance(vertices.begin(), vertices.end());
}; };
ASSERT_EQ(VisibleVertexCount(db), 400); ASSERT_EQ(VisibleVertexCount(db), 400);
@ -805,8 +805,8 @@ TEST_F(Durability, WorkerIdRecovery) {
EXPECT_EQ(recovered.WorkerId(), config.worker_id); EXPECT_EQ(recovered.WorkerId(), config.worker_id);
CompareDbs(db, recovered); CompareDbs(db, recovered);
auto dba = recovered.Access(); auto dba = recovered.Access();
EXPECT_NE(dba->VerticesCount(), 0); EXPECT_NE(dba.VerticesCount(), 0);
EXPECT_NE(dba->EdgesCount(), 0); EXPECT_NE(dba.EdgesCount(), 0);
recovered.Shutdown(); recovered.Shutdown();
EXPECT_TRUE(recovered.AwaitShutdown()); EXPECT_TRUE(recovered.AwaitShutdown());
} }
@ -820,8 +820,8 @@ TEST_F(Durability, WorkerIdRecovery) {
database::Master recovered{config}; database::Master recovered{config};
EXPECT_NE(recovered.WorkerId(), db.WorkerId()); EXPECT_NE(recovered.WorkerId(), db.WorkerId());
auto dba = recovered.Access(); auto dba = recovered.Access();
EXPECT_EQ(dba->VerticesCount(), 0); EXPECT_EQ(dba.VerticesCount(), 0);
EXPECT_EQ(dba->EdgesCount(), 0); EXPECT_EQ(dba.EdgesCount(), 0);
recovered.Shutdown(); recovered.Shutdown();
EXPECT_TRUE(recovered.AwaitShutdown()); EXPECT_TRUE(recovered.AwaitShutdown());
} }
@ -843,8 +843,8 @@ TEST_F(Durability, SequentialRecovery) {
auto init_db = [](database::GraphDb &db) { auto init_db = [](database::GraphDb &db) {
auto dba = db.Access(); auto dba = db.Access();
for (int i = 0; i < kNumVertices; ++i) dba->InsertVertex(i); for (int i = 0; i < kNumVertices; ++i) dba.InsertVertex(i);
dba->Commit(); dba.Commit();
}; };
auto run_updates = [&random_int](database::GraphDb &db, auto run_updates = [&random_int](database::GraphDb &db,
@ -854,14 +854,14 @@ TEST_F(Durability, SequentialRecovery) {
threads.emplace_back([&random_int, &db, &keep_running]() { threads.emplace_back([&random_int, &db, &keep_running]() {
while (keep_running) { while (keep_running) {
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->FindVertex(random_int(kNumVertices), false); auto v = dba.FindVertex(random_int(kNumVertices), false);
try { try {
v.PropsSet(dba->Property("prop"), random_int(100)); v.PropsSet(dba.Property("prop"), random_int(100));
} catch (utils::LockTimeoutException &) { } catch (utils::LockTimeoutException &) {
} catch (mvcc::SerializationError &) { } catch (mvcc::SerializationError &) {
} }
dba->InsertVertex(); dba.InsertVertex();
dba->Commit(); dba.Commit();
} }
}); });
} }
@ -918,7 +918,7 @@ TEST_F(Durability, ContainsDurabilityFilesSnapshot) {
{ {
database::GraphDb db{DbConfig()}; database::GraphDb db{DbConfig()};
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
MakeSnapshot(db); MakeSnapshot(db);
} }
ASSERT_TRUE(durability::ContainsDurabilityFiles(durability_dir_)); ASSERT_TRUE(durability::ContainsDurabilityFiles(durability_dir_));
@ -929,8 +929,8 @@ TEST_F(Durability, ContainsDurabilityFilesWal) {
{ {
database::GraphDb db{DbConfig(true, false)}; database::GraphDb db{DbConfig(true, false)};
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
dba->Commit(); dba.Commit();
db.wal().Flush(); db.wal().Flush();
} }
ASSERT_TRUE(durability::ContainsDurabilityFiles(durability_dir_)); ASSERT_TRUE(durability::ContainsDurabilityFiles(durability_dir_));
@ -941,7 +941,7 @@ TEST_F(Durability, MoveToBackupSnapshot) {
{ {
database::GraphDb db{DbConfig()}; database::GraphDb db{DbConfig()};
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
MakeSnapshot(db); MakeSnapshot(db);
} }
@ -955,8 +955,8 @@ TEST_F(Durability, MoveToBackupWal) {
{ {
database::GraphDb db{DbConfig(true, false)}; database::GraphDb db{DbConfig(true, false)};
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
dba->Commit(); dba.Commit();
db.wal().Flush(); db.wal().Flush();
} }
@ -971,32 +971,32 @@ TEST_F(Durability, UniqueIndexRecoverySnapshotAndWal) {
database::GraphDb db{config}; database::GraphDb db{config};
{ {
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label("A"); auto label = dba.Label("A");
auto property = dba->Property("x"); auto property = dba.Property("x");
dba->BuildIndex(label, property, true); dba.BuildIndex(label, property, true);
auto v0 = dba->InsertVertex(); auto v0 = dba.InsertVertex();
v0.add_label(label); v0.add_label(label);
v0.PropsSet(property, 5); v0.PropsSet(property, 5);
dba->Commit(); dba.Commit();
} }
// create snapshot with build index and vertex // create snapshot with build index and vertex
MakeSnapshot(db); MakeSnapshot(db);
{ {
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label("A"); auto label = dba.Label("A");
auto property = dba->Property("x"); auto property = dba.Property("x");
dba->DeleteIndex(label, property); dba.DeleteIndex(label, property);
auto v0 = dba->InsertVertex(); auto v0 = dba.InsertVertex();
v0.add_label(label); v0.add_label(label);
v0.PropsSet(property, 5); v0.PropsSet(property, 5);
dba->Commit(); dba.Commit();
} }
// create wal with drop index and vertex // create wal with drop index and vertex
db.wal().Flush(); db.wal().Flush();
@ -1015,22 +1015,22 @@ TEST_F(Durability, UniqueIndexRecoveryWal) {
database::GraphDb db{config}; database::GraphDb db{config};
{ {
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label("A"); auto label = dba.Label("A");
auto property = dba->Property("x"); auto property = dba.Property("x");
dba->BuildIndex(label, property, true); dba.BuildIndex(label, property, true);
auto v0 = dba->InsertVertex(); auto v0 = dba.InsertVertex();
v0.add_label(label); v0.add_label(label);
v0.PropsSet(property, 5); v0.PropsSet(property, 5);
dba->DeleteIndex(label, property); dba.DeleteIndex(label, property);
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(label); v1.add_label(label);
v1.PropsSet(property, 5); v1.PropsSet(property, 5);
dba->Commit(); dba.Commit();
} }
db.wal().Flush(); db.wal().Flush();
{ {
@ -1047,21 +1047,21 @@ TEST_F(Durability, ExistenceConstraintRecoveryWal) {
{ {
// Fill database with some data // Fill database with some data
auto dba = db.Access(); auto dba = db.Access();
DbGenerator gen(*dba); DbGenerator gen(dba);
dba->InsertVertex(); dba.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
auto l1 = dba->Label("l1"); auto l1 = dba.Label("l1");
std::vector<storage::Property> p1{dba->Property("p1"), dba->Property("p2")}; std::vector<storage::Property> p1{dba.Property("p1"), dba.Property("p2")};
dba->BuildExistenceConstraint(l1, p1); dba.BuildExistenceConstraint(l1, p1);
gen.InsertEdge(); gen.InsertEdge();
auto l2 = dba->Label("l2"); auto l2 = dba.Label("l2");
std::vector<storage::Property> p2{dba->Property("p3"), dba->Property("p4")}; std::vector<storage::Property> p2{dba.Property("p3"), dba.Property("p4")};
dba->BuildExistenceConstraint(l2, p2); dba.BuildExistenceConstraint(l2, p2);
gen.InsertVertex(); gen.InsertVertex();
gen.InsertEdge(); gen.InsertEdge();
dba->DeleteExistenceConstraint(l1, p1); dba.DeleteExistenceConstraint(l1, p1);
dba->Commit(); dba.Commit();
} }
{ {
// Recover and compare // Recover and compare
@ -1078,34 +1078,34 @@ TEST_F(Durability, ExistenceConstraintRecoverySnapshotAndWal) {
{ {
// Fill database with some data // Fill database with some data
auto dba = db.Access(); auto dba = db.Access();
DbGenerator gen(*dba); DbGenerator gen(dba);
dba->InsertVertex(); dba.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
auto l1 = dba->Label("l1"); auto l1 = dba.Label("l1");
std::vector<storage::Property> p1{dba->Property("p1"), dba->Property("p2")}; std::vector<storage::Property> p1{dba.Property("p1"), dba.Property("p2")};
dba->BuildExistenceConstraint(l1, p1); dba.BuildExistenceConstraint(l1, p1);
gen.InsertEdge(); gen.InsertEdge();
auto l2 = dba->Label("l2"); auto l2 = dba.Label("l2");
std::vector<storage::Property> p2{dba->Property("p3"), dba->Property("p4")}; std::vector<storage::Property> p2{dba.Property("p3"), dba.Property("p4")};
dba->BuildExistenceConstraint(l2, p2); dba.BuildExistenceConstraint(l2, p2);
gen.InsertVertex(); gen.InsertVertex();
gen.InsertEdge(); gen.InsertEdge();
dba->DeleteExistenceConstraint(l1, p1); dba.DeleteExistenceConstraint(l1, p1);
dba->Commit(); dba.Commit();
} }
// create snapshot with build existence constraint // create snapshot with build existence constraint
MakeSnapshot(db); MakeSnapshot(db);
{ {
auto dba = db.Access(); auto dba = db.Access();
DbGenerator gen(*dba); DbGenerator gen(dba);
gen.InsertVertex(); gen.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
auto l3 = dba->Label("l3"); auto l3 = dba.Label("l3");
std::vector<storage::Property> p3{dba->Property("p5"), dba->Property("p6")}; std::vector<storage::Property> p3{dba.Property("p5"), dba.Property("p6")};
dba->BuildExistenceConstraint(l3, p3); dba.BuildExistenceConstraint(l3, p3);
dba->Commit(); dba.Commit();
} }
{ {
// Recover and compare // Recover and compare
@ -1122,21 +1122,21 @@ TEST_F(Durability, UniqueConstraintRecoveryWal) {
{ {
// Fill database with some data // Fill database with some data
auto dba = db.Access(); auto dba = db.Access();
DbGenerator gen(*dba); DbGenerator gen(dba);
dba->InsertVertex(); dba.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
auto l1 = dba->Label("l1"); auto l1 = dba.Label("l1");
auto p1 = dba->Property("p1"); auto p1 = dba.Property("p1");
dba->BuildUniqueConstraint(l1, p1); dba.BuildUniqueConstraint(l1, p1);
gen.InsertEdge(); gen.InsertEdge();
auto l2 = dba->Label("l2"); auto l2 = dba.Label("l2");
auto p2 = dba->Property("p2"); auto p2 = dba.Property("p2");
dba->BuildUniqueConstraint(l2, p2); dba.BuildUniqueConstraint(l2, p2);
gen.InsertVertex(); gen.InsertVertex();
gen.InsertEdge(); gen.InsertEdge();
dba->DeleteUniqueConstraint(l1, p1); dba.DeleteUniqueConstraint(l1, p1);
dba->Commit(); dba.Commit();
} }
{ {
// Recover and compare // Recover and compare
@ -1153,34 +1153,34 @@ TEST_F(Durability, UniqueConstraintRecoverySnapshotAndWal) {
{ {
// Fill database with some data // Fill database with some data
auto dba = db.Access(); auto dba = db.Access();
DbGenerator gen(*dba); DbGenerator gen(dba);
dba->InsertVertex(); dba.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
auto l1 = dba->Label("l1"); auto l1 = dba.Label("l1");
auto p1 = dba->Property("p1"); auto p1 = dba.Property("p1");
dba->BuildUniqueConstraint(l1, p1); dba.BuildUniqueConstraint(l1, p1);
gen.InsertEdge(); gen.InsertEdge();
auto l2 = dba->Label("l2"); auto l2 = dba.Label("l2");
auto p2 = dba->Property("p2"); auto p2 = dba.Property("p2");
dba->BuildUniqueConstraint(l2, p2); dba.BuildUniqueConstraint(l2, p2);
gen.InsertVertex(); gen.InsertVertex();
gen.InsertEdge(); gen.InsertEdge();
dba->DeleteUniqueConstraint(l1, p1); dba.DeleteUniqueConstraint(l1, p1);
dba->Commit(); dba.Commit();
} }
// create snapshot with build unique constraint // create snapshot with build unique constraint
MakeSnapshot(db); MakeSnapshot(db);
{ {
auto dba = db.Access(); auto dba = db.Access();
DbGenerator gen(*dba); DbGenerator gen(dba);
gen.InsertVertex(); gen.InsertVertex();
gen.InsertVertex(); gen.InsertVertex();
auto l3 = dba->Label("l3"); auto l3 = dba.Label("l3");
auto p3 = dba->Property("p3"); auto p3 = dba.Property("p3");
dba->BuildUniqueConstraint(l3, p3); dba.BuildUniqueConstraint(l3, p3);
dba->Commit(); dba.Commit();
} }
{ {
// Recover and compare // Recover and compare

View File

@ -9,11 +9,11 @@ class ExistenceConstraintsTest : public ::testing::Test {
public: public:
void SetUp() override { void SetUp() override {
auto dba = db_.Access(); auto dba = db_.Access();
label_ = dba->Label("label"); label_ = dba.Label("label");
property_ = dba->Property("property"); property_ = dba.Property("property");
properties_ = {property_}; properties_ = {property_};
rule_ = {label_, properties_}; rule_ = {label_, properties_};
dba->Commit(); dba.Commit();
} }
storage::constraints::ExistenceConstraints constraints_; storage::constraints::ExistenceConstraints constraints_;
@ -27,33 +27,33 @@ class ExistenceConstraintsTest : public ::testing::Test {
TEST_F(ExistenceConstraintsTest, BuildDrop) { TEST_F(ExistenceConstraintsTest, BuildDrop) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_FALSE(dba->ExistenceConstraintExists(label_, properties_)); EXPECT_FALSE(dba.ExistenceConstraintExists(label_, properties_));
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_); dba.BuildExistenceConstraint(label_, properties_);
EXPECT_TRUE(dba->ExistenceConstraintExists(label_, properties_)); EXPECT_TRUE(dba.ExistenceConstraintExists(label_, properties_));
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->DeleteExistenceConstraint(label_, properties_); dba.DeleteExistenceConstraint(label_, properties_);
EXPECT_FALSE(dba->ExistenceConstraintExists(label_, properties_)); EXPECT_FALSE(dba.ExistenceConstraintExists(label_, properties_));
dba->Commit(); dba.Commit();
} }
} }
TEST_F(ExistenceConstraintsTest, BuildWithViolation) { TEST_F(ExistenceConstraintsTest, BuildWithViolation) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_THROW(dba->BuildExistenceConstraint(label_, properties_), EXPECT_THROW(dba.BuildExistenceConstraint(label_, properties_),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
} }
@ -61,12 +61,12 @@ TEST_F(ExistenceConstraintsTest, BuildWithViolation) {
TEST_F(ExistenceConstraintsTest, InsertFail) { TEST_F(ExistenceConstraintsTest, InsertFail) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_); dba.BuildExistenceConstraint(label_, properties_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
EXPECT_THROW(v.add_label(label_), EXPECT_THROW(v.add_label(label_),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
@ -75,36 +75,36 @@ TEST_F(ExistenceConstraintsTest, InsertFail) {
TEST_F(ExistenceConstraintsTest, InsertPass) { TEST_F(ExistenceConstraintsTest, InsertPass) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_); dba.BuildExistenceConstraint(label_, properties_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property_, PropertyValue("Something")); v.PropsSet(property_, PropertyValue("Something"));
v.add_label(label_); v.add_label(label_);
dba->Commit(); dba.Commit();
} }
} }
TEST_F(ExistenceConstraintsTest, RemoveFail) { TEST_F(ExistenceConstraintsTest, RemoveFail) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_); dba.BuildExistenceConstraint(label_, properties_);
dba->Commit(); dba.Commit();
} }
gid::Gid gid; gid::Gid gid;
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property_, PropertyValue("Something")); v.PropsSet(property_, PropertyValue("Something"));
v.add_label(label_); v.add_label(label_);
gid = v.gid(); gid = v.gid();
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
EXPECT_THROW(v.PropsErase(property_), EXPECT_THROW(v.PropsErase(property_),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
@ -113,24 +113,24 @@ TEST_F(ExistenceConstraintsTest, RemoveFail) {
TEST_F(ExistenceConstraintsTest, RemovePass) { TEST_F(ExistenceConstraintsTest, RemovePass) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_); dba.BuildExistenceConstraint(label_, properties_);
dba->Commit(); dba.Commit();
} }
gid::Gid gid; gid::Gid gid;
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property_, PropertyValue("Something")); v.PropsSet(property_, PropertyValue("Something"));
v.add_label(label_); v.add_label(label_);
gid = v.gid(); gid = v.gid();
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
v.remove_label(label_); v.remove_label(label_);
v.PropsErase(property_); v.PropsErase(property_);
dba->Commit(); dba.Commit();
} }
} }

View File

@ -11,28 +11,28 @@ TEST(GraphDbTest, GarbageCollectIndices) {
database::Config config; database::Config config;
config.gc_cycle_sec = -1; config.gc_cycle_sec = -1;
database::GraphDb graph_db{config}; database::GraphDb graph_db{config};
std::unique_ptr<database::GraphDbAccessor> dba = graph_db.Access(); auto dba = graph_db.Access();
auto commit = [&] { auto commit = [&] {
dba->Commit(); dba.Commit();
dba = graph_db.Access(); dba = graph_db.Access();
}; };
auto label = dba->Label("label"); auto label = dba.Label("label");
auto property = dba->Property("property"); auto property = dba.Property("property");
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
commit(); commit();
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
vertex.PropsSet(property, 42); vertex.PropsSet(property, 42);
commit(); commit();
EXPECT_EQ(dba->VerticesCount(label, property), 1); EXPECT_EQ(dba.VerticesCount(label, property), 1);
auto vertex_transferred = dba->Transfer(vertex); auto vertex_transferred = dba.Transfer(vertex);
dba->RemoveVertex(vertex_transferred.value()); dba.RemoveVertex(vertex_transferred.value());
EXPECT_EQ(dba->VerticesCount(label, property), 1); EXPECT_EQ(dba.VerticesCount(label, property), 1);
commit(); commit();
EXPECT_EQ(dba->VerticesCount(label, property), 1); EXPECT_EQ(dba.VerticesCount(label, property), 1);
graph_db.CollectGarbage(); graph_db.CollectGarbage();
EXPECT_EQ(dba->VerticesCount(label, property), 0); EXPECT_EQ(dba.VerticesCount(label, property), 0);
} }

View File

@ -21,19 +21,19 @@ TEST(GraphDbAccessorTest, InsertVertex) {
auto accessor = db.Access(); auto accessor = db.Access();
gid::Generator generator; gid::Generator generator;
EXPECT_EQ(Count(accessor->Vertices(false)), 0); EXPECT_EQ(Count(accessor.Vertices(false)), 0);
EXPECT_EQ(accessor->InsertVertex().gid(), generator.Next()); EXPECT_EQ(accessor.InsertVertex().gid(), generator.Next());
EXPECT_EQ(Count(accessor->Vertices(false)), 0); EXPECT_EQ(Count(accessor.Vertices(false)), 0);
EXPECT_EQ(Count(accessor->Vertices(true)), 1); EXPECT_EQ(Count(accessor.Vertices(true)), 1);
accessor->AdvanceCommand(); accessor.AdvanceCommand();
EXPECT_EQ(Count(accessor->Vertices(false)), 1); EXPECT_EQ(Count(accessor.Vertices(false)), 1);
EXPECT_EQ(accessor->InsertVertex().gid(), generator.Next()); EXPECT_EQ(accessor.InsertVertex().gid(), generator.Next());
EXPECT_EQ(Count(accessor->Vertices(false)), 1); EXPECT_EQ(Count(accessor.Vertices(false)), 1);
EXPECT_EQ(Count(accessor->Vertices(true)), 2); EXPECT_EQ(Count(accessor.Vertices(true)), 2);
accessor->AdvanceCommand(); accessor.AdvanceCommand();
EXPECT_EQ(Count(accessor->Vertices(false)), 2); EXPECT_EQ(Count(accessor.Vertices(false)), 2);
} }
TEST(GraphDbAccessorTest, UniqueVertexId) { TEST(GraphDbAccessorTest, UniqueVertexId) {
@ -45,7 +45,7 @@ TEST(GraphDbAccessorTest, UniqueVertexId) {
threads.emplace_back([&db, &ids]() { threads.emplace_back([&db, &ids]() {
auto dba = db.Access(); auto dba = db.Access();
auto access = ids.access(); auto access = ids.access();
for (int i = 0; i < 200; i++) access.insert(dba->InsertVertex().gid()); for (int i = 0; i < 200; i++) access.insert(dba.InsertVertex().gid());
}); });
} }
@ -57,18 +57,18 @@ TEST(GraphDbAccessorTest, RemoveVertexSameTransaction) {
GraphDb db; GraphDb db;
auto accessor = db.Access(); auto accessor = db.Access();
EXPECT_EQ(Count(accessor->Vertices(false)), 0); EXPECT_EQ(Count(accessor.Vertices(false)), 0);
auto va1 = accessor->InsertVertex(); auto va1 = accessor.InsertVertex();
accessor->AdvanceCommand(); accessor.AdvanceCommand();
EXPECT_EQ(Count(accessor->Vertices(false)), 1); EXPECT_EQ(Count(accessor.Vertices(false)), 1);
EXPECT_TRUE(accessor->RemoveVertex(va1)); EXPECT_TRUE(accessor.RemoveVertex(va1));
EXPECT_EQ(Count(accessor->Vertices(false)), 1); EXPECT_EQ(Count(accessor.Vertices(false)), 1);
EXPECT_EQ(Count(accessor->Vertices(true)), 0); EXPECT_EQ(Count(accessor.Vertices(true)), 0);
accessor->AdvanceCommand(); accessor.AdvanceCommand();
EXPECT_EQ(Count(accessor->Vertices(false)), 0); EXPECT_EQ(Count(accessor.Vertices(false)), 0);
EXPECT_EQ(Count(accessor->Vertices(true)), 0); EXPECT_EQ(Count(accessor.Vertices(true)), 0);
} }
TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) { TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) {
@ -76,23 +76,23 @@ TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) {
// first transaction creates a vertex // first transaction creates a vertex
{ {
auto accessor = db.Access(); auto accessor = db.Access();
accessor->InsertVertex(); accessor.InsertVertex();
accessor->Commit(); accessor.Commit();
} }
// second transaction checks that it sees it, and deletes it // second transaction checks that it sees it, and deletes it
{ {
auto accessor = db.Access(); auto accessor = db.Access();
EXPECT_EQ(Count(accessor->Vertices(false)), 1); EXPECT_EQ(Count(accessor.Vertices(false)), 1);
EXPECT_EQ(Count(accessor->Vertices(true)), 1); EXPECT_EQ(Count(accessor.Vertices(true)), 1);
for (auto vertex_accessor : accessor->Vertices(false)) for (auto vertex_accessor : accessor.Vertices(false))
accessor->RemoveVertex(vertex_accessor); accessor.RemoveVertex(vertex_accessor);
accessor->Commit(); accessor.Commit();
} }
// third transaction checks that it does not see the vertex // third transaction checks that it does not see the vertex
{ {
auto accessor = db.Access(); auto accessor = db.Access();
EXPECT_EQ(Count(accessor->Vertices(false)), 0); EXPECT_EQ(Count(accessor.Vertices(false)), 0);
EXPECT_EQ(Count(accessor->Vertices(true)), 0); EXPECT_EQ(Count(accessor.Vertices(true)), 0);
} }
} }
@ -100,21 +100,21 @@ TEST(GraphDbAccessorTest, InsertEdge) {
GraphDb db; GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto va1 = dba->InsertVertex(); auto va1 = dba.InsertVertex();
auto va2 = dba->InsertVertex(); auto va2 = dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(va1.in_degree(), 0); EXPECT_EQ(va1.in_degree(), 0);
EXPECT_EQ(va1.out_degree(), 0); EXPECT_EQ(va1.out_degree(), 0);
EXPECT_EQ(va2.in_degree(), 0); EXPECT_EQ(va2.in_degree(), 0);
EXPECT_EQ(va2.out_degree(), 0); EXPECT_EQ(va2.out_degree(), 0);
// setup (v1) - [:likes] -> (v2) // setup (v1) - [:likes] -> (v2)
dba->InsertEdge(va1, va2, dba->EdgeType("likes")); dba.InsertEdge(va1, va2, dba.EdgeType("likes"));
EXPECT_EQ(Count(dba->Edges(false)), 0); EXPECT_EQ(Count(dba.Edges(false)), 0);
EXPECT_EQ(Count(dba->Edges(true)), 1); EXPECT_EQ(Count(dba.Edges(true)), 1);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(Count(dba->Edges(false)), 1); EXPECT_EQ(Count(dba.Edges(false)), 1);
EXPECT_EQ(Count(dba->Edges(true)), 1); EXPECT_EQ(Count(dba.Edges(true)), 1);
EXPECT_EQ(va1.out().begin()->to(), va2); EXPECT_EQ(va1.out().begin()->to(), va2);
EXPECT_EQ(va2.in().begin()->from(), va1); EXPECT_EQ(va2.in().begin()->from(), va1);
EXPECT_EQ(va1.in_degree(), 0); EXPECT_EQ(va1.in_degree(), 0);
@ -123,12 +123,12 @@ TEST(GraphDbAccessorTest, InsertEdge) {
EXPECT_EQ(va2.out_degree(), 0); EXPECT_EQ(va2.out_degree(), 0);
// setup (v1) - [:likes] -> (v2) <- [:hates] - (v3) // setup (v1) - [:likes] -> (v2) <- [:hates] - (v3)
auto va3 = dba->InsertVertex(); auto va3 = dba.InsertVertex();
dba->InsertEdge(va3, va2, dba->EdgeType("hates")); dba.InsertEdge(va3, va2, dba.EdgeType("hates"));
EXPECT_EQ(Count(dba->Edges(false)), 1); EXPECT_EQ(Count(dba.Edges(false)), 1);
EXPECT_EQ(Count(dba->Edges(true)), 2); EXPECT_EQ(Count(dba.Edges(true)), 2);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(Count(dba->Edges(false)), 2); EXPECT_EQ(Count(dba.Edges(false)), 2);
EXPECT_EQ(va3.out().begin()->to(), va2); EXPECT_EQ(va3.out().begin()->to(), va2);
EXPECT_EQ(va1.in_degree(), 0); EXPECT_EQ(va1.in_degree(), 0);
EXPECT_EQ(va1.out_degree(), 1); EXPECT_EQ(va1.out_degree(), 1);
@ -146,12 +146,12 @@ TEST(GraphDbAccessorTest, UniqueEdgeId) {
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
threads.emplace_back([&db, &ids]() { threads.emplace_back([&db, &ids]() {
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto edge_type = dba->EdgeType("edge_type"); auto edge_type = dba.EdgeType("edge_type");
auto access = ids.access(); auto access = ids.access();
for (int i = 0; i < 200; i++) for (int i = 0; i < 200; i++)
access.insert(dba->InsertEdge(v1, v2, edge_type).gid()); access.insert(dba.InsertEdge(v1, v2, edge_type).gid());
}); });
} }
@ -164,34 +164,34 @@ TEST(GraphDbAccessorTest, RemoveEdge) {
auto dba = db.Access(); auto dba = db.Access();
// setup (v1) - [:likes] -> (v2) <- [:hates] - (v3) // setup (v1) - [:likes] -> (v2) <- [:hates] - (v3)
auto va1 = dba->InsertVertex(); auto va1 = dba.InsertVertex();
auto va2 = dba->InsertVertex(); auto va2 = dba.InsertVertex();
auto va3 = dba->InsertVertex(); auto va3 = dba.InsertVertex();
dba->InsertEdge(va1, va2, dba->EdgeType("likes")); dba.InsertEdge(va1, va2, dba.EdgeType("likes"));
dba->InsertEdge(va3, va2, dba->EdgeType("hates")); dba.InsertEdge(va3, va2, dba.EdgeType("hates"));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(Count(dba->Edges(false)), 2); EXPECT_EQ(Count(dba.Edges(false)), 2);
EXPECT_EQ(Count(dba->Edges(true)), 2); EXPECT_EQ(Count(dba.Edges(true)), 2);
// remove all [:hates] edges // remove all [:hates] edges
for (auto edge : dba->Edges(false)) for (auto edge : dba.Edges(false))
if (edge.EdgeType() == dba->EdgeType("hates")) dba->RemoveEdge(edge); if (edge.EdgeType() == dba.EdgeType("hates")) dba.RemoveEdge(edge);
EXPECT_EQ(Count(dba->Edges(false)), 2); EXPECT_EQ(Count(dba.Edges(false)), 2);
EXPECT_EQ(Count(dba->Edges(true)), 1); EXPECT_EQ(Count(dba.Edges(true)), 1);
// current state: (v1) - [:likes] -> (v2), (v3) // current state: (v1) - [:likes] -> (v2), (v3)
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(Count(dba->Edges(false)), 1); EXPECT_EQ(Count(dba.Edges(false)), 1);
EXPECT_EQ(Count(dba->Edges(true)), 1); EXPECT_EQ(Count(dba.Edges(true)), 1);
EXPECT_EQ(Count(dba->Vertices(false)), 3); EXPECT_EQ(Count(dba.Vertices(false)), 3);
EXPECT_EQ(Count(dba->Vertices(true)), 3); EXPECT_EQ(Count(dba.Vertices(true)), 3);
for (auto edge : dba->Edges(false)) { for (auto edge : dba.Edges(false)) {
EXPECT_EQ(edge.EdgeType(), dba->EdgeType("likes")); EXPECT_EQ(edge.EdgeType(), dba.EdgeType("likes"));
auto v1 = edge.from(); auto v1 = edge.from();
auto v2 = edge.to(); auto v2 = edge.to();
// ensure correct connectivity for all the vertices // ensure correct connectivity for all the vertices
for (auto vertex : dba->Vertices(false)) { for (auto vertex : dba.Vertices(false)) {
if (vertex == v1) { if (vertex == v1) {
EXPECT_EQ(vertex.in_degree(), 0); EXPECT_EQ(vertex.in_degree(), 0);
EXPECT_EQ(vertex.out_degree(), 1); EXPECT_EQ(vertex.out_degree(), 1);
@ -212,69 +212,69 @@ TEST(GraphDbAccessorTest, DetachRemoveVertex) {
// setup (v0)- []->(v1)<-[]-(v2)<-[]-(v3) // setup (v0)- []->(v1)<-[]-(v2)<-[]-(v3)
std::vector<VertexAccessor> vertices; std::vector<VertexAccessor> vertices;
for (int i = 0; i < 4; ++i) vertices.emplace_back(dba->InsertVertex()); for (int i = 0; i < 4; ++i) vertices.emplace_back(dba.InsertVertex());
auto edge_type = dba->EdgeType("type"); auto edge_type = dba.EdgeType("type");
dba->InsertEdge(vertices[0], vertices[1], edge_type); dba.InsertEdge(vertices[0], vertices[1], edge_type);
dba->InsertEdge(vertices[2], vertices[1], edge_type); dba.InsertEdge(vertices[2], vertices[1], edge_type);
dba->InsertEdge(vertices[3], vertices[2], edge_type); dba.InsertEdge(vertices[3], vertices[2], edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
// ensure that plain remove does NOT work // ensure that plain remove does NOT work
EXPECT_EQ(Count(dba->Vertices(false)), 4); EXPECT_EQ(Count(dba.Vertices(false)), 4);
EXPECT_EQ(Count(dba->Edges(false)), 3); EXPECT_EQ(Count(dba.Edges(false)), 3);
EXPECT_FALSE(dba->RemoveVertex(vertices[0])); EXPECT_FALSE(dba.RemoveVertex(vertices[0]));
EXPECT_FALSE(dba->RemoveVertex(vertices[1])); EXPECT_FALSE(dba.RemoveVertex(vertices[1]));
EXPECT_FALSE(dba->RemoveVertex(vertices[2])); EXPECT_FALSE(dba.RemoveVertex(vertices[2]));
EXPECT_EQ(Count(dba->Vertices(false)), 4); EXPECT_EQ(Count(dba.Vertices(false)), 4);
EXPECT_EQ(Count(dba->Edges(false)), 3); EXPECT_EQ(Count(dba.Edges(false)), 3);
dba->DetachRemoveVertex(vertices[2]); dba.DetachRemoveVertex(vertices[2]);
EXPECT_EQ(Count(dba->Vertices(false)), 4); EXPECT_EQ(Count(dba.Vertices(false)), 4);
EXPECT_EQ(Count(dba->Vertices(true)), 3); EXPECT_EQ(Count(dba.Vertices(true)), 3);
EXPECT_EQ(Count(dba->Edges(false)), 3); EXPECT_EQ(Count(dba.Edges(false)), 3);
EXPECT_EQ(Count(dba->Edges(true)), 1); EXPECT_EQ(Count(dba.Edges(true)), 1);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), 3); EXPECT_EQ(Count(dba.Vertices(false)), 3);
EXPECT_EQ(Count(dba->Edges(false)), 1); EXPECT_EQ(Count(dba.Edges(false)), 1);
EXPECT_TRUE(dba->RemoveVertex(vertices[3])); EXPECT_TRUE(dba.RemoveVertex(vertices[3]));
EXPECT_EQ(Count(dba->Vertices(true)), 2); EXPECT_EQ(Count(dba.Vertices(true)), 2);
EXPECT_EQ(Count(dba->Vertices(false)), 3); EXPECT_EQ(Count(dba.Vertices(false)), 3);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), 2); EXPECT_EQ(Count(dba.Vertices(false)), 2);
EXPECT_EQ(Count(dba->Edges(false)), 1); EXPECT_EQ(Count(dba.Edges(false)), 1);
for (auto va : dba->Vertices(false)) EXPECT_FALSE(dba->RemoveVertex(va)); for (auto va : dba.Vertices(false)) EXPECT_FALSE(dba.RemoveVertex(va));
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), 2); EXPECT_EQ(Count(dba.Vertices(false)), 2);
EXPECT_EQ(Count(dba->Edges(false)), 1); EXPECT_EQ(Count(dba.Edges(false)), 1);
for (auto va : dba->Vertices(false)) { for (auto va : dba.Vertices(false)) {
EXPECT_FALSE(dba->RemoveVertex(va)); EXPECT_FALSE(dba.RemoveVertex(va));
dba->DetachRemoveVertex(va); dba.DetachRemoveVertex(va);
break; break;
} }
EXPECT_EQ(Count(dba->Vertices(true)), 1); EXPECT_EQ(Count(dba.Vertices(true)), 1);
EXPECT_EQ(Count(dba->Vertices(false)), 2); EXPECT_EQ(Count(dba.Vertices(false)), 2);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), 1); EXPECT_EQ(Count(dba.Vertices(false)), 1);
EXPECT_EQ(Count(dba->Edges(false)), 0); EXPECT_EQ(Count(dba.Edges(false)), 0);
// remove the last vertex, it has no connections // remove the last vertex, it has no connections
// so that should work // so that should work
for (auto va : dba->Vertices(false)) EXPECT_TRUE(dba->RemoveVertex(va)); for (auto va : dba.Vertices(false)) EXPECT_TRUE(dba.RemoveVertex(va));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(Count(dba->Vertices(false)), 0); EXPECT_EQ(Count(dba.Vertices(false)), 0);
EXPECT_EQ(Count(dba->Edges(false)), 0); EXPECT_EQ(Count(dba.Edges(false)), 0);
} }
TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) { TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) {
@ -288,107 +288,107 @@ TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) {
// with cycles too! // with cycles too!
int N = 7; int N = 7;
std::vector<VertexAccessor> vertices; std::vector<VertexAccessor> vertices;
auto edge_type = dba->EdgeType("edge"); auto edge_type = dba.EdgeType("edge");
for (int i = 0; i < N; ++i) vertices.emplace_back(dba->InsertVertex()); for (int i = 0; i < N; ++i) vertices.emplace_back(dba.InsertVertex());
for (int j = 0; j < N; ++j) for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k) for (int k = 0; k < N; ++k)
dba->InsertEdge(vertices[j], vertices[k], edge_type); dba.InsertEdge(vertices[j], vertices[k], edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), N); EXPECT_EQ(Count(dba.Vertices(false)), N);
EXPECT_EQ(Count(dba->Edges(false)), N * N); EXPECT_EQ(Count(dba.Edges(false)), N * N);
// detach delete one edge // detach delete one edge
dba->DetachRemoveVertex(vertices[0]); dba.DetachRemoveVertex(vertices[0]);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), N - 1); EXPECT_EQ(Count(dba.Vertices(false)), N - 1);
EXPECT_EQ(Count(dba->Edges(false)), (N - 1) * (N - 1)); EXPECT_EQ(Count(dba.Edges(false)), (N - 1) * (N - 1));
// detach delete two neighboring edges // detach delete two neighboring edges
dba->DetachRemoveVertex(vertices[1]); dba.DetachRemoveVertex(vertices[1]);
dba->DetachRemoveVertex(vertices[2]); dba.DetachRemoveVertex(vertices[2]);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), N - 3); EXPECT_EQ(Count(dba.Vertices(false)), N - 3);
EXPECT_EQ(Count(dba->Edges(false)), (N - 3) * (N - 3)); EXPECT_EQ(Count(dba.Edges(false)), (N - 3) * (N - 3));
// detach delete everything, buwahahahaha // detach delete everything, buwahahahaha
for (int l = 3; l < N; ++l) dba->DetachRemoveVertex(vertices[l]); for (int l = 3; l < N; ++l) dba.DetachRemoveVertex(vertices[l]);
dba->AdvanceCommand(); dba.AdvanceCommand();
for (auto &vertex : vertices) vertex.Reconstruct(); for (auto &vertex : vertices) vertex.Reconstruct();
EXPECT_EQ(Count(dba->Vertices(false)), 0); EXPECT_EQ(Count(dba.Vertices(false)), 0);
EXPECT_EQ(Count(dba->Edges(false)), 0); EXPECT_EQ(Count(dba.Edges(false)), 0);
} }
TEST(GraphDbAccessorTest, Labels) { TEST(GraphDbAccessorTest, Labels) {
GraphDb db; GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
Label label_friend = dba->Label("friend"); Label label_friend = dba.Label("friend");
EXPECT_EQ(label_friend, dba->Label("friend")); EXPECT_EQ(label_friend, dba.Label("friend"));
EXPECT_NE(label_friend, dba->Label("friend2")); EXPECT_NE(label_friend, dba.Label("friend2"));
EXPECT_EQ(dba->LabelName(label_friend), "friend"); EXPECT_EQ(dba.LabelName(label_friend), "friend");
// test that getting labels through a different accessor works // test that getting labels through a different accessor works
EXPECT_EQ(label_friend, db.Access()->Label("friend")); EXPECT_EQ(label_friend, db.Access().Label("friend"));
EXPECT_NE(label_friend, db.Access()->Label("friend2")); EXPECT_NE(label_friend, db.Access().Label("friend2"));
} }
TEST(GraphDbAccessorTest, EdgeTypes) { TEST(GraphDbAccessorTest, EdgeTypes) {
GraphDb db; GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
EdgeType edge_type = dba->EdgeType("likes"); EdgeType edge_type = dba.EdgeType("likes");
EXPECT_EQ(edge_type, dba->EdgeType("likes")); EXPECT_EQ(edge_type, dba.EdgeType("likes"));
EXPECT_NE(edge_type, dba->EdgeType("hates")); EXPECT_NE(edge_type, dba.EdgeType("hates"));
EXPECT_EQ(dba->EdgeTypeName(edge_type), "likes"); EXPECT_EQ(dba.EdgeTypeName(edge_type), "likes");
// test that getting labels through a different accessor works // test that getting labels through a different accessor works
EXPECT_EQ(edge_type, db.Access()->EdgeType("likes")); EXPECT_EQ(edge_type, db.Access().EdgeType("likes"));
EXPECT_NE(edge_type, db.Access()->EdgeType("hates")); EXPECT_NE(edge_type, db.Access().EdgeType("hates"));
} }
TEST(GraphDbAccessorTest, Properties) { TEST(GraphDbAccessorTest, Properties) {
GraphDb db; GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
Property prop = dba->Property("name"); Property prop = dba.Property("name");
EXPECT_EQ(prop, dba->Property("name")); EXPECT_EQ(prop, dba.Property("name"));
EXPECT_NE(prop, dba->Property("surname")); EXPECT_NE(prop, dba.Property("surname"));
EXPECT_EQ(dba->PropertyName(prop), "name"); EXPECT_EQ(dba.PropertyName(prop), "name");
// test that getting labels through a different accessor works // test that getting labels through a different accessor works
EXPECT_EQ(prop, db.Access()->Property("name")); EXPECT_EQ(prop, db.Access().Property("name"));
EXPECT_NE(prop, db.Access()->Property("surname")); EXPECT_NE(prop, db.Access().Property("surname"));
} }
TEST(GraphDbAccessorTest, Transfer) { TEST(GraphDbAccessorTest, Transfer) {
GraphDb db; GraphDb db;
auto dba1 = db.Access(); auto dba1 = db.Access();
auto prop = dba1->Property("property"); auto prop = dba1.Property("property");
VertexAccessor v1 = dba1->InsertVertex(); VertexAccessor v1 = dba1.InsertVertex();
v1.PropsSet(prop, 1); v1.PropsSet(prop, 1);
VertexAccessor v2 = dba1->InsertVertex(); VertexAccessor v2 = dba1.InsertVertex();
v2.PropsSet(prop, 2); v2.PropsSet(prop, 2);
EdgeAccessor e12 = dba1->InsertEdge(v1, v2, dba1->EdgeType("et")); EdgeAccessor e12 = dba1.InsertEdge(v1, v2, dba1.EdgeType("et"));
e12.PropsSet(prop, 12); e12.PropsSet(prop, 12);
// make dba2 that has dba1 in it's snapshot, so data isn't visible // make dba2 that has dba1 in it's snapshot, so data isn't visible
auto dba2 = db.Access(); auto dba2 = db.Access();
EXPECT_EQ(dba2->Transfer(v1), std::experimental::nullopt); EXPECT_EQ(dba2.Transfer(v1), std::experimental::nullopt);
EXPECT_EQ(dba2->Transfer(e12), std::experimental::nullopt); EXPECT_EQ(dba2.Transfer(e12), std::experimental::nullopt);
// make dba3 that does not have dba1 in it's snapshot // make dba3 that does not have dba1 in it's snapshot
dba1->Commit(); dba1.Commit();
auto dba3 = db.Access(); auto dba3 = db.Access();
// we can transfer accessors even though the GraphDbAccessor they // we can transfer accessors even though the GraphDbAccessor they
// belong to is not alive anymore // belong to is not alive anymore
EXPECT_EQ(dba3->Transfer(v1)->PropsAt(prop).Value<int64_t>(), 1); EXPECT_EQ(dba3.Transfer(v1)->PropsAt(prop).Value<int64_t>(), 1);
EXPECT_EQ(dba3->Transfer(e12)->PropsAt(prop).Value<int64_t>(), 12); EXPECT_EQ(dba3.Transfer(e12)->PropsAt(prop).Value<int64_t>(), 12);
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {

View File

@ -24,19 +24,19 @@ auto Count(TIterable iterable) {
class GraphDbAccessorIndex : public testing::Test { class GraphDbAccessorIndex : public testing::Test {
protected: protected:
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()}; database::GraphDbAccessor dba{db.Access()};
storage::Property property = dba->Property("property"); storage::Property property = dba.Property("property");
storage::Label label = dba->Label("label"); storage::Label label = dba.Label("label");
storage::EdgeType edge_type = dba->EdgeType("edge_type"); storage::EdgeType edge_type = dba.EdgeType("edge_type");
auto AddVertex() { auto AddVertex() {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
return vertex; return vertex;
} }
auto AddVertex(int property_value) { auto AddVertex(int property_value) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
vertex.PropsSet(property, property_value); vertex.PropsSet(property, property_value);
return vertex; return vertex;
@ -44,106 +44,106 @@ class GraphDbAccessorIndex : public testing::Test {
// commits the current dba, and replaces it with a new one // commits the current dba, and replaces it with a new one
void Commit() { void Commit() {
dba->Commit(); dba.Commit();
dba = db.Access(); dba = db.Access();
} }
}; };
TEST_F(GraphDbAccessorIndex, LabelIndexCount) { TEST_F(GraphDbAccessorIndex, LabelIndexCount) {
auto label2 = dba->Label("label2"); auto label2 = dba.Label("label2");
EXPECT_EQ(dba->VerticesCount(label), 0); EXPECT_EQ(dba.VerticesCount(label), 0);
EXPECT_EQ(dba->VerticesCount(label2), 0); EXPECT_EQ(dba.VerticesCount(label2), 0);
EXPECT_EQ(dba->VerticesCount(), 0); EXPECT_EQ(dba.VerticesCount(), 0);
for (int i = 0; i < 11; ++i) dba->InsertVertex().add_label(label); for (int i = 0; i < 11; ++i) dba.InsertVertex().add_label(label);
for (int i = 0; i < 17; ++i) dba->InsertVertex().add_label(label2); for (int i = 0; i < 17; ++i) dba.InsertVertex().add_label(label2);
// even though xxx_count functions in database::GraphDbAccessor can // even though xxx_count functions in database::GraphDbAccessor can
// over-estaimate in this situation they should be exact (nothing was ever // over-estaimate in this situation they should be exact (nothing was ever
// deleted) // deleted)
EXPECT_EQ(dba->VerticesCount(label), 11); EXPECT_EQ(dba.VerticesCount(label), 11);
EXPECT_EQ(dba->VerticesCount(label2), 17); EXPECT_EQ(dba.VerticesCount(label2), 17);
EXPECT_EQ(dba->VerticesCount(), 28); EXPECT_EQ(dba.VerticesCount(), 28);
} }
TEST_F(GraphDbAccessorIndex, LabelIndexIteration) { TEST_F(GraphDbAccessorIndex, LabelIndexIteration) {
// add 10 vertices, check visibility // add 10 vertices, check visibility
for (int i = 0; i < 10; i++) AddVertex(); for (int i = 0; i < 10; i++) AddVertex();
EXPECT_EQ(Count(dba->Vertices(label, false)), 0); EXPECT_EQ(Count(dba.Vertices(label, false)), 0);
EXPECT_EQ(Count(dba->Vertices(label, true)), 10); EXPECT_EQ(Count(dba.Vertices(label, true)), 10);
Commit(); Commit();
EXPECT_EQ(Count(dba->Vertices(label, false)), 10); EXPECT_EQ(Count(dba.Vertices(label, false)), 10);
EXPECT_EQ(Count(dba->Vertices(label, true)), 10); EXPECT_EQ(Count(dba.Vertices(label, true)), 10);
// remove 3 vertices, check visibility // remove 3 vertices, check visibility
int deleted = 0; int deleted = 0;
for (auto vertex : dba->Vertices(false)) { for (auto vertex : dba.Vertices(false)) {
dba->RemoveVertex(vertex); dba.RemoveVertex(vertex);
if (++deleted >= 3) break; if (++deleted >= 3) break;
} }
EXPECT_EQ(Count(dba->Vertices(label, false)), 10); EXPECT_EQ(Count(dba.Vertices(label, false)), 10);
EXPECT_EQ(Count(dba->Vertices(label, true)), 7); EXPECT_EQ(Count(dba.Vertices(label, true)), 7);
Commit(); Commit();
EXPECT_EQ(Count(dba->Vertices(label, false)), 7); EXPECT_EQ(Count(dba.Vertices(label, false)), 7);
EXPECT_EQ(Count(dba->Vertices(label, true)), 7); EXPECT_EQ(Count(dba.Vertices(label, true)), 7);
} }
TEST_F(GraphDbAccessorIndex, EdgesCount) { TEST_F(GraphDbAccessorIndex, EdgesCount) {
auto edge_type2 = dba->EdgeType("edge_type2"); auto edge_type2 = dba.EdgeType("edge_type2");
EXPECT_EQ(dba->EdgesCount(), 0); EXPECT_EQ(dba.EdgesCount(), 0);
auto v1 = AddVertex(); auto v1 = AddVertex();
auto v2 = AddVertex(); auto v2 = AddVertex();
for (int i = 0; i < 11; ++i) dba->InsertEdge(v1, v2, edge_type); for (int i = 0; i < 11; ++i) dba.InsertEdge(v1, v2, edge_type);
for (int i = 0; i < 17; ++i) dba->InsertEdge(v1, v2, edge_type2); for (int i = 0; i < 17; ++i) dba.InsertEdge(v1, v2, edge_type2);
// even though xxx_count functions in database::GraphDbAccessor can // even though xxx_count functions in database::GraphDbAccessor can
// over-estaimate in this situation they should be exact (nothing was ever // over-estaimate in this situation they should be exact (nothing was ever
// deleted) // deleted)
EXPECT_EQ(dba->EdgesCount(), 28); EXPECT_EQ(dba.EdgesCount(), 28);
} }
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuild) { TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuild) {
AddVertex(0); AddVertex(0);
Commit(); Commit();
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
Commit(); Commit();
EXPECT_EQ(dba->VerticesCount(label, property), 1); EXPECT_EQ(dba.VerticesCount(label, property), 1);
// confirm there is a differentiation of indexes based on (label, property) // confirm there is a differentiation of indexes based on (label, property)
auto label2 = dba->Label("label2"); auto label2 = dba.Label("label2");
auto property2 = dba->Property("property2"); auto property2 = dba.Property("property2");
dba->BuildIndex(label2, property, false); dba.BuildIndex(label2, property, false);
dba->BuildIndex(label, property2, false); dba.BuildIndex(label, property2, false);
Commit(); Commit();
EXPECT_EQ(dba->VerticesCount(label, property), 1); EXPECT_EQ(dba.VerticesCount(label, property), 1);
EXPECT_EQ(dba->VerticesCount(label2, property), 0); EXPECT_EQ(dba.VerticesCount(label2, property), 0);
EXPECT_EQ(dba->VerticesCount(label, property2), 0); EXPECT_EQ(dba.VerticesCount(label, property2), 0);
} }
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexDelete) { TEST_F(GraphDbAccessorIndex, LabelPropertyIndexDelete) {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
Commit(); Commit();
EXPECT_TRUE(dba->LabelPropertyIndexExists(label, property)); EXPECT_TRUE(dba.LabelPropertyIndexExists(label, property));
dba->DeleteIndex(label, property); dba.DeleteIndex(label, property);
Commit(); Commit();
EXPECT_FALSE(dba->LabelPropertyIndexExists(label, property)); EXPECT_FALSE(dba.LabelPropertyIndexExists(label, property));
} }
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuildTwice) { TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuildTwice) {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
EXPECT_THROW(dba->BuildIndex(label, property, false), utils::BasicException); EXPECT_THROW(dba.BuildIndex(label, property, false), utils::BasicException);
} }
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexCount) { TEST_F(GraphDbAccessorIndex, LabelPropertyIndexCount) {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
EXPECT_EQ(dba->VerticesCount(label, property), 0); EXPECT_EQ(dba.VerticesCount(label, property), 0);
EXPECT_EQ(Count(dba->Vertices(label, property, true)), 0); EXPECT_EQ(Count(dba.Vertices(label, property, true)), 0);
for (int i = 0; i < 14; ++i) AddVertex(0); for (int i = 0; i < 14; ++i) AddVertex(0);
EXPECT_EQ(dba->VerticesCount(label, property), 14); EXPECT_EQ(dba.VerticesCount(label, property), 14);
EXPECT_EQ(Count(dba->Vertices(label, property, true)), 14); EXPECT_EQ(Count(dba.Vertices(label, property, true)), 14);
} }
TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) { TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
@ -158,8 +158,8 @@ TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
auto dba = db.Access(); auto dba = db.Access();
try { try {
// This could either pass or throw. // This could either pass or throw.
dba->BuildIndex(dba->Label("l" + std::to_string(index)), dba.BuildIndex(dba.Label("l" + std::to_string(index)),
dba->Property("p" + std::to_string(index)), false); dba.Property("p" + std::to_string(index)), false);
// If it throws, make sure the exception is right. // If it throws, make sure the exception is right.
} catch (const database::IndexTransactionException &e) { } catch (const database::IndexTransactionException &e) {
// Nothing to see here, move along. // Nothing to see here, move along.
@ -186,7 +186,7 @@ TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
x, testing::AllOf(testing::Ge(center - 2), testing::Le(center + 2))); x, testing::AllOf(testing::Ge(center - 2), testing::Le(center + 2)));
TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) { TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
// add some vertices without the property // add some vertices without the property
for (int i = 0; i < 20; i++) AddVertex(); for (int i = 0; i < 20; i++) AddVertex();
@ -197,11 +197,11 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
for (int i = 0; i < 1000; i++) AddVertex(30 + i / 100); for (int i = 0; i < 1000; i++) AddVertex(30 + i / 100);
// test estimates for exact value count // test estimates for exact value count
EXPECT_WITH_MARGIN(dba->VerticesCount(label, property, 10), 10); EXPECT_WITH_MARGIN(dba.VerticesCount(label, property, 10), 10);
EXPECT_WITH_MARGIN(dba->VerticesCount(label, property, 14), 10); EXPECT_WITH_MARGIN(dba.VerticesCount(label, property, 14), 10);
EXPECT_WITH_MARGIN(dba->VerticesCount(label, property, 30), 100); EXPECT_WITH_MARGIN(dba.VerticesCount(label, property, 30), 100);
EXPECT_WITH_MARGIN(dba->VerticesCount(label, property, 39), 100); EXPECT_WITH_MARGIN(dba.VerticesCount(label, property, 39), 100);
EXPECT_EQ(dba->VerticesCount(label, property, 40), 0); EXPECT_EQ(dba.VerticesCount(label, property, 40), 0);
// helper functions // helper functions
auto Inclusive = [](int64_t value) { auto Inclusive = [](int64_t value) {
@ -213,7 +213,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
utils::MakeBoundExclusive(PropertyValue(value))); utils::MakeBoundExclusive(PropertyValue(value)));
}; };
auto VerticesCount = [this](auto lower, auto upper) { auto VerticesCount = [this](auto lower, auto upper) {
return dba->VerticesCount(label, property, lower, upper); return dba.VerticesCount(label, property, lower, upper);
}; };
using std::experimental::nullopt; using std::experimental::nullopt;
@ -232,27 +232,27 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
#undef EXPECT_WITH_MARGIN #undef EXPECT_WITH_MARGIN
TEST_F(GraphDbAccessorIndex, LabelPropertyValueIteration) { TEST_F(GraphDbAccessorIndex, LabelPropertyValueIteration) {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
Commit(); Commit();
// insert 10 verties and and check visibility // insert 10 verties and and check visibility
for (int i = 0; i < 10; i++) AddVertex(12); for (int i = 0; i < 10; i++) AddVertex(12);
EXPECT_EQ(Count(dba->Vertices(label, property, 12, false)), 0); EXPECT_EQ(Count(dba.Vertices(label, property, 12, false)), 0);
EXPECT_EQ(Count(dba->Vertices(label, property, 12, true)), 10); EXPECT_EQ(Count(dba.Vertices(label, property, 12, true)), 10);
Commit(); Commit();
EXPECT_EQ(Count(dba->Vertices(label, property, 12, false)), 10); EXPECT_EQ(Count(dba.Vertices(label, property, 12, false)), 10);
EXPECT_EQ(Count(dba->Vertices(label, property, 12, true)), 10); EXPECT_EQ(Count(dba.Vertices(label, property, 12, true)), 10);
} }
TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) { TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
Commit(); Commit();
std::vector<PropertyValue> expected_property_value(50, 0); std::vector<PropertyValue> expected_property_value(50, 0);
// strings // strings
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, vertex_accessor.PropsSet(property,
static_cast<std::string>(std::to_string(i))); static_cast<std::string>(std::to_string(i)));
@ -260,7 +260,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
} }
// bools - insert in reverse to check for comparison between values. // bools - insert in reverse to check for comparison between values.
for (int i = 9; i >= 0; --i) { for (int i = 9; i >= 0; --i) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, static_cast<bool>(i / 5)); vertex_accessor.PropsSet(property, static_cast<bool>(i / 5));
expected_property_value[10 + i] = vertex_accessor.PropsAt(property); expected_property_value[10 + i] = vertex_accessor.PropsAt(property);
@ -268,14 +268,14 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
// integers // integers
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, i); vertex_accessor.PropsSet(property, i);
expected_property_value[20 + 2 * i] = vertex_accessor.PropsAt(property); expected_property_value[20 + 2 * i] = vertex_accessor.PropsAt(property);
} }
// doubles // doubles
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, static_cast<double>(i + 0.5)); vertex_accessor.PropsSet(property, static_cast<double>(i + 0.5));
expected_property_value[20 + 2 * i + 1] = vertex_accessor.PropsAt(property); expected_property_value[20 + 2 * i + 1] = vertex_accessor.PropsAt(property);
@ -284,7 +284,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
// lists of ints - insert in reverse to check for comparision between // lists of ints - insert in reverse to check for comparision between
// lists. // lists.
for (int i = 9; i >= 0; --i) { for (int i = 9; i >= 0; --i) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
std::vector<PropertyValue> value; std::vector<PropertyValue> value;
value.push_back(PropertyValue(i)); value.push_back(PropertyValue(i));
@ -304,16 +304,16 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
auto shuffled = maps; auto shuffled = maps;
std::random_shuffle(shuffled.begin(), shuffled.end()); std::random_shuffle(shuffled.begin(), shuffled.end());
for (const auto &map : shuffled) { for (const auto &map : shuffled) {
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, map); vertex_accessor.PropsSet(property, map);
} }
EXPECT_EQ(Count(dba->Vertices(label, property, false)), 0); EXPECT_EQ(Count(dba.Vertices(label, property, false)), 0);
EXPECT_EQ(Count(dba->Vertices(label, property, true)), 54); EXPECT_EQ(Count(dba.Vertices(label, property, true)), 54);
int cnt = 0; int cnt = 0;
for (auto vertex : dba->Vertices(label, property, true)) { for (auto vertex : dba.Vertices(label, property, true)) {
const PropertyValue &property_value = vertex.PropsAt(property); const PropertyValue &property_value = vertex.PropsAt(property);
EXPECT_EQ(property_value.type(), expected_property_value[cnt].type()); EXPECT_EQ(property_value.type(), expected_property_value[cnt].type());
switch (property_value.type()) { switch (property_value.type()) {
@ -373,19 +373,19 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
class GraphDbAccessorIndexRange : public GraphDbAccessorIndex { class GraphDbAccessorIndexRange : public GraphDbAccessorIndex {
protected: protected:
void SetUp() override { void SetUp() override {
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
for (int i = 0; i < 100; i++) AddVertex(i / 10); for (int i = 0; i < 100; i++) AddVertex(i / 10);
ASSERT_EQ(Count(dba->Vertices(false)), 0); ASSERT_EQ(Count(dba.Vertices(false)), 0);
ASSERT_EQ(Count(dba->Vertices(true)), 100); ASSERT_EQ(Count(dba.Vertices(true)), 100);
Commit(); Commit();
ASSERT_EQ(Count(dba->Vertices(false)), 100); ASSERT_EQ(Count(dba.Vertices(false)), 100);
} }
auto Vertices(std::experimental::optional<utils::Bound<PropertyValue>> lower, auto Vertices(std::experimental::optional<utils::Bound<PropertyValue>> lower,
std::experimental::optional<utils::Bound<PropertyValue>> upper, std::experimental::optional<utils::Bound<PropertyValue>> upper,
bool current_state = false) { bool current_state = false) {
return dba->Vertices(label, property, lower, upper, current_state); return dba.Vertices(label, property, lower, upper, current_state);
} }
auto Inclusive(PropertyValue value) { auto Inclusive(PropertyValue value) {
@ -456,7 +456,7 @@ TEST_F(GraphDbAccessorIndexRange, RangeInterationIncompatibleTypes) {
} }
TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnInsert) { TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnInsert) {
dba->BuildIndex(label, property, true); dba.BuildIndex(label, property, true);
Commit(); Commit();
AddVertex(0); AddVertex(0);
EXPECT_THROW(AddVertex(0), database::IndexConstraintViolationException); EXPECT_THROW(AddVertex(0), database::IndexConstraintViolationException);
@ -466,14 +466,14 @@ TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnBuild) {
AddVertex(0); AddVertex(0);
AddVertex(0); AddVertex(0);
Commit(); Commit();
EXPECT_THROW(dba->BuildIndex(label, property, true), EXPECT_THROW(dba.BuildIndex(label, property, true),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
TEST_F(GraphDbAccessorIndex, UniqueConstraintUpdateProperty) { TEST_F(GraphDbAccessorIndex, UniqueConstraintUpdateProperty) {
dba->BuildIndex(label, property, true); dba.BuildIndex(label, property, true);
AddVertex(0); AddVertex(0);
auto vertex_accessor = dba->InsertVertex(); auto vertex_accessor = dba.InsertVertex();
vertex_accessor.add_label(label); vertex_accessor.add_label(label);
vertex_accessor.PropsSet(property, 10); vertex_accessor.PropsSet(property, 10);

View File

@ -21,7 +21,7 @@ class InterpreterTest : public ::testing::Test {
const std::map<std::string, PropertyValue> &params = {}) { const std::map<std::string, PropertyValue> &params = {}) {
auto dba = db_.Access(); auto dba = db_.Access();
ResultStreamFaker<query::TypedValue> stream; ResultStreamFaker<query::TypedValue> stream;
auto results = interpreter_(query, *dba, params, false); auto results = interpreter_(query, dba, params, false);
stream.Header(results.header()); stream.Header(results.header());
results.PullAll(stream); results.PullAll(stream);
stream.Summary(results.summary()); stream.Summary(results.summary());
@ -148,17 +148,17 @@ TEST_F(InterpreterTest, Bfs) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto add_node = [&](int level, bool reachable) { auto add_node = [&](int level, bool reachable) {
auto node = dba->InsertVertex(); auto node = dba.InsertVertex();
node.PropsSet(dba->Property(kId), id++); node.PropsSet(dba.Property(kId), id++);
node.PropsSet(dba->Property(kReachable), reachable); node.PropsSet(dba.Property(kReachable), reachable);
levels[level].push_back(node); levels[level].push_back(node);
return node; return node;
}; };
auto add_edge = [&](VertexAccessor &v1, VertexAccessor &v2, auto add_edge = [&](VertexAccessor &v1, VertexAccessor &v2,
bool reachable) { bool reachable) {
auto edge = dba->InsertEdge(v1, v2, dba->EdgeType("edge")); auto edge = dba.InsertEdge(v1, v2, dba.EdgeType("edge"));
edge.PropsSet(dba->Property(kReachable), reachable); edge.PropsSet(dba.Property(kReachable), reachable);
}; };
// Add source node. // Add source node.
@ -196,7 +196,7 @@ TEST_F(InterpreterTest, Bfs) {
add_edge(node1, node2, false); add_edge(node1, node2, false);
} }
dba->Commit(); dba.Commit();
} }
auto dba = db_.Access(); auto dba = db_.Access();
@ -204,7 +204,7 @@ TEST_F(InterpreterTest, Bfs) {
auto results = interpreter_( auto results = interpreter_(
"MATCH (n {id: 0})-[r *bfs..5 (e, n | n.reachable and " "MATCH (n {id: 0})-[r *bfs..5 (e, n | n.reachable and "
"e.reachable)]->(m) RETURN r", "e.reachable)]->(m) RETURN r",
*dba, {}, false); dba, {}, false);
stream.Header(results.header()); stream.Header(results.header());
results.PullAll(stream); results.PullAll(stream);
stream.Summary(results.summary()); stream.Summary(results.summary());
@ -225,14 +225,14 @@ TEST_F(InterpreterTest, Bfs) {
EXPECT_EQ(edges.size(), expected_level); EXPECT_EQ(edges.size(), expected_level);
// Check that starting node is correct. // Check that starting node is correct.
EXPECT_EQ( EXPECT_EQ(
edges[0].from().PropsAt(dba->Property(kId)).template Value<int64_t>(), edges[0].from().PropsAt(dba.Property(kId)).template Value<int64_t>(),
0); 0);
for (int i = 1; i < static_cast<int>(edges.size()); ++i) { for (int i = 1; i < static_cast<int>(edges.size()); ++i) {
// Check that edges form a connected path. // Check that edges form a connected path.
EXPECT_EQ(edges[i - 1].to(), edges[i].from()); EXPECT_EQ(edges[i - 1].to(), edges[i].from());
} }
auto matched_id = auto matched_id =
edges.back().to().PropsAt(dba->Property(kId)).Value<int64_t>(); edges.back().to().PropsAt(dba.Property(kId)).Value<int64_t>();
// Check that we didn't match that node already. // Check that we didn't match that node already.
EXPECT_TRUE(matched_ids.insert(matched_id).second); EXPECT_TRUE(matched_ids.insert(matched_id).second);
// Check that shortest path was found. // Check that shortest path was found.
@ -249,7 +249,7 @@ TEST_F(InterpreterTest, CreateIndexInMulticommandTransaction) {
ResultStreamFaker<query::TypedValue> stream; ResultStreamFaker<query::TypedValue> stream;
auto dba = db_.Access(); auto dba = db_.Access();
ASSERT_THROW( ASSERT_THROW(
interpreter_("CREATE INDEX ON :X(y)", *dba, {}, true).PullAll(stream), interpreter_("CREATE INDEX ON :X(y)", dba, {}, true).PullAll(stream),
query::IndexInMulticommandTxException); query::IndexInMulticommandTxException);
} }
@ -261,17 +261,17 @@ TEST_F(InterpreterTest, ShortestPath) {
interpreter_( interpreter_(
"CREATE (n:A {x: 1}), (m:B {x: 2}), (l:C {x: 1}), (n)-[:r1 {w: 1 " "CREATE (n:A {x: 1}), (m:B {x: 2}), (l:C {x: 1}), (n)-[:r1 {w: 1 "
"}]->(m)-[:r2 {w: 2}]->(l), (n)-[:r3 {w: 4}]->(l)", "}]->(m)-[:r2 {w: 2}]->(l), (n)-[:r3 {w: 4}]->(l)",
*dba, {}, true) dba, {}, true)
.PullAll(stream); .PullAll(stream);
dba->Commit(); dba.Commit();
} }
ResultStreamFaker<query::TypedValue> stream; ResultStreamFaker<query::TypedValue> stream;
auto dba = db_.Access(); auto dba = db_.Access();
auto results = auto results =
interpreter_("MATCH (n)-[e *wshortest 5 (e, n | e.w) ]->(m) return e", interpreter_("MATCH (n)-[e *wshortest 5 (e, n | e.w) ]->(m) return e",
*dba, {}, false); dba, {}, false);
stream.Header(results.header()); stream.Header(results.header());
results.PullAll(stream); results.PullAll(stream);
stream.Summary(results.summary()); stream.Summary(results.summary());
@ -289,7 +289,7 @@ TEST_F(InterpreterTest, ShortestPath) {
std::vector<std::string> datum; std::vector<std::string> datum;
for (const auto &edge : edges) { for (const auto &edge : edges) {
datum.push_back(dba->EdgeTypeName(edge.EdgeType())); datum.push_back(dba.EdgeTypeName(edge.EdgeType()));
} }
bool any_match = false; bool any_match = false;

View File

@ -26,14 +26,13 @@ using namespace nlohmann;
class PrintToJsonTest : public ::testing::Test { class PrintToJsonTest : public ::testing::Test {
protected: protected:
PrintToJsonTest() : db(), dba_ptr(db.Access()), dba(*dba_ptr) {} PrintToJsonTest() : db(), dba(db.Access()) {}
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba_ptr; database::GraphDbAccessor dba;
database::GraphDbAccessor &dba;
Symbol GetSymbol(std::string name) { Symbol GetSymbol(std::string name) {
return symbol_table.CreateSymbol(name, true); return symbol_table.CreateSymbol(name, true);

View File

@ -24,9 +24,9 @@ using MiscParam = CostEstimator<database::GraphDbAccessor>::MiscParam;
class QueryCostEstimator : public ::testing::Test { class QueryCostEstimator : public ::testing::Test {
protected: protected:
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()}; database::GraphDbAccessor dba{db.Access()};
storage::Label label = dba->Label("label"); storage::Label label = dba.Label("label");
storage::Property property = dba->Property("property"); storage::Property property = dba.Property("property");
// we incrementally build the logical operator plan // we incrementally build the logical operator plan
// start it off with Once // start it off with Once
@ -39,7 +39,7 @@ class QueryCostEstimator : public ::testing::Test {
void SetUp() { void SetUp() {
// create the index in the current db accessor and then swap it to a new one // create the index in the current db accessor and then swap it to a new one
dba->BuildIndex(label, property, false); dba.BuildIndex(label, property, false);
dba = db.Access(); dba = db.Access();
} }
@ -53,16 +53,16 @@ class QueryCostEstimator : public ::testing::Test {
void AddVertices(int vertex_count, int labeled_count, void AddVertices(int vertex_count, int labeled_count,
int property_count = 0) { int property_count = 0) {
for (int i = 0; i < vertex_count; i++) { for (int i = 0; i < vertex_count; i++) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
if (i < labeled_count) vertex.add_label(label); if (i < labeled_count) vertex.add_label(label);
if (i < property_count) vertex.PropsSet(property, i); if (i < property_count) vertex.PropsSet(property, i);
} }
dba->AdvanceCommand(); dba.AdvanceCommand();
} }
auto Cost() { auto Cost() {
CostEstimator<database::GraphDbAccessor> cost_estimator(dba.get(), parameters_); CostEstimator<database::GraphDbAccessor> cost_estimator(&dba, parameters_);
last_op_->Accept(cost_estimator); last_op_->Accept(cost_estimator);
return cost_estimator.cost(); return cost_estimator.cost();
} }

View File

@ -30,14 +30,14 @@ namespace {
class ExpressionEvaluatorTest : public ::testing::Test { class ExpressionEvaluatorTest : public ::testing::Test {
protected: protected:
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()}; database::GraphDbAccessor dba{db.Access()};
AstStorage storage; AstStorage storage;
EvaluationContext ctx; EvaluationContext ctx;
SymbolTable symbol_table; SymbolTable symbol_table;
Frame frame{128}; Frame frame{128};
ExpressionEvaluator eval{&frame, symbol_table, ctx, dba.get(), ExpressionEvaluator eval{&frame, symbol_table, ctx, &dba,
GraphView::OLD}; GraphView::OLD};
Identifier *CreateIdentifierWithValue(std::string name, Identifier *CreateIdentifierWithValue(std::string name,
@ -51,8 +51,8 @@ class ExpressionEvaluatorTest : public ::testing::Test {
template <class TExpression> template <class TExpression>
auto Eval(TExpression *expr) { auto Eval(TExpression *expr) {
ctx.properties = NamesToProperties(storage.properties_, dba.get()); ctx.properties = NamesToProperties(storage.properties_, &dba);
ctx.labels = NamesToLabels(storage.labels_, dba.get()); ctx.labels = NamesToLabels(storage.labels_, &dba);
return expr->Accept(eval); return expr->Accept(eval);
} }
}; };
@ -410,10 +410,10 @@ TEST_F(ExpressionEvaluatorTest, MapIndexing) {
} }
TEST_F(ExpressionEvaluatorTest, VertexAndEdgeIndexing) { TEST_F(ExpressionEvaluatorTest, VertexAndEdgeIndexing) {
auto edge_type = dba->EdgeType("edge_type"); auto edge_type = dba.EdgeType("edge_type");
auto prop = dba->Property("prop"); auto prop = dba.Property("prop");
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto e11 = dba->InsertEdge(v1, v1, edge_type); auto e11 = dba.InsertEdge(v1, v1, edge_type);
v1.PropsSet(prop, 42); v1.PropsSet(prop, 42);
e11.PropsSet(prop, 43); e11.PropsSet(prop, 43);
@ -624,10 +624,10 @@ TEST_F(ExpressionEvaluatorTest, IsNullOperator) {
} }
TEST_F(ExpressionEvaluatorTest, LabelsTest) { TEST_F(ExpressionEvaluatorTest, LabelsTest) {
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(dba->Label("ANIMAL")); v1.add_label(dba.Label("ANIMAL"));
v1.add_label(dba->Label("DOG")); v1.add_label(dba.Label("DOG"));
v1.add_label(dba->Label("NICE_DOG")); v1.add_label(dba.Label("NICE_DOG"));
auto *identifier = storage.Create<Identifier>("n"); auto *identifier = storage.Create<Identifier>("n");
auto node_symbol = symbol_table.CreateSymbol("n", true); auto node_symbol = symbol_table.CreateSymbol("n", true);
identifier->MapTo(node_symbol); identifier->MapTo(node_symbol);
@ -893,9 +893,9 @@ TEST_F(ExpressionEvaluatorTest, RegexMatch) {
class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest { class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
protected: protected:
std::pair<std::string, storage::Property> prop_age = std::pair<std::string, storage::Property> prop_age =
std::make_pair("age", dba->Property("age")); std::make_pair("age", dba.Property("age"));
std::pair<std::string, storage::Property> prop_height = std::pair<std::string, storage::Property> prop_height =
std::make_pair("height", dba->Property("height")); std::make_pair("height", dba.Property("height"));
Identifier *identifier = storage.Create<Identifier>("element"); Identifier *identifier = storage.Create<Identifier>("element");
Symbol symbol = symbol_table.CreateSymbol("element", true); Symbol symbol = symbol_table.CreateSymbol("element", true);
@ -909,7 +909,7 @@ class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
}; };
TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) { TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.PropsSet(prop_age.second, 10); v1.PropsSet(prop_age.second, 10);
frame[symbol] = v1; frame[symbol] = v1;
EXPECT_EQ(Value(prop_age).ValueInt(), 10); EXPECT_EQ(Value(prop_age).ValueInt(), 10);
@ -917,9 +917,9 @@ TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
} }
TEST_F(ExpressionEvaluatorPropertyLookup, Edge) { TEST_F(ExpressionEvaluatorPropertyLookup, Edge) {
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("edge_type")); auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("edge_type"));
e12.PropsSet(prop_age.second, 10); e12.PropsSet(prop_age.second, 10);
frame[symbol] = e12; frame[symbol] = e12;
EXPECT_EQ(Value(prop_age).ValueInt(), 10); EXPECT_EQ(Value(prop_age).ValueInt(), 10);
@ -973,14 +973,14 @@ class FunctionTest : public ExpressionEvaluatorTest {
TEST_F(FunctionTest, EndNode) { TEST_F(FunctionTest, EndNode) {
ASSERT_THROW(EvaluateFunction("ENDNODE", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("ENDNODE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("ENDNODE", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("ENDNODE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(dba->Label("label1")); v1.add_label(dba.Label("label1"));
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.add_label(dba->Label("label2")); v2.add_label(dba.Label("label2"));
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("t")); auto e = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
ASSERT_TRUE(EvaluateFunction("ENDNODE", {e}) ASSERT_TRUE(EvaluateFunction("ENDNODE", {e})
.ValueVertex() .ValueVertex()
.has_label(dba->Label("label2"))); .has_label(dba.Label("label2")));
ASSERT_THROW(EvaluateFunction("ENDNODE", {2}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("ENDNODE", {2}), QueryRuntimeException);
} }
@ -998,13 +998,13 @@ TEST_F(FunctionTest, Head) {
TEST_F(FunctionTest, Properties) { TEST_F(FunctionTest, Properties) {
ASSERT_THROW(EvaluateFunction("PROPERTIES", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("PROPERTIES", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("PROPERTIES", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("PROPERTIES", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.PropsSet(dba->Property("height"), 5); v1.PropsSet(dba.Property("height"), 5);
v1.PropsSet(dba->Property("age"), 10); v1.PropsSet(dba.Property("age"), 10);
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("type1")); auto e = dba.InsertEdge(v1, v2, dba.EdgeType("type1"));
e.PropsSet(dba->Property("height"), 3); e.PropsSet(dba.Property("height"), 3);
e.PropsSet(dba->Property("age"), 15); e.PropsSet(dba.Property("age"), 15);
auto prop_values_to_int = [](TypedValue t) { auto prop_values_to_int = [](TypedValue t) {
std::unordered_map<std::string, int> properties; std::unordered_map<std::string, int> properties;
@ -1047,11 +1047,11 @@ TEST_F(FunctionTest, Size) {
3); 3);
ASSERT_THROW(EvaluateFunction("SIZE", {5}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("SIZE", {5}), QueryRuntimeException);
auto v0 = dba->InsertVertex(); auto v0 = dba.InsertVertex();
query::Path path(v0); query::Path path(v0);
EXPECT_EQ(EvaluateFunction("SIZE", {path}).ValueInt(), 0); EXPECT_EQ(EvaluateFunction("SIZE", {path}).ValueInt(), 0);
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
path.Expand(dba->InsertEdge(v0, v1, dba->EdgeType("type"))); path.Expand(dba.InsertEdge(v0, v1, dba.EdgeType("type")));
path.Expand(v1); path.Expand(v1);
EXPECT_EQ(EvaluateFunction("SIZE", {path}).ValueInt(), 1); EXPECT_EQ(EvaluateFunction("SIZE", {path}).ValueInt(), 1);
} }
@ -1059,25 +1059,25 @@ TEST_F(FunctionTest, Size) {
TEST_F(FunctionTest, StartNode) { TEST_F(FunctionTest, StartNode) {
ASSERT_THROW(EvaluateFunction("STARTNODE", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("STARTNODE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("STARTNODE", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("STARTNODE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(dba->Label("label1")); v1.add_label(dba.Label("label1"));
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.add_label(dba->Label("label2")); v2.add_label(dba.Label("label2"));
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("t")); auto e = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
ASSERT_TRUE(EvaluateFunction("STARTNODE", {e}) ASSERT_TRUE(EvaluateFunction("STARTNODE", {e})
.ValueVertex() .ValueVertex()
.has_label(dba->Label("label1"))); .has_label(dba.Label("label1")));
ASSERT_THROW(EvaluateFunction("STARTNODE", {2}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("STARTNODE", {2}), QueryRuntimeException);
} }
TEST_F(FunctionTest, Degree) { TEST_F(FunctionTest, Degree) {
ASSERT_THROW(EvaluateFunction("DEGREE", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("DEGREE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("DEGREE", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("DEGREE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t")); auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
dba->InsertEdge(v3, v2, dba->EdgeType("t")); dba.InsertEdge(v3, v2, dba.EdgeType("t"));
ASSERT_EQ(EvaluateFunction("DEGREE", {v1}).ValueInt(), 1); ASSERT_EQ(EvaluateFunction("DEGREE", {v1}).ValueInt(), 1);
ASSERT_EQ(EvaluateFunction("DEGREE", {v2}).ValueInt(), 2); ASSERT_EQ(EvaluateFunction("DEGREE", {v2}).ValueInt(), 2);
ASSERT_EQ(EvaluateFunction("DEGREE", {v3}).ValueInt(), 1); ASSERT_EQ(EvaluateFunction("DEGREE", {v3}).ValueInt(), 1);
@ -1088,11 +1088,11 @@ TEST_F(FunctionTest, Degree) {
TEST_F(FunctionTest, InDegree) { TEST_F(FunctionTest, InDegree) {
ASSERT_THROW(EvaluateFunction("INDEGREE", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("INDEGREE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("INDEGREE", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("INDEGREE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t")); auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
dba->InsertEdge(v3, v2, dba->EdgeType("t")); dba.InsertEdge(v3, v2, dba.EdgeType("t"));
ASSERT_EQ(EvaluateFunction("INDEGREE", {v1}).ValueInt(), 0); ASSERT_EQ(EvaluateFunction("INDEGREE", {v1}).ValueInt(), 0);
ASSERT_EQ(EvaluateFunction("INDEGREE", {v2}).ValueInt(), 2); ASSERT_EQ(EvaluateFunction("INDEGREE", {v2}).ValueInt(), 2);
ASSERT_EQ(EvaluateFunction("INDEGREE", {v3}).ValueInt(), 0); ASSERT_EQ(EvaluateFunction("INDEGREE", {v3}).ValueInt(), 0);
@ -1103,11 +1103,11 @@ TEST_F(FunctionTest, InDegree) {
TEST_F(FunctionTest, OutDegree) { TEST_F(FunctionTest, OutDegree) {
ASSERT_THROW(EvaluateFunction("OUTDEGREE", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("OUTDEGREE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("OUTDEGREE", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("OUTDEGREE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t")); auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
dba->InsertEdge(v3, v2, dba->EdgeType("t")); dba.InsertEdge(v3, v2, dba.EdgeType("t"));
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v1}).ValueInt(), 1); ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v1}).ValueInt(), 1);
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v2}).ValueInt(), 0); ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v2}).ValueInt(), 0);
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v3}).ValueInt(), 1); ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v3}).ValueInt(), 1);
@ -1154,11 +1154,11 @@ TEST_F(FunctionTest, ToInteger) {
TEST_F(FunctionTest, Type) { TEST_F(FunctionTest, Type) {
ASSERT_THROW(EvaluateFunction("TYPE", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("TYPE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("TYPE", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("TYPE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(dba->Label("label1")); v1.add_label(dba.Label("label1"));
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.add_label(dba->Label("label2")); v2.add_label(dba.Label("label2"));
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("type1")); auto e = dba.InsertEdge(v1, v2, dba.EdgeType("type1"));
ASSERT_EQ(EvaluateFunction("TYPE", {e}).ValueString(), "type1"); ASSERT_EQ(EvaluateFunction("TYPE", {e}).ValueString(), "type1");
ASSERT_THROW(EvaluateFunction("TYPE", {2}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("TYPE", {2}), QueryRuntimeException);
} }
@ -1166,9 +1166,9 @@ TEST_F(FunctionTest, Type) {
TEST_F(FunctionTest, Labels) { TEST_F(FunctionTest, Labels) {
ASSERT_THROW(EvaluateFunction("LABELS", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("LABELS", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("LABELS", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("LABELS", {TypedValue::Null}).IsNull());
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(dba->Label("label1")); v.add_label(dba.Label("label1"));
v.add_label(dba->Label("label2")); v.add_label(dba.Label("label2"));
std::vector<std::string> labels; std::vector<std::string> labels;
auto _labels = EvaluateFunction("LABELS", {v}).ValueList(); auto _labels = EvaluateFunction("LABELS", {v}).ValueList();
for (auto label : _labels) { for (auto label : _labels) {
@ -1185,11 +1185,11 @@ TEST_F(FunctionTest, NodesRelationships) {
EXPECT_TRUE(EvaluateFunction("RELATIONSHIPS", {TypedValue::Null}).IsNull()); EXPECT_TRUE(EvaluateFunction("RELATIONSHIPS", {TypedValue::Null}).IsNull());
{ {
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto e1 = dba->InsertEdge(v1, v2, dba->EdgeType("Type")); auto e1 = dba.InsertEdge(v1, v2, dba.EdgeType("Type"));
auto e2 = dba->InsertEdge(v2, v3, dba->EdgeType("Type")); auto e2 = dba.InsertEdge(v2, v3, dba.EdgeType("Type"));
query::Path path(v1, e1, v2, e2, v3); query::Path path(v1, e1, v2, e2, v3);
auto _nodes = EvaluateFunction("NODES", {path}).ValueList(); auto _nodes = EvaluateFunction("NODES", {path}).ValueList();
@ -1240,13 +1240,13 @@ TEST_F(FunctionTest, Range) {
TEST_F(FunctionTest, Keys) { TEST_F(FunctionTest, Keys) {
ASSERT_THROW(EvaluateFunction("KEYS", {}), QueryRuntimeException); ASSERT_THROW(EvaluateFunction("KEYS", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("KEYS", {TypedValue::Null}).IsNull()); ASSERT_TRUE(EvaluateFunction("KEYS", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.PropsSet(dba->Property("height"), 5); v1.PropsSet(dba.Property("height"), 5);
v1.PropsSet(dba->Property("age"), 10); v1.PropsSet(dba.Property("age"), 10);
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("type1")); auto e = dba.InsertEdge(v1, v2, dba.EdgeType("type1"));
e.PropsSet(dba->Property("width"), 3); e.PropsSet(dba.Property("width"), 3);
e.PropsSet(dba->Property("age"), 15); e.PropsSet(dba.Property("age"), 15);
auto prop_keys_to_string = [](TypedValue t) { auto prop_keys_to_string = [](TypedValue t) {
std::vector<std::string> keys; std::vector<std::string> keys;
@ -1482,9 +1482,9 @@ TEST_F(FunctionTest, CounterSet) {
} }
TEST_F(FunctionTest, Id) { TEST_F(FunctionTest, Id) {
auto va = dba->InsertVertex(); auto va = dba.InsertVertex();
auto ea = dba->InsertEdge(va, va, dba->EdgeType("edge")); auto ea = dba.InsertEdge(va, va, dba.EdgeType("edge"));
auto vb = dba->InsertVertex(); auto vb = dba.InsertVertex();
EXPECT_EQ(EvaluateFunction("ID", {va}).ValueInt(), 0); EXPECT_EQ(EvaluateFunction("ID", {va}).ValueInt(), 0);
EXPECT_EQ(EvaluateFunction("ID", {ea}).ValueInt(), 0); EXPECT_EQ(EvaluateFunction("ID", {ea}).ValueInt(), 0);
EXPECT_EQ(EvaluateFunction("ID", {vb}).ValueInt(), 1); EXPECT_EQ(EvaluateFunction("ID", {vb}).ValueInt(), 1);
@ -1495,7 +1495,7 @@ TEST_F(FunctionTest, Id) {
/* TODO: FIXME /* TODO: FIXME
TEST_F(FunctionTest, WorkerIdException) { TEST_F(FunctionTest, WorkerIdException) {
auto va = dba->InsertVertex(); auto va = dba.InsertVertex();
EXPECT_THROW(EvaluateFunction("WORKERID", {}), QueryRuntimeException); EXPECT_THROW(EvaluateFunction("WORKERID", {}), QueryRuntimeException);
EXPECT_THROW(EvaluateFunction("WORKERID", {va, va}), QueryRuntimeException); EXPECT_THROW(EvaluateFunction("WORKERID", {va, va}), QueryRuntimeException);
} }
@ -1503,7 +1503,7 @@ TEST_F(FunctionTest, WorkerIdException) {
/* TODO: FIXME /* TODO: FIXME
TEST_F(FunctionTest, WorkerIdSingleNode) { TEST_F(FunctionTest, WorkerIdSingleNode) {
auto va = dba->InsertVertex(); auto va = dba.InsertVertex();
EXPECT_EQ(EvaluateFunction("WORKERID", {va}).ValueInt(), 0); EXPECT_EQ(EvaluateFunction("WORKERID", {va}).ValueInt(), 0);
} }
*/ */

View File

@ -28,8 +28,7 @@ TEST(QueryPlan, Accumulate) {
auto check = [&](bool accumulate) { auto check = [&](bool accumulate) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto prop = dba.Property("x"); auto prop = dba.Property("x");
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();
@ -96,7 +95,7 @@ TEST(QueryPlan, AccumulateAdvance) {
auto accumulate = std::make_shared<Accumulate>( auto accumulate = std::make_shared<Accumulate>(
create, std::vector<Symbol>{node.symbol}, advance); create, std::vector<Symbol>{node.symbol}, advance);
auto match = MakeScanAll(storage, symbol_table, "m", accumulate); auto match = MakeScanAll(storage, symbol_table, "m", accumulate);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(advance ? 1 : 0, PullAll(*match.op_, &context)); EXPECT_EQ(advance ? 1 : 0, PullAll(*match.op_, &context));
}; };
check(false); check(false);
@ -146,8 +145,7 @@ std::shared_ptr<Produce> MakeAggregationProduce(
class QueryPlanAggregateOps : public ::testing::Test { class QueryPlanAggregateOps : public ::testing::Test {
protected: protected:
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()}; database::GraphDbAccessor dba{db.Access()};
database::GraphDbAccessor &dba{*dba_ptr};
storage::Property prop = dba.Property("prop"); storage::Property prop = dba.Property("prop");
AstStorage storage; AstStorage storage;
@ -286,8 +284,7 @@ TEST(QueryPlan, AggregateGroupByValues) {
// Also test the "remember" part of the Aggregation API as final results are // Also test the "remember" part of the Aggregation API as final results are
// obtained via a property lookup of a remembered node. // obtained via a property lookup of a remembered node.
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// a vector of PropertyValue to be set as property values on vertices // a vector of PropertyValue to be set as property values on vertices
// most of them should result in a distinct group (commented where not) // most of them should result in a distinct group (commented where not)
@ -346,8 +343,7 @@ TEST(QueryPlan, AggregateMultipleGroupBy) {
// for different records and assert that we get the correct combination // for different records and assert that we get the correct combination
// of values in our groups // of values in our groups
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto prop1 = dba.Property("prop1"); auto prop1 = dba.Property("prop1");
auto prop2 = dba.Property("prop2"); auto prop2 = dba.Property("prop2");
@ -387,7 +383,7 @@ TEST(QueryPlan, AggregateNoInput) {
auto two = LITERAL(2); auto two = LITERAL(2);
auto produce = MakeAggregationProduce(nullptr, symbol_table, storage, {two}, auto produce = MakeAggregationProduce(nullptr, symbol_table, storage, {two},
{Aggregation::Op::COUNT}, {}, {}); {Aggregation::Op::COUNT}, {}, {});
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(1, results.size()); EXPECT_EQ(1, results.size());
EXPECT_EQ(1, results[0].size()); EXPECT_EQ(1, results[0].size());
@ -405,8 +401,7 @@ TEST(QueryPlan, AggregateCountEdgeCases) {
// - 2 vertices in database, property set on both // - 2 vertices in database, property set on both
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto prop = dba.Property("prop"); auto prop = dba.Property("prop");
AstStorage storage; AstStorage storage;
@ -458,8 +453,7 @@ TEST(QueryPlan, AggregateFirstValueTypes) {
// type check // type check
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();
auto prop_string = dba.Property("string"); auto prop_string = dba.Property("string");
@ -515,8 +509,7 @@ TEST(QueryPlan, AggregateTypes) {
// (that logic is defined and tested by TypedValue) // (that logic is defined and tested by TypedValue)
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto p1 = dba.Property("p1"); // has only string props auto p1 = dba.Property("p1"); // has only string props
dba.InsertVertex().PropsSet(p1, "string"); dba.InsertVertex().PropsSet(p1, "string");
@ -592,7 +585,7 @@ TEST(QueryPlan, Unwind) {
->MapTo(symbol_table.CreateSymbol("y_ne", true)); ->MapTo(symbol_table.CreateSymbol("y_ne", true));
auto produce = MakeProduce(unwind_1, x_ne, y_ne); auto produce = MakeProduce(unwind_1, x_ne, y_ne);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(4, results.size()); ASSERT_EQ(4, results.size());
const std::vector<int> expected_x_card{3, 3, 3, 1}; const std::vector<int> expected_x_card{3, 3, 3, 1};

View File

@ -31,23 +31,23 @@ TEST(QueryPlan, Skip) {
auto n = MakeScanAll(storage, symbol_table, "n1"); auto n = MakeScanAll(storage, symbol_table, "n1");
auto skip = std::make_shared<plan::Skip>(n.op_, LITERAL(2)); auto skip = std::make_shared<plan::Skip>(n.op_, LITERAL(2));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(0, PullAll(*skip, &context)); EXPECT_EQ(0, PullAll(*skip, &context));
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(0, PullAll(*skip, &context)); EXPECT_EQ(0, PullAll(*skip, &context));
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(0, PullAll(*skip, &context)); EXPECT_EQ(0, PullAll(*skip, &context));
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(1, PullAll(*skip, &context)); EXPECT_EQ(1, PullAll(*skip, &context));
for (int i = 0; i < 10; ++i) dba->InsertVertex(); for (int i = 0; i < 10; ++i) dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(11, PullAll(*skip, &context)); EXPECT_EQ(11, PullAll(*skip, &context));
} }
@ -61,23 +61,23 @@ TEST(QueryPlan, Limit) {
auto n = MakeScanAll(storage, symbol_table, "n1"); auto n = MakeScanAll(storage, symbol_table, "n1");
auto skip = std::make_shared<plan::Limit>(n.op_, LITERAL(2)); auto skip = std::make_shared<plan::Limit>(n.op_, LITERAL(2));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(0, PullAll(*skip, &context)); EXPECT_EQ(0, PullAll(*skip, &context));
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(1, PullAll(*skip, &context)); EXPECT_EQ(1, PullAll(*skip, &context));
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(2, PullAll(*skip, &context)); EXPECT_EQ(2, PullAll(*skip, &context));
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(2, PullAll(*skip, &context)); EXPECT_EQ(2, PullAll(*skip, &context));
for (int i = 0; i < 10; ++i) dba->InsertVertex(); for (int i = 0; i < 10; ++i) dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(2, PullAll(*skip, &context)); EXPECT_EQ(2, PullAll(*skip, &context));
} }
@ -87,9 +87,9 @@ TEST(QueryPlan, CreateLimit) {
// in the end we need to have 3 vertices in the db // in the end we need to have 3 vertices in the db
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -100,16 +100,15 @@ TEST(QueryPlan, CreateLimit) {
auto c = std::make_shared<CreateNode>(n.op_, m); auto c = std::make_shared<CreateNode>(n.op_, m);
auto skip = std::make_shared<plan::Limit>(c, LITERAL(1)); auto skip = std::make_shared<plan::Limit>(c, LITERAL(1));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*skip, &context)); EXPECT_EQ(1, PullAll(*skip, &context));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(3, CountIterable(dba->Vertices(false))); EXPECT_EQ(3, CountIterable(dba.Vertices(false)));
} }
TEST(QueryPlan, OrderBy) { TEST(QueryPlan, OrderBy) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto prop = dba.Property("prop"); auto prop = dba.Property("prop");
@ -168,8 +167,7 @@ TEST(QueryPlan, OrderBy) {
TEST(QueryPlan, OrderByMultiple) { TEST(QueryPlan, OrderByMultiple) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -224,8 +222,7 @@ TEST(QueryPlan, OrderByMultiple) {
TEST(QueryPlan, OrderByExceptions) { TEST(QueryPlan, OrderByExceptions) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto prop = dba.Property("prop"); auto prop = dba.Property("prop");

View File

@ -18,8 +18,7 @@ using namespace query::plan;
TEST(QueryPlan, CreateNodeWithAttributes) { TEST(QueryPlan, CreateNodeWithAttributes) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
storage::Label label = dba.Label("Person"); storage::Label label = dba.Label("Person");
auto property = PROPERTY_PAIR("prop"); auto property = PROPERTY_PAIR("prop");
@ -54,8 +53,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
TEST(QueryPlan, CreateReturn) { TEST(QueryPlan, CreateReturn) {
// test CREATE (n:Person {age: 42}) RETURN n, n.age // test CREATE (n:Person {age: 42}) RETURN n, n.age
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
storage::Label label = dba.Label("Person"); storage::Label label = dba.Label("Person");
auto property = PROPERTY_PAIR("property"); auto property = PROPERTY_PAIR("property");
@ -94,8 +92,7 @@ TEST(QueryPlan, CreateReturn) {
TEST(QueryPlan, CreateExpand) { TEST(QueryPlan, CreateExpand) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
storage::Label label_node_1 = dba.Label("Node1"); storage::Label label_node_1 = dba.Label("Node1");
storage::Label label_node_2 = dba.Label("Node2"); storage::Label label_node_2 = dba.Label("Node2");
@ -169,10 +166,10 @@ TEST(QueryPlan, MatchCreateNode) {
auto dba = db.Access(); auto dba = db.Access();
// add three nodes we'll match and expand-create from // add three nodes we'll match and expand-create from
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
SymbolTable symbol_table; SymbolTable symbol_table;
AstStorage storage; AstStorage storage;
@ -185,11 +182,11 @@ TEST(QueryPlan, MatchCreateNode) {
// creation op // creation op
auto create_node = std::make_shared<CreateNode>(n_scan_all.op_, m); auto create_node = std::make_shared<CreateNode>(n_scan_all.op_, m);
EXPECT_EQ(CountIterable(dba->Vertices(false)), 3); EXPECT_EQ(CountIterable(dba.Vertices(false)), 3);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
PullAll(*create_node, &context); PullAll(*create_node, &context);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(CountIterable(dba->Vertices(false)), 6); EXPECT_EQ(CountIterable(dba.Vertices(false)), 6);
} }
TEST(QueryPlan, MatchCreateExpand) { TEST(QueryPlan, MatchCreateExpand) {
@ -197,23 +194,23 @@ TEST(QueryPlan, MatchCreateExpand) {
auto dba = db.Access(); auto dba = db.Access();
// add three nodes we'll match and expand-create from // add three nodes we'll match and expand-create from
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
// storage::Label label_node_1 = dba->Label("Node1"); // storage::Label label_node_1 = dba.Label("Node1");
// storage::Label label_node_2 = dba->Label("Node2"); // storage::Label label_node_2 = dba.Label("Node2");
// storage::Property property = dba->Label("prop"); // storage::Property property = dba.Label("prop");
storage::EdgeType edge_type = dba->EdgeType("edge_type"); storage::EdgeType edge_type = dba.EdgeType("edge_type");
SymbolTable symbol_table; SymbolTable symbol_table;
AstStorage storage; AstStorage storage;
auto test_create_path = [&](bool cycle, int expected_nodes_created, auto test_create_path = [&](bool cycle, int expected_nodes_created,
int expected_edges_created) { int expected_edges_created) {
int before_v = CountIterable(dba->Vertices(false)); int before_v = CountIterable(dba.Vertices(false));
int before_e = CountIterable(dba->Edges(false)); int before_e = CountIterable(dba.Edges(false));
// data for the first node // data for the first node
auto n_scan_all = MakeScanAll(storage, symbol_table, "n"); auto n_scan_all = MakeScanAll(storage, symbol_table, "n");
@ -229,13 +226,13 @@ TEST(QueryPlan, MatchCreateExpand) {
auto create_expand = std::make_shared<CreateExpand>(m, r, n_scan_all.op_, auto create_expand = std::make_shared<CreateExpand>(m, r, n_scan_all.op_,
n_scan_all.sym_, cycle); n_scan_all.sym_, cycle);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
PullAll(*create_expand, &context); PullAll(*create_expand, &context);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(CountIterable(dba->Vertices(false)) - before_v, EXPECT_EQ(CountIterable(dba.Vertices(false)) - before_v,
expected_nodes_created); expected_nodes_created);
EXPECT_EQ(CountIterable(dba->Edges(false)) - before_e, EXPECT_EQ(CountIterable(dba.Edges(false)) - before_e,
expected_edges_created); expected_edges_created);
}; };
@ -249,15 +246,15 @@ TEST(QueryPlan, Delete) {
// make a fully-connected (one-direction, no cycles) with 4 nodes // make a fully-connected (one-direction, no cycles) with 4 nodes
std::vector<VertexAccessor> vertices; std::vector<VertexAccessor> vertices;
for (int i = 0; i < 4; ++i) vertices.push_back(dba->InsertVertex()); for (int i = 0; i < 4; ++i) vertices.push_back(dba.InsertVertex());
auto type = dba->EdgeType("type"); auto type = dba.EdgeType("type");
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
for (int k = j + 1; k < 4; ++k) for (int k = j + 1; k < 4; ++k)
dba->InsertEdge(vertices[j], vertices[k], type); dba.InsertEdge(vertices[j], vertices[k], type);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(4, CountIterable(dba->Vertices(false))); EXPECT_EQ(4, CountIterable(dba.Vertices(false)));
EXPECT_EQ(6, CountIterable(dba->Edges(false))); EXPECT_EQ(6, CountIterable(dba.Edges(false)));
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -268,11 +265,11 @@ TEST(QueryPlan, Delete) {
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_); auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*delete_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*delete_op, &context), QueryRuntimeException);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(4, CountIterable(dba->Vertices(false))); EXPECT_EQ(4, CountIterable(dba.Vertices(false)));
EXPECT_EQ(6, CountIterable(dba->Edges(false))); EXPECT_EQ(6, CountIterable(dba.Edges(false)));
} }
// detach delete a single vertex // detach delete a single vertex
@ -282,11 +279,11 @@ TEST(QueryPlan, Delete) {
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, true); n.op_, std::vector<Expression *>{n_get}, true);
Frame frame(symbol_table.max_position()); Frame frame(symbol_table.max_position());
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
delete_op->MakeCursor(*dba)->Pull(frame, context); delete_op->MakeCursor(dba)->Pull(frame, context);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(3, CountIterable(dba->Vertices(false))); EXPECT_EQ(3, CountIterable(dba.Vertices(false)));
EXPECT_EQ(3, CountIterable(dba->Edges(false))); EXPECT_EQ(3, CountIterable(dba.Edges(false)));
} }
// delete all remaining edges // delete all remaining edges
@ -298,11 +295,11 @@ TEST(QueryPlan, Delete) {
auto r_get = storage.Create<Identifier>("r")->MapTo(r_m.edge_sym_); auto r_get = storage.Create<Identifier>("r")->MapTo(r_m.edge_sym_);
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
r_m.op_, std::vector<Expression *>{r_get}, false); r_m.op_, std::vector<Expression *>{r_get}, false);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
PullAll(*delete_op, &context); PullAll(*delete_op, &context);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(3, CountIterable(dba->Vertices(false))); EXPECT_EQ(3, CountIterable(dba.Vertices(false)));
EXPECT_EQ(0, CountIterable(dba->Edges(false))); EXPECT_EQ(0, CountIterable(dba.Edges(false)));
} }
// delete all remaining vertices // delete all remaining vertices
@ -311,11 +308,11 @@ TEST(QueryPlan, Delete) {
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_); auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
PullAll(*delete_op, &context); PullAll(*delete_op, &context);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
EXPECT_EQ(0, CountIterable(dba->Edges(false))); EXPECT_EQ(0, CountIterable(dba.Edges(false)));
} }
} }
@ -335,12 +332,12 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
dba->InsertEdge(v1, v2, dba->EdgeType("T")); dba.InsertEdge(v1, v2, dba.EdgeType("T"));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
EXPECT_EQ(1, CountIterable(dba->Edges(false))); EXPECT_EQ(1, CountIterable(dba.Edges(false)));
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -357,11 +354,11 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
r_m.op_, std::vector<Expression *>{n_get, r_get, m_get}, detach); r_m.op_, std::vector<Expression *>{n_get, r_get, m_get}, detach);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*delete_op, &context)); EXPECT_EQ(2, PullAll(*delete_op, &context));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
EXPECT_EQ(0, CountIterable(dba->Edges(false))); EXPECT_EQ(0, CountIterable(dba.Edges(false)));
}; };
test_delete(true); test_delete(true);
@ -370,8 +367,7 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
TEST(QueryPlan, DeleteReturn) { TEST(QueryPlan, DeleteReturn) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// make a fully-connected (one-direction, no cycles) with 4 nodes // make a fully-connected (one-direction, no cycles) with 4 nodes
auto prop = PROPERTY_PAIR("property"); auto prop = PROPERTY_PAIR("property");
@ -415,7 +411,7 @@ TEST(QueryPlan, DeleteNull) {
auto once = std::make_shared<Once>(); auto once = std::make_shared<Once>();
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
once, std::vector<Expression *>{LITERAL(TypedValue::Null)}, false); once, std::vector<Expression *>{LITERAL(TypedValue::Null)}, false);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*delete_op, &context)); EXPECT_EQ(1, PullAll(*delete_op, &context));
} }
@ -431,8 +427,8 @@ TEST(QueryPlan, DeleteAdvance) {
// we are not yet compatible with that // we are not yet compatible with that
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -443,14 +439,13 @@ TEST(QueryPlan, DeleteAdvance) {
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
auto advance = std::make_shared<Accumulate>( auto advance = std::make_shared<Accumulate>(
delete_op, std::vector<Symbol>{n.sym_}, true); delete_op, std::vector<Symbol>{n.sym_}, true);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*advance, &context), ReconstructionException); EXPECT_THROW(PullAll(*advance, &context), ReconstructionException);
} }
TEST(QueryPlan, SetProperty) { TEST(QueryPlan, SetProperty) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// graph with 4 vertices in connected pairs // graph with 4 vertices in connected pairs
// the origin vertex in each par and both edges // the origin vertex in each par and both edges
@ -506,16 +501,16 @@ TEST(QueryPlan, SetProperties) {
auto dba = db.Access(); auto dba = db.Access();
// graph: ({a: 0})-[:R {b:1}]->({c:2}) // graph: ({a: 0})-[:R {b:1}]->({c:2})
auto prop_a = dba->Property("a"); auto prop_a = dba.Property("a");
auto prop_b = dba->Property("b"); auto prop_b = dba.Property("b");
auto prop_c = dba->Property("c"); auto prop_c = dba.Property("c");
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("R")); auto e = dba.InsertEdge(v1, v2, dba.EdgeType("R"));
v1.PropsSet(prop_a, 0); v1.PropsSet(prop_a, 0);
e.PropsSet(prop_b, 1); e.PropsSet(prop_b, 1);
v2.PropsSet(prop_c, 2); v2.PropsSet(prop_c, 2);
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -536,12 +531,12 @@ TEST(QueryPlan, SetProperties) {
std::make_shared<plan::SetProperties>(r_m.op_, n.sym_, r_ident, op); std::make_shared<plan::SetProperties>(r_m.op_, n.sym_, r_ident, op);
auto set_m_to_r = std::make_shared<plan::SetProperties>( auto set_m_to_r = std::make_shared<plan::SetProperties>(
set_r_to_n, r_m.edge_sym_, m_ident, op); set_r_to_n, r_m.edge_sym_, m_ident, op);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*set_m_to_r, &context)); EXPECT_EQ(1, PullAll(*set_m_to_r, &context));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(CountIterable(dba->Edges(false)), 1); EXPECT_EQ(CountIterable(dba.Edges(false)), 1);
for (EdgeAccessor edge : dba->Edges(false)) { for (EdgeAccessor edge : dba.Edges(false)) {
VertexAccessor from = edge.from(); VertexAccessor from = edge.from();
EXPECT_EQ(from.Properties().size(), update ? 2 : 1); EXPECT_EQ(from.Properties().size(), update ? 2 : 1);
if (update) { if (update) {
@ -574,12 +569,12 @@ TEST(QueryPlan, SetLabels) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto label1 = dba->Label("label1"); auto label1 = dba.Label("label1");
auto label2 = dba->Label("label2"); auto label2 = dba.Label("label2");
auto label3 = dba->Label("label3"); auto label3 = dba.Label("label3");
dba->InsertVertex().add_label(label1); dba.InsertVertex().add_label(label1);
dba->InsertVertex().add_label(label1); dba.InsertVertex().add_label(label1);
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -587,10 +582,10 @@ TEST(QueryPlan, SetLabels) {
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
auto label_set = std::make_shared<plan::SetLabels>( auto label_set = std::make_shared<plan::SetLabels>(
n.op_, n.sym_, std::vector<storage::Label>{label2, label3}); n.op_, n.sym_, std::vector<storage::Label>{label2, label3});
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*label_set, &context)); EXPECT_EQ(2, PullAll(*label_set, &context));
for (VertexAccessor vertex : dba->Vertices(false)) { for (VertexAccessor vertex : dba.Vertices(false)) {
vertex.SwitchNew(); vertex.SwitchNew();
EXPECT_EQ(3, vertex.labels().size()); EXPECT_EQ(3, vertex.labels().size());
EXPECT_TRUE(vertex.has_label(label2)); EXPECT_TRUE(vertex.has_label(label2));
@ -600,8 +595,7 @@ TEST(QueryPlan, SetLabels) {
TEST(QueryPlan, RemoveProperty) { TEST(QueryPlan, RemoveProperty) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// graph with 4 vertices in connected pairs // graph with 4 vertices in connected pairs
// the origin vertex in each par and both edges // the origin vertex in each par and both edges
@ -655,17 +649,17 @@ TEST(QueryPlan, RemoveLabels) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto label1 = dba->Label("label1"); auto label1 = dba.Label("label1");
auto label2 = dba->Label("label2"); auto label2 = dba.Label("label2");
auto label3 = dba->Label("label3"); auto label3 = dba.Label("label3");
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(label1); v1.add_label(label1);
v1.add_label(label2); v1.add_label(label2);
v1.add_label(label3); v1.add_label(label3);
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.add_label(label1); v2.add_label(label1);
v2.add_label(label3); v2.add_label(label3);
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -673,10 +667,10 @@ TEST(QueryPlan, RemoveLabels) {
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
auto label_remove = std::make_shared<plan::RemoveLabels>( auto label_remove = std::make_shared<plan::RemoveLabels>(
n.op_, n.sym_, std::vector<storage::Label>{label1, label2}); n.op_, n.sym_, std::vector<storage::Label>{label1, label2});
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*label_remove, &context)); EXPECT_EQ(2, PullAll(*label_remove, &context));
for (VertexAccessor vertex : dba->Vertices(false)) { for (VertexAccessor vertex : dba.Vertices(false)) {
vertex.SwitchNew(); vertex.SwitchNew();
EXPECT_EQ(1, vertex.labels().size()); EXPECT_EQ(1, vertex.labels().size());
EXPECT_FALSE(vertex.has_label(label1)); EXPECT_FALSE(vertex.has_label(label1));
@ -686,8 +680,7 @@ TEST(QueryPlan, RemoveLabels) {
TEST(QueryPlan, NodeFilterSet) { TEST(QueryPlan, NodeFilterSet) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// Create a graph such that (v1 {prop: 42}) is connected to v2 and v3. // Create a graph such that (v1 {prop: 42}) is connected to v2 and v3.
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();
auto prop = PROPERTY_PAIR("property"); auto prop = PROPERTY_PAIR("property");
@ -730,8 +723,7 @@ TEST(QueryPlan, NodeFilterSet) {
TEST(QueryPlan, FilterRemove) { TEST(QueryPlan, FilterRemove) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// Create a graph such that (v1 {prop: 42}) is connected to v2 and v3. // Create a graph such that (v1 {prop: 42}) is connected to v2 and v3.
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();
auto prop = PROPERTY_PAIR("property"); auto prop = PROPERTY_PAIR("property");
@ -769,10 +761,10 @@ TEST(QueryPlan, FilterRemove) {
TEST(QueryPlan, SetRemove) { TEST(QueryPlan, SetRemove) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
auto label1 = dba->Label("label1"); auto label1 = dba.Label("label1");
auto label2 = dba->Label("label2"); auto label2 = dba.Label("label2");
dba->AdvanceCommand(); dba.AdvanceCommand();
// Create operations which match (v) and set and remove v :label. // Create operations which match (v) and set and remove v :label.
// The expected result is single (v) as it was at the start. // The expected result is single (v) as it was at the start.
AstStorage storage; AstStorage storage;
@ -783,9 +775,9 @@ TEST(QueryPlan, SetRemove) {
scan_all.op_, scan_all.sym_, std::vector<storage::Label>{label1, label2}); scan_all.op_, scan_all.sym_, std::vector<storage::Label>{label1, label2});
auto rem = std::make_shared<plan::RemoveLabels>( auto rem = std::make_shared<plan::RemoveLabels>(
set, scan_all.sym_, std::vector<storage::Label>{label1, label2}); set, scan_all.sym_, std::vector<storage::Label>{label1, label2});
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*rem, &context)); EXPECT_EQ(1, PullAll(*rem, &context));
dba->AdvanceCommand(); dba.AdvanceCommand();
v.Reconstruct(); v.Reconstruct();
EXPECT_FALSE(v.has_label(label1)); EXPECT_FALSE(v.has_label(label1));
EXPECT_FALSE(v.has_label(label2)); EXPECT_FALSE(v.has_label(label2));
@ -799,8 +791,7 @@ TEST(QueryPlan, Merge) {
// and sets some property (for result validation) // and sets some property (for result validation)
// - merge_create branch just sets some other property // - merge_create branch just sets some other property
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba.InsertVertex(); auto v2 = dba.InsertVertex();
dba.InsertEdge(v1, v2, dba.EdgeType("Type")); dba.InsertEdge(v1, v2, dba.EdgeType("Type"));
@ -855,18 +846,17 @@ TEST(QueryPlan, MergeNoInput) {
auto create = std::make_shared<CreateNode>(nullptr, node); auto create = std::make_shared<CreateNode>(nullptr, node);
auto merge = std::make_shared<plan::Merge>(nullptr, create, create); auto merge = std::make_shared<plan::Merge>(nullptr, create, create);
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*merge, &context)); EXPECT_EQ(1, PullAll(*merge, &context));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(1, CountIterable(dba->Vertices(false))); EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
} }
TEST(QueryPlan, SetPropertyOnNull) { TEST(QueryPlan, SetPropertyOnNull) {
// SET (Null).prop = 42 // SET (Null).prop = 42
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto prop = PROPERTY_PAIR("property"); auto prop = PROPERTY_PAIR("property");
@ -892,8 +882,8 @@ TEST(QueryPlan, SetPropertiesOnNull) {
std::vector<Symbol>{n.sym_}); std::vector<Symbol>{n.sym_});
auto set_op = std::make_shared<plan::SetProperties>( auto set_op = std::make_shared<plan::SetProperties>(
optional, n.sym_, n_ident, plan::SetProperties::Op::REPLACE); optional, n.sym_, n_ident, plan::SetProperties::Op::REPLACE);
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*set_op, &context)); EXPECT_EQ(1, PullAll(*set_op, &context));
} }
@ -901,7 +891,7 @@ TEST(QueryPlan, SetLabelsOnNull) {
// OPTIONAL MATCH (n) SET n :label // OPTIONAL MATCH (n) SET n :label
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label("label"); auto label = dba.Label("label");
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
@ -909,16 +899,15 @@ TEST(QueryPlan, SetLabelsOnNull) {
std::vector<Symbol>{n.sym_}); std::vector<Symbol>{n.sym_});
auto set_op = std::make_shared<plan::SetLabels>( auto set_op = std::make_shared<plan::SetLabels>(
optional, n.sym_, std::vector<storage::Label>{label}); optional, n.sym_, std::vector<storage::Label>{label});
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*set_op, &context)); EXPECT_EQ(1, PullAll(*set_op, &context));
} }
TEST(QueryPlan, RemovePropertyOnNull) { TEST(QueryPlan, RemovePropertyOnNull) {
// REMOVE (Null).prop // REMOVE (Null).prop
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto prop = PROPERTY_PAIR("property"); auto prop = PROPERTY_PAIR("property");
@ -935,7 +924,7 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
// OPTIONAL MATCH (n) REMOVE n :label // OPTIONAL MATCH (n) REMOVE n :label
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label("label"); auto label = dba.Label("label");
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
@ -943,15 +932,14 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
std::vector<Symbol>{n.sym_}); std::vector<Symbol>{n.sym_});
auto remove_op = std::make_shared<plan::RemoveLabels>( auto remove_op = std::make_shared<plan::RemoveLabels>(
optional, n.sym_, std::vector<storage::Label>{label}); optional, n.sym_, std::vector<storage::Label>{label});
EXPECT_EQ(0, CountIterable(dba->Vertices(false))); EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*remove_op, &context)); EXPECT_EQ(1, PullAll(*remove_op, &context));
} }
TEST(QueryPlan, DeleteSetProperty) { TEST(QueryPlan, DeleteSetProperty) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// Add a single vertex. // Add a single vertex.
dba.InsertVertex(); dba.InsertVertex();
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -973,8 +961,7 @@ TEST(QueryPlan, DeleteSetProperty) {
TEST(QueryPlan, DeleteSetPropertiesFromMap) { TEST(QueryPlan, DeleteSetPropertiesFromMap) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// Add a single vertex. // Add a single vertex.
dba.InsertVertex(); dba.InsertVertex();
dba.AdvanceCommand(); dba.AdvanceCommand();
@ -1001,8 +988,7 @@ TEST(QueryPlan, DeleteSetPropertiesFromMap) {
TEST(QueryPlan, DeleteSetPropertiesFromVertex) { TEST(QueryPlan, DeleteSetPropertiesFromVertex) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// Add a single vertex. // Add a single vertex.
{ {
auto v = dba.InsertVertex(); auto v = dba.InsertVertex();
@ -1031,9 +1017,9 @@ TEST(QueryPlan, DeleteRemoveLabels) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Add a single vertex. // Add a single vertex.
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(1, CountIterable(dba->Vertices(false))); EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
// MATCH (n) DELETE n REMOVE n :label // MATCH (n) DELETE n REMOVE n :label
@ -1041,16 +1027,15 @@ TEST(QueryPlan, DeleteRemoveLabels) {
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_); auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
auto delete_op = std::make_shared<plan::Delete>( auto delete_op = std::make_shared<plan::Delete>(
n.op_, std::vector<Expression *>{n_get}, false); n.op_, std::vector<Expression *>{n_get}, false);
std::vector<storage::Label> labels{dba->Label("label")}; std::vector<storage::Label> labels{dba.Label("label")};
auto rem_op = std::make_shared<plan::RemoveLabels>(delete_op, n.sym_, labels); auto rem_op = std::make_shared<plan::RemoveLabels>(delete_op, n.sym_, labels);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException);
} }
TEST(QueryPlan, DeleteRemoveProperty) { TEST(QueryPlan, DeleteRemoveProperty) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// Add a single vertex. // Add a single vertex.
dba.InsertVertex(); dba.InsertVertex();
dba.AdvanceCommand(); dba.AdvanceCommand();

View File

@ -17,15 +17,15 @@ DECLARE_bool(query_cost_planner);
class QueryExecution : public testing::Test { class QueryExecution : public testing::Test {
protected: protected:
std::experimental::optional<database::GraphDb> db_; std::experimental::optional<database::GraphDb> db_;
std::unique_ptr<database::GraphDbAccessor> dba_; std::experimental::optional<database::GraphDbAccessor> dba_;
void SetUp() { void SetUp() {
db_.emplace(); db_.emplace();
dba_ = db_->Access(); dba_.emplace(db_->Access());
} }
void TearDown() { void TearDown() {
dba_ = nullptr; dba_ = std::experimental::nullopt;
db_ = std::experimental::nullopt; db_ = std::experimental::nullopt;
} }

View File

@ -27,18 +27,18 @@ using namespace query::plan;
class MatchReturnFixture : public testing::Test { class MatchReturnFixture : public testing::Test {
protected: protected:
database::GraphDb db_; database::GraphDb db_;
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()}; database::GraphDbAccessor dba_{db_.Access()};
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
void AddVertices(int count) { void AddVertices(int count) {
for (int i = 0; i < count; i++) dba_->InsertVertex(); for (int i = 0; i < count; i++) dba_.InsertVertex();
} }
template <typename TResult> template <typename TResult>
std::vector<TResult> Results(std::shared_ptr<Produce> &op) { std::vector<TResult> Results(std::shared_ptr<Produce> &op) {
std::vector<TResult> res; std::vector<TResult> res;
auto context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, &dba_);
for (const auto &row : CollectProduce(*op, &context)) for (const auto &row : CollectProduce(*op, &context))
res.emplace_back(row[0].Value<TResult>()); res.emplace_back(row[0].Value<TResult>());
return res; return res;
@ -47,7 +47,7 @@ class MatchReturnFixture : public testing::Test {
TEST_F(MatchReturnFixture, MatchReturn) { TEST_F(MatchReturnFixture, MatchReturn) {
AddVertices(2); AddVertices(2);
dba_->AdvanceCommand(); dba_.AdvanceCommand();
auto test_pull_count = [&](GraphView graph_view) { auto test_pull_count = [&](GraphView graph_view) {
auto scan_all = auto scan_all =
@ -56,22 +56,22 @@ TEST_F(MatchReturnFixture, MatchReturn) {
NEXPR("n", IDENT("n")->MapTo(scan_all.sym_)) NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
auto context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, &dba_);
return PullAll(*produce, &context); return PullAll(*produce, &context);
}; };
EXPECT_EQ(2, test_pull_count(GraphView::NEW)); EXPECT_EQ(2, test_pull_count(GraphView::NEW));
EXPECT_EQ(2, test_pull_count(GraphView::OLD)); EXPECT_EQ(2, test_pull_count(GraphView::OLD));
dba_->InsertVertex(); dba_.InsertVertex();
EXPECT_EQ(3, test_pull_count(GraphView::NEW)); EXPECT_EQ(3, test_pull_count(GraphView::NEW));
EXPECT_EQ(2, test_pull_count(GraphView::OLD)); EXPECT_EQ(2, test_pull_count(GraphView::OLD));
dba_->AdvanceCommand(); dba_.AdvanceCommand();
EXPECT_EQ(3, test_pull_count(GraphView::OLD)); EXPECT_EQ(3, test_pull_count(GraphView::OLD));
} }
TEST_F(MatchReturnFixture, MatchReturnPath) { TEST_F(MatchReturnFixture, MatchReturnPath) {
AddVertices(2); AddVertices(2);
dba_->AdvanceCommand(); dba_.AdvanceCommand();
auto scan_all = MakeScanAll(storage, symbol_table, "n", nullptr); auto scan_all = MakeScanAll(storage, symbol_table, "n", nullptr);
Symbol path_sym = symbol_table.CreateSymbol("path", true); Symbol path_sym = symbol_table.CreateSymbol("path", true);
@ -84,7 +84,7 @@ TEST_F(MatchReturnFixture, MatchReturnPath) {
auto results = Results<query::Path>(produce); auto results = Results<query::Path>(produce);
ASSERT_EQ(results.size(), 2); ASSERT_EQ(results.size(), 2);
std::vector<query::Path> expected_paths; std::vector<query::Path> expected_paths;
for (const auto &v : dba_->Vertices(false)) expected_paths.emplace_back(v); for (const auto &v : dba_.Vertices(false)) expected_paths.emplace_back(v);
ASSERT_EQ(expected_paths.size(), 2); ASSERT_EQ(expected_paths.size(), 2);
EXPECT_TRUE(std::is_permutation(expected_paths.begin(), expected_paths.end(), EXPECT_TRUE(std::is_permutation(expected_paths.begin(), expected_paths.end(),
results.begin())); results.begin()));
@ -94,9 +94,9 @@ TEST(QueryPlan, MatchReturnCartesian) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex().add_label(dba->Label("l1")); dba.InsertVertex().add_label(dba.Label("l1"));
dba->InsertVertex().add_label(dba->Label("l2")); dba.InsertVertex().add_label(dba.Label("l2"));
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -110,7 +110,7 @@ TEST(QueryPlan, MatchReturnCartesian) {
NEXPR("m", IDENT("m")->MapTo(m.sym_)) NEXPR("m", IDENT("m")->MapTo(m.sym_))
->MapTo(symbol_table.CreateSymbol("named_expression_2", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_2", true));
auto produce = MakeProduce(m.op_, return_n, return_m); auto produce = MakeProduce(m.op_, return_n, return_m);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 4); EXPECT_EQ(results.size(), 4);
// ensure the result ordering is OK: // ensure the result ordering is OK:
@ -126,9 +126,9 @@ TEST(QueryPlan, StandaloneReturn) {
auto dba = db.Access(); auto dba = db.Access();
// add a few nodes to the database // add a few nodes to the database
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -137,7 +137,7 @@ TEST(QueryPlan, StandaloneReturn) {
auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output); auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output);
output->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); output->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 1); EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0].size(), 1); EXPECT_EQ(results[0].size(), 1);
@ -146,8 +146,7 @@ TEST(QueryPlan, StandaloneReturn) {
TEST(QueryPlan, NodeFilterLabelsAndProperties) { TEST(QueryPlan, NodeFilterLabelsAndProperties) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// add a few nodes to the database // add a few nodes to the database
storage::Label label = dba.Label("Label"); storage::Label label = dba.Label("Label");
@ -207,33 +206,33 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
auto dba = db.Access(); auto dba = db.Access();
// add a few nodes to the database // add a few nodes to the database
storage::Label label1 = dba->Label("label1"); storage::Label label1 = dba.Label("label1");
storage::Label label2 = dba->Label("label2"); storage::Label label2 = dba.Label("label2");
storage::Label label3 = dba->Label("label3"); storage::Label label3 = dba.Label("label3");
// the test will look for nodes that have label1 and label2 // the test will look for nodes that have label1 and label2
dba->InsertVertex(); // NOT accepted dba.InsertVertex(); // NOT accepted
dba->InsertVertex().add_label(label1); // NOT accepted dba.InsertVertex().add_label(label1); // NOT accepted
dba->InsertVertex().add_label(label2); // NOT accepted dba.InsertVertex().add_label(label2); // NOT accepted
dba->InsertVertex().add_label(label3); // NOT accepted dba.InsertVertex().add_label(label3); // NOT accepted
auto v1 = dba->InsertVertex(); // YES accepted auto v1 = dba.InsertVertex(); // YES accepted
v1.add_label(label1); v1.add_label(label1);
v1.add_label(label2); v1.add_label(label2);
auto v2 = dba->InsertVertex(); // NOT accepted auto v2 = dba.InsertVertex(); // NOT accepted
v2.add_label(label1); v2.add_label(label1);
v2.add_label(label3); v2.add_label(label3);
auto v3 = dba->InsertVertex(); // YES accepted auto v3 = dba.InsertVertex(); // YES accepted
v3.add_label(label1); v3.add_label(label1);
v3.add_label(label2); v3.add_label(label2);
v3.add_label(label3); v3.add_label(label3);
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
// make a scan all // make a scan all
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
n.node_->labels_.emplace_back(storage.GetLabelIx(dba->LabelName(label1))); n.node_->labels_.emplace_back(storage.GetLabelIx(dba.LabelName(label1)));
n.node_->labels_.emplace_back(storage.GetLabelIx(dba->LabelName(label2))); n.node_->labels_.emplace_back(storage.GetLabelIx(dba.LabelName(label2)));
// node filtering // node filtering
auto *filter_expr = auto *filter_expr =
@ -246,7 +245,7 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto produce = MakeProduce(node_filter, output); auto produce = MakeProduce(node_filter, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 2); EXPECT_EQ(results.size(), 2);
} }
@ -256,14 +255,14 @@ TEST(QueryPlan, Cartesian) {
auto dba = db.Access(); auto dba = db.Access();
auto add_vertex = [&dba](std::string label) { auto add_vertex = [&dba](std::string label) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(dba->Label(label)); vertex.add_label(dba.Label(label));
return vertex; return vertex;
}; };
std::vector<VertexAccessor> vertices{add_vertex("v1"), add_vertex("v2"), std::vector<VertexAccessor> vertices{add_vertex("v1"), add_vertex("v2"),
add_vertex("v3")}; add_vertex("v3")};
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -284,7 +283,7 @@ TEST(QueryPlan, Cartesian) {
auto produce = MakeProduce(cartesian_op, return_n, return_m); auto produce = MakeProduce(cartesian_op, return_n, return_m);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 9); EXPECT_EQ(results.size(), 9);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
@ -317,7 +316,7 @@ TEST(QueryPlan, CartesianEmptySet) {
std::make_shared<Cartesian>(n.op_, left_symbols, m.op_, right_symbols); std::make_shared<Cartesian>(n.op_, left_symbols, m.op_, right_symbols);
auto produce = MakeProduce(cartesian_op, return_n, return_m); auto produce = MakeProduce(cartesian_op, return_n, return_m);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 0); EXPECT_EQ(results.size(), 0);
} }
@ -326,14 +325,14 @@ TEST(QueryPlan, CartesianThreeWay) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto add_vertex = [&dba](std::string label) { auto add_vertex = [&dba](std::string label) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(dba->Label(label)); vertex.add_label(dba.Label(label));
return vertex; return vertex;
}; };
std::vector<VertexAccessor> vertices{add_vertex("v1"), add_vertex("v2"), std::vector<VertexAccessor> vertices{add_vertex("v1"), add_vertex("v2"),
add_vertex("v3")}; add_vertex("v3")};
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -362,7 +361,7 @@ TEST(QueryPlan, CartesianThreeWay) {
l.op_, l_symbols); l.op_, l_symbols);
auto produce = MakeProduce(cartesian_op_2, return_n, return_m, return_l); auto produce = MakeProduce(cartesian_op_2, return_n, return_m, return_l);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 27); EXPECT_EQ(results.size(), 27);
int id = 0; int id = 0;
@ -381,23 +380,23 @@ TEST(QueryPlan, CartesianThreeWay) {
class ExpandFixture : public testing::Test { class ExpandFixture : public testing::Test {
protected: protected:
database::GraphDb db_; database::GraphDb db_;
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()}; database::GraphDbAccessor dba_{db_.Access()};
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
// make a V-graph (v3)<-[r2]-(v1)-[r1]->(v2) // make a V-graph (v3)<-[r2]-(v1)-[r1]->(v2)
VertexAccessor v1 = dba_->InsertVertex(); VertexAccessor v1 = dba_.InsertVertex();
VertexAccessor v2 = dba_->InsertVertex(); VertexAccessor v2 = dba_.InsertVertex();
VertexAccessor v3 = dba_->InsertVertex(); VertexAccessor v3 = dba_.InsertVertex();
storage::EdgeType edge_type = dba_->EdgeType("Edge"); storage::EdgeType edge_type = dba_.EdgeType("Edge");
EdgeAccessor r1 = dba_->InsertEdge(v1, v2, edge_type); EdgeAccessor r1 = dba_.InsertEdge(v1, v2, edge_type);
EdgeAccessor r2 = dba_->InsertEdge(v1, v3, edge_type); EdgeAccessor r2 = dba_.InsertEdge(v1, v3, edge_type);
void SetUp() override { void SetUp() override {
v1.add_label(dba_->Label("l1")); v1.add_label(dba_.Label("l1"));
v2.add_label(dba_->Label("l2")); v2.add_label(dba_.Label("l2"));
v3.add_label(dba_->Label("l3")); v3.add_label(dba_.Label("l3"));
dba_->AdvanceCommand(); dba_.AdvanceCommand();
} }
}; };
@ -412,7 +411,7 @@ TEST_F(ExpandFixture, Expand) {
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_)) NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto produce = MakeProduce(r_m.op_, output); auto produce = MakeProduce(r_m.op_, output);
auto context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, &dba_);
return PullAll(*produce, &context); return PullAll(*produce, &context);
}; };
@ -420,15 +419,15 @@ TEST_F(ExpandFixture, Expand) {
v1.Reconstruct(); v1.Reconstruct();
v2.Reconstruct(); v2.Reconstruct();
v3.Reconstruct(); v3.Reconstruct();
dba_->InsertEdge(v1, v2, edge_type); dba_.InsertEdge(v1, v2, edge_type);
dba_->InsertEdge(v1, v3, edge_type); dba_.InsertEdge(v1, v3, edge_type);
EXPECT_EQ(2, test_expand(EdgeAtom::Direction::OUT, GraphView::OLD)); EXPECT_EQ(2, test_expand(EdgeAtom::Direction::OUT, GraphView::OLD));
EXPECT_EQ(2, test_expand(EdgeAtom::Direction::IN, GraphView::OLD)); EXPECT_EQ(2, test_expand(EdgeAtom::Direction::IN, GraphView::OLD));
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::BOTH, GraphView::OLD)); EXPECT_EQ(4, test_expand(EdgeAtom::Direction::BOTH, GraphView::OLD));
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::OUT, GraphView::NEW)); EXPECT_EQ(4, test_expand(EdgeAtom::Direction::OUT, GraphView::NEW));
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::IN, GraphView::NEW)); EXPECT_EQ(4, test_expand(EdgeAtom::Direction::IN, GraphView::NEW));
EXPECT_EQ(8, test_expand(EdgeAtom::Direction::BOTH, GraphView::NEW)); EXPECT_EQ(8, test_expand(EdgeAtom::Direction::BOTH, GraphView::NEW));
dba_->AdvanceCommand(); dba_.AdvanceCommand();
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::OUT, GraphView::OLD)); EXPECT_EQ(4, test_expand(EdgeAtom::Direction::OUT, GraphView::OLD));
EXPECT_EQ(4, test_expand(EdgeAtom::Direction::IN, GraphView::OLD)); EXPECT_EQ(4, test_expand(EdgeAtom::Direction::IN, GraphView::OLD));
EXPECT_EQ(8, test_expand(EdgeAtom::Direction::BOTH, GraphView::OLD)); EXPECT_EQ(8, test_expand(EdgeAtom::Direction::BOTH, GraphView::OLD));
@ -449,7 +448,7 @@ TEST_F(ExpandFixture, ExpandPath) {
auto produce = MakeProduce(path, output); auto produce = MakeProduce(path, output);
std::vector<query::Path> expected_paths{{v1, r2, v3}, {v1, r1, v2}}; std::vector<query::Path> expected_paths{{v1, r2, v3}, {v1, r1, v2}};
auto context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, &dba_);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), 2); ASSERT_EQ(results.size(), 2);
std::vector<query::Path> results_paths; std::vector<query::Path> results_paths;
@ -478,11 +477,11 @@ class QueryPlanExpandVariable : public testing::Test {
using map_int = std::unordered_map<int, int>; using map_int = std::unordered_map<int, int>;
database::GraphDb db_; database::GraphDb db_;
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()}; database::GraphDbAccessor dba_{db_.Access()};
// labels for layers in the double chain // labels for layers in the double chain
std::vector<storage::Label> labels; std::vector<storage::Label> labels;
// for all the edges // for all the edges
storage::EdgeType edge_type = dba_->EdgeType("edge_type"); storage::EdgeType edge_type = dba_.EdgeType("edge_type");
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -496,26 +495,26 @@ class QueryPlanExpandVariable : public testing::Test {
std::vector<VertexAccessor> layer; std::vector<VertexAccessor> layer;
for (int from_layer_ind = -1; from_layer_ind < chain_length - 1; for (int from_layer_ind = -1; from_layer_ind < chain_length - 1;
from_layer_ind++) { from_layer_ind++) {
std::vector<VertexAccessor> new_layer{dba_->InsertVertex(), std::vector<VertexAccessor> new_layer{dba_.InsertVertex(),
dba_->InsertVertex()}; dba_.InsertVertex()};
auto label = dba_->Label(std::to_string(from_layer_ind + 1)); auto label = dba_.Label(std::to_string(from_layer_ind + 1));
labels.push_back(label); labels.push_back(label);
for (size_t v_to_ind = 0; v_to_ind < new_layer.size(); v_to_ind++) { for (size_t v_to_ind = 0; v_to_ind < new_layer.size(); v_to_ind++) {
auto &v_to = new_layer[v_to_ind]; auto &v_to = new_layer[v_to_ind];
v_to.add_label(label); v_to.add_label(label);
for (size_t v_from_ind = 0; v_from_ind < layer.size(); v_from_ind++) { for (size_t v_from_ind = 0; v_from_ind < layer.size(); v_from_ind++) {
auto &v_from = layer[v_from_ind]; auto &v_from = layer[v_from_ind];
auto edge = dba_->InsertEdge(v_from, v_to, edge_type); auto edge = dba_.InsertEdge(v_from, v_to, edge_type);
edge.PropsSet(dba_->Property("p"), edge.PropsSet(dba_.Property("p"),
fmt::format("V{}{}->V{}{}", from_layer_ind, v_from_ind, fmt::format("V{}{}->V{}{}", from_layer_ind, v_from_ind,
from_layer_ind + 1, v_to_ind)); from_layer_ind + 1, v_to_ind));
} }
} }
layer = new_layer; layer = new_layer;
} }
dba_->AdvanceCommand(); dba_.AdvanceCommand();
ASSERT_EQ(CountIterable(dba_->Vertices(false)), 2 * chain_length); ASSERT_EQ(CountIterable(dba_.Vertices(false)), 2 * chain_length);
ASSERT_EQ(CountIterable(dba_->Edges(false)), 4 * (chain_length - 1)); ASSERT_EQ(CountIterable(dba_.Edges(false)), 4 * (chain_length - 1));
} }
/** /**
@ -543,7 +542,7 @@ class QueryPlanExpandVariable : public testing::Test {
n_from.op_, n_from.op_,
storage.Create<query::LabelsTest>( storage.Create<query::LabelsTest>(
n_from.node_->identifier_, std::vector<LabelIx>{storage.GetLabelIx( n_from.node_->identifier_, std::vector<LabelIx>{storage.GetLabelIx(
dba_->LabelName(labels[layer]))})); dba_.LabelName(labels[layer]))}));
auto n_to = NODE(node_to); auto n_to = NODE(node_to);
auto n_to_sym = symbol_table.CreateSymbol(node_to, true); auto n_to_sym = symbol_table.CreateSymbol(node_to, true);
@ -588,8 +587,8 @@ class QueryPlanExpandVariable : public testing::Test {
template <typename TResult> template <typename TResult>
auto GetResults(std::shared_ptr<LogicalOperator> input_op, Symbol symbol) { auto GetResults(std::shared_ptr<LogicalOperator> input_op, Symbol symbol) {
Frame frame(symbol_table.max_position()); Frame frame(symbol_table.max_position());
auto cursor = input_op->MakeCursor(*dba_); auto cursor = input_op->MakeCursor(dba_);
auto context = MakeContext(storage, symbol_table, dba_.get()); auto context = MakeContext(storage, symbol_table, &dba_);
std::vector<TResult> results; std::vector<TResult> results;
while (cursor->Pull(frame, context)) while (cursor->Pull(frame, context))
results.emplace_back(frame[symbol].Value<TResult>()); results.emplace_back(frame[symbol].Value<TResult>());
@ -768,7 +767,7 @@ TEST_F(QueryPlanExpandVariable, NamedPath) {
std::vector<Symbol>{find_symbol("n"), e, find_symbol("m")}); std::vector<Symbol>{find_symbol("n"), e, find_symbol("m")});
std::vector<query::Path> expected_paths; std::vector<query::Path> expected_paths;
for (const auto &v : dba_->Vertices(labels[0], false)) for (const auto &v : dba_.Vertices(labels[0], false))
for (const auto &e1 : v.out()) for (const auto &e1 : v.out())
for (const auto &e2 : e1.to().out()) for (const auto &e2 : e1.to().out())
expected_paths.emplace_back(v, e1, e1.to(), e2, e2.to()); expected_paths.emplace_back(v, e1, e1.to(), e2, e2.to());
@ -803,8 +802,7 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test {
// style-guide non-conformant name due to PROPERTY_PAIR and // style-guide non-conformant name due to PROPERTY_PAIR and
// PROPERTY_LOOKUP macro requirements // PROPERTY_LOOKUP macro requirements
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()}; database::GraphDbAccessor dba{db.Access()};
database::GraphDbAccessor &dba{*dba_ptr};
std::pair<std::string, storage::Property> prop = PROPERTY_PAIR("property"); std::pair<std::string, storage::Property> prop = PROPERTY_PAIR("property");
storage::EdgeType edge_type = dba.EdgeType("edge_type"); storage::EdgeType edge_type = dba.EdgeType("edge_type");
@ -1139,17 +1137,17 @@ TEST(QueryPlan, ExpandOptional) {
SymbolTable symbol_table; SymbolTable symbol_table;
// graph (v2 {p: 2})<-[:T]-(v1 {p: 1})-[:T]->(v3 {p: 2}) // graph (v2 {p: 2})<-[:T]-(v1 {p: 1})-[:T]->(v3 {p: 2})
auto prop = dba->Property("p"); auto prop = dba.Property("p");
auto edge_type = dba->EdgeType("T"); auto edge_type = dba.EdgeType("T");
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.PropsSet(prop, 1); v1.PropsSet(prop, 1);
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.PropsSet(prop, 2); v2.PropsSet(prop, 2);
dba->InsertEdge(v1, v2, edge_type); dba.InsertEdge(v1, v2, edge_type);
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
v3.PropsSet(prop, 2); v3.PropsSet(prop, 2);
dba->InsertEdge(v1, v3, edge_type); dba.InsertEdge(v1, v3, edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
// MATCH (n) OPTIONAL MATCH (n)-[r]->(m) // MATCH (n) OPTIONAL MATCH (n)-[r]->(m)
auto n = MakeScanAll(storage, symbol_table, "n"); auto n = MakeScanAll(storage, symbol_table, "n");
@ -1167,7 +1165,7 @@ TEST(QueryPlan, ExpandOptional) {
auto m_ne = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_)) auto m_ne = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
->MapTo(symbol_table.CreateSymbol("m", true)); ->MapTo(symbol_table.CreateSymbol("m", true));
auto produce = MakeProduce(optional, n_ne, r_ne, m_ne); auto produce = MakeProduce(optional, n_ne, r_ne, m_ne);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(4, results.size()); ASSERT_EQ(4, results.size());
int v1_is_n_count = 0; int v1_is_n_count = 0;
@ -1203,7 +1201,7 @@ TEST(QueryPlan, OptionalMatchEmptyDB) {
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_, auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
std::vector<Symbol>{n.sym_}); std::vector<Symbol>{n.sym_});
auto produce = MakeProduce(optional, n_ne); auto produce = MakeProduce(optional, n_ne);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(1, results.size()); ASSERT_EQ(1, results.size());
EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null); EXPECT_EQ(results[0][0].type(), TypedValue::Type::Null);
@ -1231,7 +1229,7 @@ TEST(QueryPlan, OptionalMatchEmptyDBExpandFromNode) {
auto m_ne = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_)) auto m_ne = NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
->MapTo(symbol_table.CreateSymbol("m", true)); ->MapTo(symbol_table.CreateSymbol("m", true));
auto produce = MakeProduce(r_m.op_, m_ne); auto produce = MakeProduce(r_m.op_, m_ne);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(0, results.size()); EXPECT_EQ(0, results.size());
} }
@ -1240,13 +1238,13 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Make a graph with 2 connected, unlabeled nodes. // Make a graph with 2 connected, unlabeled nodes.
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto edge_type = dba->EdgeType("edge_type"); auto edge_type = dba.EdgeType("edge_type");
dba->InsertEdge(v1, v2, edge_type); dba.InsertEdge(v1, v2, edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
EXPECT_EQ(1, CountIterable(dba->Edges(false))); EXPECT_EQ(1, CountIterable(dba.Edges(false)));
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
// OPTIONAL MATCH (n :missing) // OPTIONAL MATCH (n :missing)
@ -1279,7 +1277,7 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
auto m_ne = NEXPR("m", IDENT("m")->MapTo(m.sym_)) auto m_ne = NEXPR("m", IDENT("m")->MapTo(m.sym_))
->MapTo(symbol_table.CreateSymbol("m", true)); ->MapTo(symbol_table.CreateSymbol("m", true));
auto produce = MakeProduce(expand, m_ne); auto produce = MakeProduce(expand, m_ne);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(0, results.size()); EXPECT_EQ(0, results.size());
} }
@ -1290,12 +1288,12 @@ TEST(QueryPlan, ExpandExistingNode) {
// make a graph (v1)->(v2) that // make a graph (v1)->(v2) that
// has a recursive edge (v1)->(v1) // has a recursive edge (v1)->(v1)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto edge_type = dba->EdgeType("Edge"); auto edge_type = dba.EdgeType("Edge");
dba->InsertEdge(v1, v1, edge_type); dba.InsertEdge(v1, v1, edge_type);
dba->InsertEdge(v1, v2, edge_type); dba.InsertEdge(v1, v2, edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1315,7 +1313,7 @@ TEST(QueryPlan, ExpandExistingNode) {
NEXPR("n", IDENT("n")->MapTo(n.sym_)) NEXPR("n", IDENT("n")->MapTo(n.sym_))
->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto produce = MakeProduce(r_n.op_, output); auto produce = MakeProduce(r_n.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), expected_result_count); EXPECT_EQ(results.size(), expected_result_count);
}; };
@ -1330,9 +1328,9 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
dba->InsertEdge(v, v, dba->EdgeType("et")); dba.InsertEdge(v, v, dba.EdgeType("et"));
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1341,14 +1339,13 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
auto r_ = auto r_ =
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r", MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
EdgeAtom::Direction::BOTH, {}, "_", false, GraphView::OLD); EdgeAtom::Direction::BOTH, {}, "_", false, GraphView::OLD);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*r_.op_, &context)); EXPECT_EQ(1, PullAll(*r_.op_, &context));
} }
TEST(QueryPlan, EdgeFilter) { TEST(QueryPlan, EdgeFilter) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// make an N-star expanding from (v1) // make an N-star expanding from (v1)
// where only one edge will qualify // where only one edge will qualify
@ -1419,15 +1416,15 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto type_1 = dba->EdgeType("type_1"); auto type_1 = dba.EdgeType("type_1");
auto type_2 = dba->EdgeType("type_2"); auto type_2 = dba.EdgeType("type_2");
auto type_3 = dba->EdgeType("type_3"); auto type_3 = dba.EdgeType("type_3");
dba->InsertEdge(v1, v2, type_1); dba.InsertEdge(v1, v2, type_1);
dba->InsertEdge(v1, v2, type_2); dba.InsertEdge(v1, v2, type_2);
dba->InsertEdge(v1, v2, type_3); dba.InsertEdge(v1, v2, type_3);
dba->AdvanceCommand(); dba.AdvanceCommand();
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1443,15 +1440,14 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_)) NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto produce = MakeProduce(r_m.op_, output); auto produce = MakeProduce(r_m.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 2); EXPECT_EQ(results.size(), 2);
} }
TEST(QueryPlan, Filter) { TEST(QueryPlan, Filter) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
// add a 6 nodes with property 'prop', 2 have true as value // add a 6 nodes with property 'prop', 2 have true as value
auto property = PROPERTY_PAIR("property"); auto property = PROPERTY_PAIR("property");
@ -1480,12 +1476,12 @@ TEST(QueryPlan, EdgeUniquenessFilter) {
auto dba = db.Access(); auto dba = db.Access();
// make a graph that has (v1)->(v2) and a recursive edge (v1)->(v1) // make a graph that has (v1)->(v2) and a recursive edge (v1)->(v1)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto edge_type = dba->EdgeType("edge_type"); auto edge_type = dba.EdgeType("edge_type");
dba->InsertEdge(v1, v2, edge_type); dba.InsertEdge(v1, v2, edge_type);
dba->InsertEdge(v1, v1, edge_type); dba.InsertEdge(v1, v1, edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
auto check_expand_results = [&](bool edge_uniqueness) { auto check_expand_results = [&](bool edge_uniqueness) {
AstStorage storage; AstStorage storage;
@ -1503,7 +1499,7 @@ TEST(QueryPlan, EdgeUniquenessFilter) {
if (edge_uniqueness) if (edge_uniqueness)
last_op = std::make_shared<EdgeUniquenessFilter>( last_op = std::make_shared<EdgeUniquenessFilter>(
last_op, r2_n3.edge_sym_, std::vector<Symbol>{r1_n2.edge_sym_}); last_op, r2_n3.edge_sym_, std::vector<Symbol>{r1_n2.edge_sym_});
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
return PullAll(*last_op, &context); return PullAll(*last_op, &context);
}; };
@ -1536,7 +1532,7 @@ TEST(QueryPlan, Distinct) {
auto x_ne = NEXPR("x", x_expr); auto x_ne = NEXPR("x", x_expr);
x_ne->MapTo(symbol_table.CreateSymbol("x_ne", true)); x_ne->MapTo(symbol_table.CreateSymbol("x_ne", true));
auto produce = MakeProduce(distinct, x_ne); auto produce = MakeProduce(distinct, x_ne);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(output.size(), results.size()); ASSERT_EQ(output.size(), results.size());
auto output_it = output.begin(); auto output_it = output.begin();
@ -1560,12 +1556,12 @@ TEST(QueryPlan, ScanAllByLabel) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Add a vertex with a label and one without. // Add a vertex with a label and one without.
auto label = dba->Label("label"); auto label = dba.Label("label");
auto labeled_vertex = dba->InsertVertex(); auto labeled_vertex = dba.InsertVertex();
labeled_vertex.add_label(label); labeled_vertex.add_label(label);
dba->InsertVertex(); dba.InsertVertex();
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (n :label) // MATCH (n :label)
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1575,7 +1571,7 @@ TEST(QueryPlan, ScanAllByLabel) {
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all_by_label.sym_)) auto output = NEXPR("n", IDENT("n")->MapTo(scan_all_by_label.sym_))
->MapTo(symbol_table.CreateSymbol("n", true)); ->MapTo(symbol_table.CreateSymbol("n", true));
auto produce = MakeProduce(scan_all_by_label.op_, output); auto produce = MakeProduce(scan_all_by_label.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), 1); ASSERT_EQ(results.size(), 1);
auto result_row = results[0]; auto result_row = results[0];
@ -1586,8 +1582,8 @@ TEST(QueryPlan, ScanAllByLabel) {
TEST(QueryPlan, ScanAllByLabelProperty) { TEST(QueryPlan, ScanAllByLabelProperty) {
database::GraphDb db; database::GraphDb db;
// Add 5 vertices with same label, but with different property values. // Add 5 vertices with same label, but with different property values.
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
// vertex property values that will be stored into the DB // vertex property values that will be stored into the DB
// clang-format off // clang-format off
std::vector<PropertyValue> values{ std::vector<PropertyValue> values{
@ -1598,15 +1594,15 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
{ {
auto dba = db.Access(); auto dba = db.Access();
for (const auto &value : values) { for (const auto &value : values) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
vertex.PropsSet(prop, value); vertex.PropsSet(prop, value);
} }
dba->Commit(); dba.Commit();
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
} }
auto dba = db.Access(); auto dba = db.Access();
ASSERT_EQ(14, CountIterable(dba->Vertices(false))); ASSERT_EQ(14, CountIterable(dba.Vertices(false)));
auto check = [&dba, label, prop](TypedValue lower, Bound::Type lower_type, auto check = [&dba, label, prop](TypedValue lower, Bound::Type lower_type,
TypedValue upper, Bound::Type upper_type, TypedValue upper, Bound::Type upper_type,
@ -1620,7 +1616,7 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_)) auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
->MapTo(symbol_table.CreateSymbol("n", true)); ->MapTo(symbol_table.CreateSymbol("n", true));
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), expected.size()); ASSERT_EQ(results.size(), expected.size());
for (size_t i = 0; i < expected.size(); i++) { for (size_t i = 0; i < expected.size(); i++) {
@ -1657,21 +1653,21 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
database::GraphDb db; database::GraphDb db;
// Add 2 vertices with same label, but with property values that cannot be // Add 2 vertices with same label, but with property values that cannot be
// compared. On the other hand, equality works fine. // compared. On the other hand, equality works fine.
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
{ {
auto dba = db.Access(); auto dba = db.Access();
auto number_vertex = dba->InsertVertex(); auto number_vertex = dba.InsertVertex();
number_vertex.add_label(label); number_vertex.add_label(label);
number_vertex.PropsSet(prop, 42); number_vertex.PropsSet(prop, 42);
auto string_vertex = dba->InsertVertex(); auto string_vertex = dba.InsertVertex();
string_vertex.add_label(label); string_vertex.add_label(label);
string_vertex.PropsSet(prop, "string"); string_vertex.PropsSet(prop, "string");
dba->Commit(); dba.Commit();
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
} }
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (n :label {prop: 42}) // MATCH (n :label {prop: 42})
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1681,7 +1677,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_)) auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
->MapTo(symbol_table.CreateSymbol("n", true)); ->MapTo(symbol_table.CreateSymbol("n", true));
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
ASSERT_EQ(results.size(), 1); ASSERT_EQ(results.size(), 1);
const auto &row = results[0]; const auto &row = results[0];
@ -1694,20 +1690,20 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
TEST(QueryPlan, ScanAllByLabelPropertyValueError) { TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
database::GraphDb db; database::GraphDb db;
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
{ {
auto dba = db.Access(); auto dba = db.Access();
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
vertex.PropsSet(prop, i); vertex.PropsSet(prop, i);
} }
dba->Commit(); dba.Commit();
} }
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (m), (n :label {prop: m}) // MATCH (m), (n :label {prop: m})
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1716,26 +1712,26 @@ TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
ident_m->MapTo(scan_all.sym_); ident_m->MapTo(scan_all.sym_);
auto scan_index = MakeScanAllByLabelPropertyValue( auto scan_index = MakeScanAllByLabelPropertyValue(
storage, symbol_table, "n", label, prop, "prop", ident_m, scan_all.op_); storage, symbol_table, "n", label, prop, "prop", ident_m, scan_all.op_);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
TEST(QueryPlan, ScanAllByLabelPropertyRangeError) { TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
database::GraphDb db; database::GraphDb db;
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
{ {
auto dba = db.Access(); auto dba = db.Access();
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
vertex.PropsSet(prop, i); vertex.PropsSet(prop, i);
} }
dba->Commit(); dba.Commit();
} }
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (m), (n :label {prop: m}) // MATCH (m), (n :label {prop: m})
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1748,7 +1744,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
storage, symbol_table, "n", label, prop, "prop", storage, symbol_table, "n", label, prop, "prop",
Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt, Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt,
scan_all.op_); scan_all.op_);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
{ {
@ -1757,7 +1753,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
storage, symbol_table, "n", label, prop, "prop", storage, symbol_table, "n", label, prop, "prop",
std::experimental::nullopt, Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt, Bound{ident_m, Bound::Type::INCLUSIVE},
scan_all.op_); scan_all.op_);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
{ {
@ -1766,7 +1762,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
storage, symbol_table, "n", label, prop, "prop", storage, symbol_table, "n", label, prop, "prop",
Bound{ident_m, Bound::Type::INCLUSIVE}, Bound{ident_m, Bound::Type::INCLUSIVE},
Bound{ident_m, Bound::Type::INCLUSIVE}, scan_all.op_); Bound{ident_m, Bound::Type::INCLUSIVE}, scan_all.op_);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException); EXPECT_THROW(PullAll(*scan_index.op_, &context), QueryRuntimeException);
} }
} }
@ -1776,20 +1772,20 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
// Add 2 vertices with the same label, but one has a property value while // Add 2 vertices with the same label, but one has a property value while
// the other does not. Checking if the value is equal to null, should // the other does not. Checking if the value is equal to null, should
// yield no results. // yield no results.
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
auto vertex_with_prop = dba->InsertVertex(); auto vertex_with_prop = dba.InsertVertex();
vertex_with_prop.add_label(label); vertex_with_prop.add_label(label);
vertex_with_prop.PropsSet(prop, 42); vertex_with_prop.PropsSet(prop, 42);
dba->Commit(); dba.Commit();
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
} }
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (n :label {prop: 42}) // MATCH (n :label {prop: 42})
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1800,7 +1796,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_)) auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
->MapTo(symbol_table.CreateSymbol("n", true)); ->MapTo(symbol_table.CreateSymbol("n", true));
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 0); EXPECT_EQ(results.size(), 0);
} }
@ -1810,20 +1806,20 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
// Add 2 vertices with the same label, but one has a property value while // Add 2 vertices with the same label, but one has a property value while
// the other does not. Checking if the value is between nulls, should // the other does not. Checking if the value is between nulls, should
// yield no results. // yield no results.
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
vertex.add_label(label); vertex.add_label(label);
auto vertex_with_prop = dba->InsertVertex(); auto vertex_with_prop = dba.InsertVertex();
vertex_with_prop.add_label(label); vertex_with_prop.add_label(label);
vertex_with_prop.PropsSet(prop, 42); vertex_with_prop.PropsSet(prop, 42);
dba->Commit(); dba.Commit();
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
} }
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(2, CountIterable(dba->Vertices(false))); EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
// MATCH (n :label) WHERE null <= n.prop < null // MATCH (n :label) WHERE null <= n.prop < null
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1835,25 +1831,25 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_)) auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
->MapTo(symbol_table.CreateSymbol("n", true)); ->MapTo(symbol_table.CreateSymbol("n", true));
auto produce = MakeProduce(scan_all.op_, output); auto produce = MakeProduce(scan_all.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
auto results = CollectProduce(*produce, &context); auto results = CollectProduce(*produce, &context);
EXPECT_EQ(results.size(), 0); EXPECT_EQ(results.size(), 0);
} }
TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) { TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
database::GraphDb db; database::GraphDb db;
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
{ {
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label); v.add_label(label);
v.PropsSet(prop, 2); v.PropsSet(prop, 2);
dba->Commit(); dba.Commit();
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
} }
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(1, CountIterable(dba->Vertices(false))); EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
@ -1869,14 +1865,14 @@ TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
auto scan_all = MakeScanAllByLabelPropertyValue( auto scan_all = MakeScanAllByLabelPropertyValue(
storage, symbol_table, "n", label, prop, "prop", x_expr, unwind); storage, symbol_table, "n", label, prop, "prop", x_expr, unwind);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(PullAll(*scan_all.op_, &context), 1); EXPECT_EQ(PullAll(*scan_all.op_, &context), 1);
} }
TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) { TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
database::GraphDb db; database::GraphDb db;
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
auto prop = db.Access()->Property("prop"); auto prop = db.Access().Property("prop");
// Insert vertices // Insert vertices
const int vertex_count = 300, vertex_prop_count = 50; const int vertex_count = 300, vertex_prop_count = 50;
@ -1884,18 +1880,18 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
for (int i = 0; i < vertex_count; ++i) { for (int i = 0; i < vertex_count; ++i) {
auto dba = db.Access(); auto dba = db.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label); v.add_label(label);
v.PropsSet(prop, i < vertex_prop_count ? prop_value1 : prop_value2); v.PropsSet(prop, i < vertex_prop_count ? prop_value1 : prop_value2);
dba->Commit(); dba.Commit();
} }
db.Access()->BuildIndex(label, prop, false); db.Access().BuildIndex(label, prop, false);
// Make sure there are `vertex_count` vertices // Make sure there are `vertex_count` vertices
{ {
auto dba = db.Access(); auto dba = db.Access();
EXPECT_EQ(vertex_count, CountIterable(dba->Vertices(false))); EXPECT_EQ(vertex_count, CountIterable(dba.Vertices(false)));
} }
// Make sure there are `vertex_prop_count` results when using index // Make sure there are `vertex_prop_count` results when using index
@ -1909,7 +1905,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
NEXPR("n", IDENT("n")->MapTo(scan_all_by_label_property_value.sym_)) NEXPR("n", IDENT("n")->MapTo(scan_all_by_label_property_value.sym_))
->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); ->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
auto produce = MakeProduce(scan_all_by_label_property_value.op_, output); auto produce = MakeProduce(scan_all_by_label_property_value.op_, output);
auto context = MakeContext(storage, symbol_table, dba.get()); auto context = MakeContext(storage, symbol_table, &dba);
EXPECT_EQ(PullAll(*produce, &context), prop_count); EXPECT_EQ(PullAll(*produce, &context), prop_count);
}; };
@ -1917,8 +1913,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
auto count_with_scan_all = [&db, &prop](int prop_value, int prop_count) { auto count_with_scan_all = [&db, &prop](int prop_value, int prop_count) {
AstStorage storage; AstStorage storage;
SymbolTable symbol_table; SymbolTable symbol_table;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto scan_all = MakeScanAll(storage, symbol_table, "n"); auto scan_all = MakeScanAll(storage, symbol_table, "n");
auto e = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_), auto e = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_),
std::make_pair("prop", prop)); std::make_pair("prop", prop));

View File

@ -18,11 +18,10 @@ using testing::UnorderedElementsAre;
namespace { namespace {
struct ExpressionPrettyPrinterTest : public ::testing::Test { struct ExpressionPrettyPrinterTest : public ::testing::Test {
ExpressionPrettyPrinterTest() : pdba{db.Access()}, dba{*pdba} {} ExpressionPrettyPrinterTest() : dba{db.Access()} {}
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> pdba; database::GraphDbAccessor dba;
database::GraphDbAccessor &dba;
AstStorage storage; AstStorage storage;
}; };

View File

@ -16,8 +16,7 @@ using namespace query;
class TestSymbolGenerator : public ::testing::Test { class TestSymbolGenerator : public ::testing::Test {
protected: protected:
database::GraphDb db; database::GraphDb db;
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()}; database::GraphDbAccessor dba{db.Access()};
database::GraphDbAccessor &dba{*dba_ptr};
AstStorage storage; AstStorage storage;
}; };

View File

@ -82,17 +82,17 @@ TEST(TestVariableStartPlanner, MatchReturn) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Make a graph (v1) -[:r]-> (v2) // Make a graph (v1) -[:r]-> (v2)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
dba->InsertEdge(v1, v2, dba->EdgeType("r")); dba.InsertEdge(v1, v2, dba.EdgeType("r"));
dba->AdvanceCommand(); dba.AdvanceCommand();
// Test MATCH (n) -[r]-> (m) RETURN n // Test MATCH (n) -[r]-> (m) RETURN n
AstStorage storage; AstStorage storage;
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m"))), MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m"))),
RETURN("n"))); RETURN("n")));
// We have 2 nodes `n` and `m` from which we could start, so expect 2 plans. // We have 2 nodes `n` and `m` from which we could start, so expect 2 plans.
CheckPlansProduce(2, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
// We expect to produce only a single (v1) node. // We expect to produce only a single (v1) node.
AssertRows(results, {{v1}}); AssertRows(results, {{v1}});
}); });
@ -102,12 +102,12 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3) // Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
dba->InsertEdge(v1, v2, dba->EdgeType("r")); dba.InsertEdge(v1, v2, dba.EdgeType("r"));
dba->InsertEdge(v2, v3, dba->EdgeType("r")); dba.InsertEdge(v2, v3, dba.EdgeType("r"));
dba->AdvanceCommand(); dba.AdvanceCommand();
{ {
// Test `MATCH (n) -[r]-> (m) -[e]-> (l) RETURN n` // Test `MATCH (n) -[r]-> (m) -[e]-> (l) RETURN n`
AstStorage storage; AstStorage storage;
@ -116,7 +116,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
EDGE("e", Direction::OUT), NODE("l"))), EDGE("e", Direction::OUT), NODE("l"))),
RETURN("n"))); RETURN("n")));
// We have 3 nodes: `n`, `m` and `l` from which we could start. // We have 3 nodes: `n`, `m` and `l` from which we could start.
CheckPlansProduce(3, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
// We expect to produce only a single (v1) node. // We expect to produce only a single (v1) node.
AssertRows(results, {{v1}}); AssertRows(results, {{v1}});
}); });
@ -128,7 +128,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m")), MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m")),
PATTERN(NODE("m"), EDGE("e", Direction::OUT), NODE("l"))), PATTERN(NODE("m"), EDGE("e", Direction::OUT), NODE("l"))),
RETURN("n"))); RETURN("n")));
CheckPlansProduce(3, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{v1}}); AssertRows(results, {{v1}});
}); });
} }
@ -138,12 +138,12 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3) // Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
dba->InsertEdge(v1, v2, dba->EdgeType("r")); dba.InsertEdge(v1, v2, dba.EdgeType("r"));
dba->InsertEdge(v2, v3, dba->EdgeType("r")); dba.InsertEdge(v2, v3, dba.EdgeType("r"));
dba->AdvanceCommand(); dba.AdvanceCommand();
// Test MATCH (n) -[r]-> (m) OPTIONAL MATCH (m) -[e]-> (l) RETURN n, l // Test MATCH (n) -[r]-> (m) OPTIONAL MATCH (m) -[e]-> (l) RETURN n, l
AstStorage storage; AstStorage storage;
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
@ -152,7 +152,7 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
RETURN("n", "l"))); RETURN("n", "l")));
// We have 2 nodes `n` and `m` from which we could start the MATCH, and 2 // We have 2 nodes `n` and `m` from which we could start the MATCH, and 2
// nodes for OPTIONAL MATCH. This should produce 2 * 2 plans. // nodes for OPTIONAL MATCH. This should produce 2 * 2 plans.
CheckPlansProduce(4, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(4, query, storage, &dba, [&](const auto &results) {
// We expect to produce 2 rows: // We expect to produce 2 rows:
// * (v1), (v3) // * (v1), (v3)
// * (v2), null // * (v2), null
@ -164,12 +164,12 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Graph (v1) -[:r]-> (v2) // Graph (v1) -[:r]-> (v2)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto r_type_name = "r"; auto r_type_name = "r";
auto r_type = dba->EdgeType(r_type_name); auto r_type = dba.EdgeType(r_type_name);
dba->InsertEdge(v1, v2, r_type); dba.InsertEdge(v1, v2, r_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
// Test MATCH (n) -[r]-> (m) OPTIONAL MATCH (m) -[e]-> (l) // Test MATCH (n) -[r]-> (m) OPTIONAL MATCH (m) -[e]-> (l)
// MERGE (u) -[q:r]-> (v) RETURN n, m, l, u, v // MERGE (u) -[q:r]-> (v) RETURN n, m, l, u, v
AstStorage storage; AstStorage storage;
@ -181,7 +181,7 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
RETURN("n", "m", "l", "u", "v"))); RETURN("n", "m", "l", "u", "v")));
// Since MATCH, OPTIONAL MATCH and MERGE each have 2 nodes from which we can // Since MATCH, OPTIONAL MATCH and MERGE each have 2 nodes from which we can
// start, we generate 2 * 2 * 2 plans. // start, we generate 2 * 2 * 2 plans.
CheckPlansProduce(8, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(8, query, storage, &dba, [&](const auto &results) {
// We expect to produce a single row: (v1), (v2), null, (v1), (v2) // We expect to produce a single row: (v1), (v2), null, (v1), (v2)
AssertRows(results, {{v1, v2, TypedValue::Null, v1, v2}}); AssertRows(results, {{v1, v2, TypedValue::Null, v1, v2}});
}); });
@ -191,10 +191,10 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Graph (v1) -[:r]-> (v2) // Graph (v1) -[:r]-> (v2)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
dba->InsertEdge(v1, v2, dba->EdgeType("r")); dba.InsertEdge(v1, v2, dba.EdgeType("r"));
dba->AdvanceCommand(); dba.AdvanceCommand();
// Test MATCH (n) -[r]-> (m) WITH n MATCH (m) -[r]-> (l) RETURN n, m, l // Test MATCH (n) -[r]-> (m) WITH n MATCH (m) -[r]-> (l) RETURN n, m, l
AstStorage storage; AstStorage storage;
auto *query = QUERY(SINGLE_QUERY( auto *query = QUERY(SINGLE_QUERY(
@ -204,7 +204,7 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
RETURN("n", "m", "l"))); RETURN("n", "m", "l")));
// We can start from 2 nodes in each match. Since WITH separates query parts, // We can start from 2 nodes in each match. Since WITH separates query parts,
// we expect to get 2 plans for each, which totals 2 * 2. // we expect to get 2 plans for each, which totals 2 * 2.
CheckPlansProduce(4, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(4, query, storage, &dba, [&](const auto &results) {
// We expect to produce a single row: (v1), (v1), (v2) // We expect to produce a single row: (v1), (v1), (v2)
AssertRows(results, {{v1, v1, v2}}); AssertRows(results, {{v1, v1, v2}});
}); });
@ -214,12 +214,12 @@ TEST(TestVariableStartPlanner, MatchVariableExpand) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
// Graph (v1) -[:r1]-> (v2) -[:r2]-> (v3) // Graph (v1) -[:r1]-> (v2) -[:r2]-> (v3)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto r1 = dba->InsertEdge(v1, v2, dba->EdgeType("r1")); auto r1 = dba.InsertEdge(v1, v2, dba.EdgeType("r1"));
auto r2 = dba->InsertEdge(v2, v3, dba->EdgeType("r2")); auto r2 = dba.InsertEdge(v2, v3, dba.EdgeType("r2"));
dba->AdvanceCommand(); dba.AdvanceCommand();
// Test MATCH (n) -[r*]-> (m) RETURN r // Test MATCH (n) -[r*]-> (m) RETURN r
AstStorage storage; AstStorage storage;
auto edge = EDGE_VARIABLE("r", Type::DEPTH_FIRST, Direction::OUT); auto edge = EDGE_VARIABLE("r", Type::DEPTH_FIRST, Direction::OUT);
@ -229,15 +229,14 @@ TEST(TestVariableStartPlanner, MatchVariableExpand) {
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1] TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1]
TypedValue r2_list(std::vector<TypedValue>{r2}); // [r2] TypedValue r2_list(std::vector<TypedValue>{r2}); // [r2]
TypedValue r1_r2_list(std::vector<TypedValue>{r1, r2}); // [r1, r2] TypedValue r1_r2_list(std::vector<TypedValue>{r1, r2}); // [r1, r2]
CheckPlansProduce(2, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{r1_list}, {r2_list}, {r1_r2_list}}); AssertRows(results, {{r1_list}, {r2_list}, {r1_r2_list}});
}); });
} }
TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) { TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto id = dba.Property("id"); auto id = dba.Property("id");
// Graph (v1 {id:1}) -[:r1]-> (v2 {id: 2}) -[:r2]-> (v3 {id: 3}) // Graph (v1 {id:1}) -[:r1]-> (v2 {id: 2}) -[:r2]-> (v3 {id: 3})
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();
@ -266,15 +265,15 @@ TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
TEST(TestVariableStartPlanner, MatchVariableExpandBoth) { TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto id = dba->Property("id"); auto id = dba.Property("id");
// Graph (v1 {id:1}) -[:r1]-> (v2) -[:r2]-> (v3) // Graph (v1 {id:1}) -[:r1]-> (v2) -[:r2]-> (v3)
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.PropsSet(id, 1); v1.PropsSet(id, 1);
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto r1 = dba->InsertEdge(v1, v2, dba->EdgeType("r1")); auto r1 = dba.InsertEdge(v1, v2, dba.EdgeType("r1"));
auto r2 = dba->InsertEdge(v2, v3, dba->EdgeType("r2")); auto r2 = dba.InsertEdge(v2, v3, dba.EdgeType("r2"));
dba->AdvanceCommand(); dba.AdvanceCommand();
// Test MATCH (n {id:1}) -[r*]- (m) RETURN r // Test MATCH (n {id:1}) -[r*]- (m) RETURN r
AstStorage storage; AstStorage storage;
auto edge = EDGE_VARIABLE("r", Type::DEPTH_FIRST, Direction::BOTH); auto edge = EDGE_VARIABLE("r", Type::DEPTH_FIRST, Direction::BOTH);
@ -285,15 +284,14 @@ TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
// We expect to get a single column with the following rows: // We expect to get a single column with the following rows:
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1] TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1]
TypedValue r1_r2_list(std::vector<TypedValue>{r1, r2}); // [r1, r2] TypedValue r1_r2_list(std::vector<TypedValue>{r1, r2}); // [r1, r2]
CheckPlansProduce(2, query, storage, dba.get(), [&](const auto &results) { CheckPlansProduce(2, query, storage, &dba, [&](const auto &results) {
AssertRows(results, {{r1_list}, {r1_r2_list}}); AssertRows(results, {{r1_list}, {r1_r2_list}});
}); });
} }
TEST(TestVariableStartPlanner, MatchBfs) { TEST(TestVariableStartPlanner, MatchBfs) {
database::GraphDb db; database::GraphDb db;
auto dba_ptr = db.Access(); auto dba = db.Access();
auto &dba = *dba_ptr;
auto id = dba.Property("id"); auto id = dba.Property("id");
// Graph (v1 {id:1}) -[:r1]-> (v2 {id: 2}) -[:r2]-> (v3 {id: 3}) // Graph (v1 {id:1}) -[:r1]-> (v2 {id: 2}) -[:r2]-> (v3 {id: 3})
auto v1 = dba.InsertVertex(); auto v1 = dba.InsertVertex();

View File

@ -15,11 +15,11 @@ TEST(RecordAccessor, Properties) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
auto &properties = vertex.Properties(); auto &properties = vertex.Properties();
auto property = dba->Property("PropName"); auto property = dba.Property("PropName");
auto property_other = dba->Property("Other"); auto property_other = dba.Property("Other");
EXPECT_EQ(vertex.PropsAt(property).type(), PropertyValue::Type::Null); EXPECT_EQ(vertex.PropsAt(property).type(), PropertyValue::Type::Null);
vertex.PropsSet(property, 42); vertex.PropsSet(property, 42);
@ -37,24 +37,24 @@ TEST(RecordAccessor, DbAccessor) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->InsertVertex(); auto vertex = dba.InsertVertex();
const auto &const_vertex_dba = vertex.db_accessor(); const auto &const_vertex_dba = vertex.db_accessor();
EXPECT_EQ(dba.get(), &const_vertex_dba); EXPECT_EQ(&dba, &const_vertex_dba);
auto &vertex_dba = vertex.db_accessor(); auto &vertex_dba = vertex.db_accessor();
EXPECT_EQ(dba.get(), &vertex_dba); EXPECT_EQ(&dba, &vertex_dba);
} }
TEST(RecordAccessor, RecordEquality) { TEST(RecordAccessor, RecordEquality) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
EXPECT_EQ(v1, v1); EXPECT_EQ(v1, v1);
EXPECT_NE(v1, v2); EXPECT_NE(v1, v2);
auto e1 = dba->InsertEdge(v1, v2, dba->EdgeType("type")); auto e1 = dba.InsertEdge(v1, v2, dba.EdgeType("type"));
auto e2 = dba->InsertEdge(v1, v2, dba->EdgeType("type")); auto e2 = dba.InsertEdge(v1, v2, dba.EdgeType("type"));
EXPECT_EQ(e1, e1); EXPECT_EQ(e1, e1);
EXPECT_NE(e1, e2); EXPECT_NE(e1, e2);
} }
@ -65,16 +65,16 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
// test both Switches work on new record // test both Switches work on new record
{ {
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.SwitchOld(); v1.SwitchOld();
v1.SwitchNew(); v1.SwitchNew();
dba->Commit(); dba.Commit();
} }
// test both Switches work on existing record // test both Switches work on existing record
{ {
auto dba = db.Access(); auto dba = db.Access();
auto v1 = *dba->Vertices(false).begin(); auto v1 = *dba.Vertices(false).begin();
v1.SwitchOld(); v1.SwitchOld();
v1.SwitchNew(); v1.SwitchNew();
} }
@ -82,8 +82,8 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
// ensure switch exposes the right data // ensure switch exposes the right data
{ {
auto dba = db.Access(); auto dba = db.Access();
auto label = dba->Label("label"); auto label = dba.Label("label");
auto v1 = *dba->Vertices(false).begin(); auto v1 = *dba.Vertices(false).begin();
EXPECT_FALSE(v1.has_label(label)); // old record EXPECT_FALSE(v1.has_label(label)); // old record
v1.add_label(label); // modifying data does not switch to new v1.add_label(label); // modifying data does not switch to new
@ -97,26 +97,26 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
TEST(RecordAccessor, Reconstruct) { TEST(RecordAccessor, Reconstruct) {
database::GraphDb db; database::GraphDb db;
auto label = db.Access()->Label("label"); auto label = db.Access().Label("label");
{ {
// we must operate on an old vertex // we must operate on an old vertex
// because otherwise we only have new // because otherwise we only have new
// so create a vertex and commit it // so create a vertex and commit it
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(); dba.InsertVertex();
dba->Commit(); dba.Commit();
} }
// ensure we don't have label set // ensure we don't have label set
auto dba = db.Access(); auto dba = db.Access();
auto v1 = *dba->Vertices(false).begin(); auto v1 = *dba.Vertices(false).begin();
v1.SwitchNew(); v1.SwitchNew();
EXPECT_FALSE(v1.has_label(label)); EXPECT_FALSE(v1.has_label(label));
{ {
// update the record through a different accessor // update the record through a different accessor
auto v1_other_accessor = *dba->Vertices(false).begin(); auto v1_other_accessor = *dba.Vertices(false).begin();
v1_other_accessor.add_label(label); v1_other_accessor.add_label(label);
EXPECT_FALSE(v1.has_label(label)); EXPECT_FALSE(v1.has_label(label));
v1_other_accessor.SwitchNew(); v1_other_accessor.SwitchNew();
@ -132,13 +132,13 @@ TEST(RecordAccessor, Reconstruct) {
TEST(RecordAccessor, VertexLabels) { TEST(RecordAccessor, VertexLabels) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto &labels = v1.labels(); auto &labels = v1.labels();
EXPECT_EQ(v1.labels().size(), 0); EXPECT_EQ(v1.labels().size(), 0);
storage::Label l1 = dba->Label("label1"); storage::Label l1 = dba.Label("label1");
storage::Label l2 = dba->Label("label2"); storage::Label l2 = dba.Label("label2");
// adding labels // adding labels
EXPECT_FALSE(v1.has_label(l1)); EXPECT_FALSE(v1.has_label(l1));
@ -158,7 +158,7 @@ TEST(RecordAccessor, VertexLabels) {
EXPECT_EQ(labels.size(), 2); EXPECT_EQ(labels.size(), 2);
// removing labels // removing labels
storage::Label l3 = dba->Label("label3"); storage::Label l3 = dba.Label("label3");
v1.remove_label(l3); v1.remove_label(l3);
EXPECT_EQ(labels.size(), 2); EXPECT_EQ(labels.size(), 2);
@ -173,13 +173,13 @@ TEST(RecordAccessor, VertexLabels) {
TEST(RecordAccessor, EdgeType) { TEST(RecordAccessor, EdgeType) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
storage::EdgeType likes = dba->EdgeType("likes"); storage::EdgeType likes = dba.EdgeType("likes");
storage::EdgeType hates = dba->EdgeType("hates"); storage::EdgeType hates = dba.EdgeType("hates");
auto edge = dba->InsertEdge(v1, v2, likes); auto edge = dba.InsertEdge(v1, v2, likes);
EXPECT_EQ(edge.EdgeType(), likes); EXPECT_EQ(edge.EdgeType(), likes);
EXPECT_NE(edge.EdgeType(), hates); EXPECT_NE(edge.EdgeType(), hates);
} }
@ -187,23 +187,23 @@ TEST(RecordAccessor, EdgeType) {
TEST(RecordAccessor, EdgeIsCycle) { TEST(RecordAccessor, EdgeIsCycle) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto likes = dba->EdgeType("edge_type"); auto likes = dba.EdgeType("edge_type");
EXPECT_TRUE(dba->InsertEdge(v1, v1, likes).is_cycle()); EXPECT_TRUE(dba.InsertEdge(v1, v1, likes).is_cycle());
EXPECT_TRUE(dba->InsertEdge(v2, v2, likes).is_cycle()); EXPECT_TRUE(dba.InsertEdge(v2, v2, likes).is_cycle());
EXPECT_FALSE(dba->InsertEdge(v1, v2, likes).is_cycle()); EXPECT_FALSE(dba.InsertEdge(v1, v2, likes).is_cycle());
EXPECT_FALSE(dba->InsertEdge(v2, v1, likes).is_cycle()); EXPECT_FALSE(dba.InsertEdge(v2, v1, likes).is_cycle());
} }
TEST(RecordAccessor, VertexEdgeConnections) { TEST(RecordAccessor, VertexEdgeConnections) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto edge = dba->InsertEdge(v1, v2, dba->EdgeType("likes")); auto edge = dba.InsertEdge(v1, v2, dba.EdgeType("likes"));
dba->AdvanceCommand(); dba.AdvanceCommand();
EXPECT_EQ(edge.from(), v1); EXPECT_EQ(edge.from(), v1);
EXPECT_NE(edge.from(), v2); EXPECT_NE(edge.from(), v2);
@ -232,16 +232,16 @@ TEST(RecordAccessor, VertexEdgeConnections) {
TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) { TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto edge_type = dba->EdgeType("edge type"); auto edge_type = dba.EdgeType("edge type");
auto e12 = dba->InsertEdge(v1, v2, edge_type); auto e12 = dba.InsertEdge(v1, v2, edge_type);
auto e22 = dba->InsertEdge(v2, v2, edge_type); auto e22 = dba.InsertEdge(v2, v2, edge_type);
auto e23a = dba->InsertEdge(v2, v3, edge_type); auto e23a = dba.InsertEdge(v2, v3, edge_type);
auto e23b = dba->InsertEdge(v2, v3, edge_type); auto e23b = dba.InsertEdge(v2, v3, edge_type);
auto e32 = dba->InsertEdge(v3, v2, edge_type); auto e32 = dba.InsertEdge(v3, v2, edge_type);
dba->AdvanceCommand(); dba.AdvanceCommand();
TEST_EDGE_ITERABLE(v1.out(v1)); TEST_EDGE_ITERABLE(v1.out(v1));
TEST_EDGE_ITERABLE(v1.out(v2), {e12}); TEST_EDGE_ITERABLE(v1.out(v2), {e12});
@ -267,16 +267,16 @@ TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) {
TEST(RecordAccessor, VertexEdgeConnectionsWithEdgeType) { TEST(RecordAccessor, VertexEdgeConnectionsWithEdgeType) {
database::GraphDb db; database::GraphDb db;
auto dba = db.Access(); auto dba = db.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto a = dba->EdgeType("a"); auto a = dba.EdgeType("a");
auto b = dba->EdgeType("b"); auto b = dba.EdgeType("b");
auto c = dba->EdgeType("c"); auto c = dba.EdgeType("c");
auto ea = dba->InsertEdge(v1, v2, a); auto ea = dba.InsertEdge(v1, v2, a);
auto eb_1 = dba->InsertEdge(v2, v1, b); auto eb_1 = dba.InsertEdge(v2, v1, b);
auto eb_2 = dba->InsertEdge(v2, v1, b); auto eb_2 = dba.InsertEdge(v2, v1, b);
auto ec = dba->InsertEdge(v1, v2, c); auto ec = dba.InsertEdge(v1, v2, c);
dba->AdvanceCommand(); dba.AdvanceCommand();
TEST_EDGE_ITERABLE(v1.in(), {eb_1, eb_2}); TEST_EDGE_ITERABLE(v1.in(), {eb_1, eb_2});
TEST_EDGE_ITERABLE(v2.in(), {ea, ec}); TEST_EDGE_ITERABLE(v2.in(), {ea, ec});

View File

@ -11,13 +11,13 @@ TEST(StateDelta, CreateVertex) {
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = auto delta =
database::StateDelta::CreateVertex(dba->transaction_id(), gid0); database::StateDelta::CreateVertex(dba.transaction_id(), gid0);
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->FindVertexOptional(gid0, false); auto vertex = dba.FindVertexOptional(gid0, false);
EXPECT_TRUE(vertex); EXPECT_TRUE(vertex);
EXPECT_EQ(vertex->CypherId(), 0); EXPECT_EQ(vertex->CypherId(), 0);
} }
@ -29,19 +29,19 @@ TEST(StateDelta, RemoveVertex) {
auto gid0 = generator.Next(); auto gid0 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(gid0); dba.InsertVertex(gid0);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = auto delta =
database::StateDelta::RemoveVertex(dba->transaction_id(), gid0, true); database::StateDelta::RemoveVertex(dba.transaction_id(), gid0, true);
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->FindVertexOptional(gid0, false); auto vertex = dba.FindVertexOptional(gid0, false);
EXPECT_FALSE(vertex); EXPECT_FALSE(vertex);
} }
} }
@ -54,21 +54,21 @@ TEST(StateDelta, CreateEdge) {
auto gid2 = generator.Next(); auto gid2 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(gid0); dba.InsertVertex(gid0);
dba->InsertVertex(gid1); dba.InsertVertex(gid1);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = auto delta =
database::StateDelta::CreateEdge(dba->transaction_id(), gid2, gid0, database::StateDelta::CreateEdge(dba.transaction_id(), gid2, gid0,
gid1, dba->EdgeType("edge"), "edge"); gid1, dba.EdgeType("edge"), "edge");
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto edge = dba->FindEdgeOptional(gid2, false); auto edge = dba.FindEdgeOptional(gid2, false);
EXPECT_TRUE(edge); EXPECT_TRUE(edge);
} }
} }
@ -81,20 +81,20 @@ TEST(StateDelta, RemoveEdge) {
auto gid2 = generator.Next(); auto gid2 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
auto v0 = dba->InsertVertex(gid0); auto v0 = dba.InsertVertex(gid0);
auto v1 = dba->InsertVertex(gid1); auto v1 = dba.InsertVertex(gid1);
dba->InsertEdge(v0, v1, dba->EdgeType("edge"), gid2); dba.InsertEdge(v0, v1, dba.EdgeType("edge"), gid2);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = database::StateDelta::RemoveEdge(dba->transaction_id(), gid2); auto delta = database::StateDelta::RemoveEdge(dba.transaction_id(), gid2);
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto edge = dba->FindEdgeOptional(gid2, false); auto edge = dba.FindEdgeOptional(gid2, false);
EXPECT_FALSE(edge); EXPECT_FALSE(edge);
} }
} }
@ -105,23 +105,23 @@ TEST(StateDelta, AddLabel) {
auto gid0 = generator.Next(); auto gid0 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(gid0); dba.InsertVertex(gid0);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = database::StateDelta::AddLabel(dba->transaction_id(), gid0, auto delta = database::StateDelta::AddLabel(dba.transaction_id(), gid0,
dba->Label("label"), "label"); dba.Label("label"), "label");
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->FindVertexOptional(gid0, false); auto vertex = dba.FindVertexOptional(gid0, false);
EXPECT_TRUE(vertex); EXPECT_TRUE(vertex);
auto labels = vertex->labels(); auto labels = vertex->labels();
EXPECT_EQ(labels.size(), 1); EXPECT_EQ(labels.size(), 1);
EXPECT_EQ(labels[0], dba->Label("label")); EXPECT_EQ(labels[0], dba.Label("label"));
} }
} }
@ -131,20 +131,20 @@ TEST(StateDelta, RemoveLabel) {
auto gid0 = generator.Next(); auto gid0 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->InsertVertex(gid0); auto vertex = dba.InsertVertex(gid0);
vertex.add_label(dba->Label("label")); vertex.add_label(dba.Label("label"));
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = database::StateDelta::RemoveLabel( auto delta = database::StateDelta::RemoveLabel(
dba->transaction_id(), gid0, dba->Label("label"), "label"); dba.transaction_id(), gid0, dba.Label("label"), "label");
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->FindVertexOptional(gid0, false); auto vertex = dba.FindVertexOptional(gid0, false);
EXPECT_TRUE(vertex); EXPECT_TRUE(vertex);
auto labels = vertex->labels(); auto labels = vertex->labels();
EXPECT_EQ(labels.size(), 0); EXPECT_EQ(labels.size(), 0);
@ -157,22 +157,22 @@ TEST(StateDelta, SetPropertyVertex) {
auto gid0 = generator.Next(); auto gid0 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
dba->InsertVertex(gid0); dba.InsertVertex(gid0);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = database::StateDelta::PropsSetVertex( auto delta = database::StateDelta::PropsSetVertex(
dba->transaction_id(), gid0, dba->Property("property"), "property", dba.transaction_id(), gid0, dba.Property("property"), "property",
PropertyValue(2212)); PropertyValue(2212));
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto vertex = dba->FindVertexOptional(gid0, false); auto vertex = dba.FindVertexOptional(gid0, false);
EXPECT_TRUE(vertex); EXPECT_TRUE(vertex);
auto prop = vertex->PropsAt(dba->Property("property")); auto prop = vertex->PropsAt(dba.Property("property"));
EXPECT_EQ(prop.Value<int64_t>(), 2212); EXPECT_EQ(prop.Value<int64_t>(), 2212);
} }
} }
@ -185,24 +185,24 @@ TEST(StateDelta, SetPropertyEdge) {
auto gid2 = generator.Next(); auto gid2 = generator.Next();
{ {
auto dba = db.Access(); auto dba = db.Access();
auto v0 = dba->InsertVertex(gid0); auto v0 = dba.InsertVertex(gid0);
auto v1 = dba->InsertVertex(gid1); auto v1 = dba.InsertVertex(gid1);
dba->InsertEdge(v0, v1, dba->EdgeType("edge"), gid2); dba.InsertEdge(v0, v1, dba.EdgeType("edge"), gid2);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto delta = database::StateDelta::PropsSetEdge( auto delta = database::StateDelta::PropsSetEdge(
dba->transaction_id(), gid2, dba->Property("property"), "property", dba.transaction_id(), gid2, dba.Property("property"), "property",
PropertyValue(2212)); PropertyValue(2212));
delta.Apply(*dba); delta.Apply(dba);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db.Access(); auto dba = db.Access();
auto edge = dba->FindEdgeOptional(gid2, false); auto edge = dba.FindEdgeOptional(gid2, false);
EXPECT_TRUE(edge); EXPECT_TRUE(edge);
auto prop = edge->PropsAt(dba->Property("property")); auto prop = edge->PropsAt(dba.Property("property"));
EXPECT_EQ(prop.Value<int64_t>(), 2212); EXPECT_EQ(prop.Value<int64_t>(), 2212);
} }
} }

View File

@ -20,9 +20,9 @@ TEST_F(StatTest, CountTest1) {
COMPARE(stat, 0, 0, 0); COMPARE(stat, 0, 0, 0);
auto dba = db_.Access(); auto dba = db_.Access();
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
dba->InsertVertex(); dba.InsertVertex();
COMPARE(stat, 0, 0, 0); COMPARE(stat, 0, 0, 0);
db_.RefreshStat(); db_.RefreshStat();
@ -34,31 +34,31 @@ TEST_F(StatTest, CountTest2) {
COMPARE(stat, 0, 0, 0); COMPARE(stat, 0, 0, 0);
auto dba = db_.Access(); auto dba = db_.Access();
auto type = dba->EdgeType("edge"); auto type = dba.EdgeType("edge");
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
auto v3 = dba->InsertVertex(); auto v3 = dba.InsertVertex();
auto v4 = dba->InsertVertex(); auto v4 = dba.InsertVertex();
dba->InsertEdge(v1, v2, type); dba.InsertEdge(v1, v2, type);
dba->InsertEdge(v2, v2, type); dba.InsertEdge(v2, v2, type);
dba->InsertEdge(v3, v2, type); dba.InsertEdge(v3, v2, type);
dba->InsertEdge(v4, v2, type); dba.InsertEdge(v4, v2, type);
dba->InsertEdge(v1, v3, type); dba.InsertEdge(v1, v3, type);
COMPARE(stat, 0, 0, 0); COMPARE(stat, 0, 0, 0);
db_.RefreshStat(); db_.RefreshStat();
COMPARE(stat, 4, 5, 2.5); COMPARE(stat, 4, 5, 2.5);
dba->Commit(); dba.Commit();
auto dba1 = db_.Access(); auto dba1 = db_.Access();
auto v22 = dba1->FindVertex(v2.gid(), true); auto v22 = dba1.FindVertex(v2.gid(), true);
dba1->DetachRemoveVertex(v22); dba1.DetachRemoveVertex(v22);
db_.RefreshStat(); db_.RefreshStat();
COMPARE(stat, 4, 5, 2.5); COMPARE(stat, 4, 5, 2.5);
dba1->Commit(); dba1.Commit();
db_.CollectGarbage(); db_.CollectGarbage();
db_.RefreshStat(); db_.RefreshStat();
COMPARE(stat, 3, 1, 2.0 / 3); COMPARE(stat, 3, 1, 2.0 / 3);

View File

@ -19,7 +19,7 @@ class AllTypesFixture : public testing::Test {
protected: protected:
std::vector<TypedValue> values_; std::vector<TypedValue> values_;
database::GraphDb db_; database::GraphDb db_;
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()}; database::GraphDbAccessor dba_{db_.Access()};
void SetUp() override { void SetUp() override {
values_.emplace_back(TypedValue::Null); values_.emplace_back(TypedValue::Null);
@ -35,11 +35,11 @@ class AllTypesFixture : public testing::Test {
{"c", 42}, {"c", 42},
{"d", 0.5}, {"d", 0.5},
{"e", TypedValue::Null}}); {"e", TypedValue::Null}});
auto vertex = dba_->InsertVertex(); auto vertex = dba_.InsertVertex();
values_.emplace_back(vertex); values_.emplace_back(vertex);
values_.emplace_back( values_.emplace_back(
dba_->InsertEdge(vertex, vertex, dba_->EdgeType("et"))); dba_.InsertEdge(vertex, vertex, dba_.EdgeType("et")));
values_.emplace_back(query::Path(dba_->InsertVertex())); values_.emplace_back(query::Path(dba_.InsertVertex()));
} }
}; };

View File

@ -11,13 +11,13 @@ class UniqueLabelPropertiesTest : public ::testing::Test {
public: public:
void SetUp() override { void SetUp() override {
auto dba = db_.AccessBlocking(); auto dba = db_.AccessBlocking();
label_ = dba->Label("label"); label_ = dba.Label("label");
property1_ = dba->Property("property1"); property1_ = dba.Property("property1");
property2_ = dba->Property("property2"); property2_ = dba.Property("property2");
property3_ = dba->Property("property3"); property3_ = dba.Property("property3");
constraint_.AddConstraint(label_, {property1_, property2_, property3_}, constraint_.AddConstraint(label_, {property1_, property2_, property3_},
dba->transaction()); dba.transaction());
dba->Commit(); dba.Commit();
} }
database::GraphDb db_; database::GraphDb db_;
@ -40,12 +40,12 @@ TEST_F(UniqueLabelPropertiesTest, BuildDrop) {
constraint_.Exists(label_, {property1_, property2_, property3_})); constraint_.Exists(label_, {property1_, property2_, property3_}));
EXPECT_FALSE( EXPECT_FALSE(
constraint_.Exists(label_, {property1_, property2_})); constraint_.Exists(label_, {property1_, property2_}));
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.AccessBlocking(); auto dba = db_.AccessBlocking();
constraint_.RemoveConstraint(label_, {property2_, property1_, property3_}); constraint_.RemoveConstraint(label_, {property2_, property1_, property3_});
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
@ -53,129 +53,129 @@ TEST_F(UniqueLabelPropertiesTest, BuildDrop) {
constraint_.Exists(label_, {property2_, property1_, property3_})); constraint_.Exists(label_, {property2_, property1_, property3_}));
EXPECT_FALSE( EXPECT_FALSE(
constraint_.Exists(label_, {property1_, property2_, property3_})); constraint_.Exists(label_, {property1_, property2_, property3_}));
dba->Commit(); dba.Commit();
} }
} }
TEST_F(UniqueLabelPropertiesTest, BuildWithViolation) { TEST_F(UniqueLabelPropertiesTest, BuildWithViolation) {
auto dba1 = db_.Access(); auto dba1 = db_.Access();
auto v1 = dba1->InsertVertex(); auto v1 = dba1.InsertVertex();
v1.add_label(label_); v1.add_label(label_);
v1.PropsSet(property1_, value1_); v1.PropsSet(property1_, value1_);
v1.PropsSet(property2_, value2_); v1.PropsSet(property2_, value2_);
v1.PropsSet(property3_, value3_); v1.PropsSet(property3_, value3_);
auto v2 = dba1->InsertVertex(); auto v2 = dba1.InsertVertex();
v2.add_label(label_); v2.add_label(label_);
v2.PropsSet(property1_, value1_); v2.PropsSet(property1_, value1_);
v2.PropsSet(property3_, value3_); v2.PropsSet(property3_, value3_);
auto v3 = dba1->InsertVertex(); auto v3 = dba1.InsertVertex();
v3.add_label(label_); v3.add_label(label_);
v3.PropsSet(property3_, value3_); v3.PropsSet(property3_, value3_);
v3.PropsSet(property1_, value1_); v3.PropsSet(property1_, value1_);
v3.PropsSet(property2_, value2_); v3.PropsSet(property2_, value2_);
dba1->Commit(); dba1.Commit();
auto dba2 = db_.Access(); auto dba2 = db_.Access();
auto v4 = dba2->FindVertex(v1.gid(), false); auto v4 = dba2.FindVertex(v1.gid(), false);
auto v5 = dba2->FindVertex(v2.gid(), false); auto v5 = dba2.FindVertex(v2.gid(), false);
auto v6 = dba2->FindVertex(v3.gid(), false); auto v6 = dba2.FindVertex(v3.gid(), false);
constraint_.UpdateOnAddLabel(label_, v4, dba2->transaction()); constraint_.UpdateOnAddLabel(label_, v4, dba2.transaction());
constraint_.UpdateOnAddLabel(label_, v5, dba2->transaction()); constraint_.UpdateOnAddLabel(label_, v5, dba2.transaction());
EXPECT_THROW(constraint_.UpdateOnAddLabel(label_, v6, dba2->transaction()), EXPECT_THROW(constraint_.UpdateOnAddLabel(label_, v6, dba2.transaction()),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
TEST_F(UniqueLabelPropertiesTest, InsertInsert) { TEST_F(UniqueLabelPropertiesTest, InsertInsert) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property1_, value1_, v, EXPECT_THROW(constraint_.UpdateOnAddProperty(property1_, value1_, v,
dba->transaction()), dba.transaction()),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
dba->Commit(); dba.Commit();
} }
} }
TEST_F(UniqueLabelPropertiesTest, InsertInsertDiffValues) { TEST_F(UniqueLabelPropertiesTest, InsertInsertDiffValues) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
PropertyValue other3("Some other value 3"); PropertyValue other3("Some other value 3");
v.PropsSet(property3_, other3); v.PropsSet(property3_, other3);
constraint_.UpdateOnAddProperty(property3_, other3, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, other3, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
PropertyValue other2("Some other value 2"); PropertyValue other2("Some other value 2");
v.PropsSet(property2_, other2); v.PropsSet(property2_, other2);
constraint_.UpdateOnAddProperty(property2_, other2, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, other2, v, dba.transaction());
PropertyValue other1("Some other value 1"); PropertyValue other1("Some other value 1");
v.PropsSet(property1_, other1); v.PropsSet(property1_, other1);
constraint_.UpdateOnAddProperty(property1_, other1, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, other1, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
} }
TEST_F(UniqueLabelPropertiesTest, InsertAbortInsert) { TEST_F(UniqueLabelPropertiesTest, InsertAbortInsert) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
dba->Abort(); dba.Abort();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
} }
@ -183,37 +183,37 @@ TEST_F(UniqueLabelPropertiesTest, InsertRemoveAbortInsert) {
gid::Gid gid = 0; gid::Gid gid = 0;
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
v.PropsErase(property2_); v.PropsErase(property2_);
constraint_.UpdateOnRemoveProperty(property2_, value2_, v, constraint_.UpdateOnRemoveProperty(property2_, value2_, v,
dba->transaction()); dba.transaction());
dba->Abort(); dba.Abort();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v, EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v,
dba->transaction()), dba.transaction()),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
} }
@ -221,31 +221,31 @@ TEST_F(UniqueLabelPropertiesTest, InsertRemoveAbortInsert) {
TEST_F(UniqueLabelPropertiesTest, InsertInsertSameTransaction) { TEST_F(UniqueLabelPropertiesTest, InsertInsertSameTransaction) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.add_label(label_); v2.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v2, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v2, dba.transaction());
v1.add_label(label_); v1.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v1, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v1, dba.transaction());
v1.PropsSet(property1_, value1_); v1.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v1, constraint_.UpdateOnAddProperty(property1_, value1_, v1,
dba->transaction()); dba.transaction());
v1.PropsSet(property2_, value2_); v1.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v1, constraint_.UpdateOnAddProperty(property2_, value2_, v1,
dba->transaction()); dba.transaction());
v2.PropsSet(property2_, value2_); v2.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v2, constraint_.UpdateOnAddProperty(property2_, value2_, v2,
dba->transaction()); dba.transaction());
v2.PropsSet(property3_, value3_); v2.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v2, constraint_.UpdateOnAddProperty(property3_, value3_, v2,
dba->transaction()); dba.transaction());
v2.PropsSet(property1_, value1_); v2.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v2, constraint_.UpdateOnAddProperty(property1_, value1_, v2,
dba->transaction()); dba.transaction());
v1.PropsSet(property3_, value3_); v1.PropsSet(property3_, value3_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v1, EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v1,
dba->transaction()), dba.transaction()),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
} }
@ -253,31 +253,31 @@ TEST_F(UniqueLabelPropertiesTest, InsertInsertSameTransaction) {
TEST_F(UniqueLabelPropertiesTest, InsertInsertReversed) { TEST_F(UniqueLabelPropertiesTest, InsertInsertReversed) {
auto dba1 = db_.Access(); auto dba1 = db_.Access();
auto dba2 = db_.Access(); auto dba2 = db_.Access();
auto v1 = dba1->InsertVertex(); auto v1 = dba1.InsertVertex();
auto v2 = dba2->InsertVertex(); auto v2 = dba2.InsertVertex();
v2.add_label(label_); v2.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v2, dba2->transaction()); constraint_.UpdateOnAddLabel(label_, v2, dba2.transaction());
v1.add_label(label_); v1.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v1, dba1->transaction()); constraint_.UpdateOnAddLabel(label_, v1, dba1.transaction());
v1.PropsSet(property1_, value1_); v1.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v1, constraint_.UpdateOnAddProperty(property1_, value1_, v1,
dba1->transaction()); dba1.transaction());
v1.PropsSet(property2_, value2_); v1.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v1, constraint_.UpdateOnAddProperty(property2_, value2_, v1,
dba1->transaction()); dba1.transaction());
v2.PropsSet(property2_, value2_); v2.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v2, constraint_.UpdateOnAddProperty(property2_, value2_, v2,
dba2->transaction()); dba2.transaction());
v2.PropsSet(property3_, value3_); v2.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v2, constraint_.UpdateOnAddProperty(property3_, value3_, v2,
dba2->transaction()); dba2.transaction());
v2.PropsSet(property1_, value1_); v2.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v2, constraint_.UpdateOnAddProperty(property1_, value1_, v2,
dba2->transaction()); dba2.transaction());
v1.PropsSet(property3_, value3_); v1.PropsSet(property3_, value3_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v1, EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v1,
dba1->transaction()), dba1.transaction()),
mvcc::SerializationError); mvcc::SerializationError);
} }
@ -285,87 +285,87 @@ TEST_F(UniqueLabelPropertiesTest, InsertRemoveInsert) {
gid::Gid gid = 0; gid::Gid gid = 0;
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
v.PropsErase(property2_); v.PropsErase(property2_);
constraint_.UpdateOnRemoveProperty(property2_, value2_, v, constraint_.UpdateOnRemoveProperty(property2_, value2_, v,
dba->transaction()); dba.transaction());
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
} }
} }
TEST_F(UniqueLabelPropertiesTest, InsertRemoveInsertSameTransaction) { TEST_F(UniqueLabelPropertiesTest, InsertRemoveInsertSameTransaction) {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsErase(property2_); v.PropsErase(property2_);
constraint_.UpdateOnRemoveProperty(property2_, value2_, v, constraint_.UpdateOnRemoveProperty(property2_, value2_, v,
dba->transaction()); dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
} }
TEST_F(UniqueLabelPropertiesTest, InsertDropInsert) { TEST_F(UniqueLabelPropertiesTest, InsertDropInsert) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
} }
{ {
auto dba = db_.AccessBlocking(); auto dba = db_.AccessBlocking();
constraint_.RemoveConstraint(label_, {property2_, property3_, property1_}); constraint_.RemoveConstraint(label_, {property2_, property3_, property1_});
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.PropsSet(property2_, value2_); v.PropsSet(property2_, value2_);
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
v.PropsSet(property1_, value1_); v.PropsSet(property1_, value1_);
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
v.add_label(label_); v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction()); constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
v.PropsSet(property3_, value3_); v.PropsSet(property3_, value3_);
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction()); constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
dba->Commit(); dba.Commit();
} }
} }

View File

@ -9,10 +9,10 @@ class UniqueLabelPropertyTest : public ::testing::Test {
public: public:
void SetUp() override { void SetUp() override {
auto dba = db_.Access(); auto dba = db_.Access();
label_ = dba->Label("label"); label_ = dba.Label("label");
property_ = dba->Property("property"); property_ = dba.Property("property");
dba->BuildUniqueConstraint(label_, property_); dba.BuildUniqueConstraint(label_, property_);
dba->Commit(); dba.Commit();
} }
database::GraphDb db_; database::GraphDb db_;
@ -24,51 +24,51 @@ class UniqueLabelPropertyTest : public ::testing::Test {
TEST_F(UniqueLabelPropertyTest, BuildDrop) { TEST_F(UniqueLabelPropertyTest, BuildDrop) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_TRUE(dba->UniqueConstraintExists(label_, property_)); EXPECT_TRUE(dba.UniqueConstraintExists(label_, property_));
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->DeleteUniqueConstraint(label_, property_); dba.DeleteUniqueConstraint(label_, property_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_FALSE(dba->UniqueConstraintExists(label_, property_)); EXPECT_FALSE(dba.UniqueConstraintExists(label_, property_));
dba->Commit(); dba.Commit();
} }
} }
TEST_F(UniqueLabelPropertyTest, BuildWithViolation) { TEST_F(UniqueLabelPropertyTest, BuildWithViolation) {
auto dba1 = db_.Access(); auto dba1 = db_.Access();
auto l1 = dba1->Label("l1"); auto l1 = dba1.Label("l1");
auto p1 = dba1->Property("p1"); auto p1 = dba1.Property("p1");
auto v1 = dba1->InsertVertex(); auto v1 = dba1.InsertVertex();
v1.add_label(l1); v1.add_label(l1);
v1.PropsSet(p1, value_); v1.PropsSet(p1, value_);
auto v2 = dba1->InsertVertex(); auto v2 = dba1.InsertVertex();
v2.add_label(l1); v2.add_label(l1);
v2.PropsSet(p1, value_); v2.PropsSet(p1, value_);
dba1->Commit(); dba1.Commit();
auto dba2 = db_.Access(); auto dba2 = db_.Access();
EXPECT_THROW(dba2->BuildUniqueConstraint(l1, p1), EXPECT_THROW(dba2.BuildUniqueConstraint(l1, p1),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
} }
TEST_F(UniqueLabelPropertyTest, InsertInsert) { TEST_F(UniqueLabelPropertyTest, InsertInsert) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
EXPECT_THROW(v.PropsSet(property_, value_), EXPECT_THROW(v.PropsSet(property_, value_),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
@ -78,35 +78,35 @@ TEST_F(UniqueLabelPropertyTest, InsertInsert) {
TEST_F(UniqueLabelPropertyTest, InsertInsertDiffValues) { TEST_F(UniqueLabelPropertyTest, InsertInsertDiffValues) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
PropertyValue other_value{"Some other value"}; PropertyValue other_value{"Some other value"};
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, other_value); v.PropsSet(property_, other_value);
dba->Commit(); dba.Commit();
} }
} }
TEST_F(UniqueLabelPropertyTest, InsertAbortInsert) { TEST_F(UniqueLabelPropertyTest, InsertAbortInsert) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Abort(); dba.Abort();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Commit(); dba.Commit();
} }
} }
@ -114,21 +114,21 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveAbortInsert) {
gid::Gid gid = 0; gid::Gid gid = 0;
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
gid = v.gid(); gid = v.gid();
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
v.PropsErase(property_); v.PropsErase(property_);
dba->Abort(); dba.Abort();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
EXPECT_THROW(v.PropsSet(property_, value_), EXPECT_THROW(v.PropsSet(property_, value_),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
@ -138,11 +138,11 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveAbortInsert) {
TEST_F(UniqueLabelPropertyTest, InsertInsertSameTransaction) { TEST_F(UniqueLabelPropertyTest, InsertInsertSameTransaction) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v1 = dba->InsertVertex(); auto v1 = dba.InsertVertex();
v1.add_label(label_); v1.add_label(label_);
v1.PropsSet(property_, value_); v1.PropsSet(property_, value_);
auto v2 = dba->InsertVertex(); auto v2 = dba.InsertVertex();
v2.add_label(label_); v2.add_label(label_);
EXPECT_THROW(v2.PropsSet(property_, value_), EXPECT_THROW(v2.PropsSet(property_, value_),
database::IndexConstraintViolationException); database::IndexConstraintViolationException);
@ -153,12 +153,12 @@ TEST_F(UniqueLabelPropertyTest, InsertInsertReversed) {
auto dba1 = db_.Access(); auto dba1 = db_.Access();
auto dba2 = db_.Access(); auto dba2 = db_.Access();
auto v2 = dba2->InsertVertex(); auto v2 = dba2.InsertVertex();
v2.add_label(label_); v2.add_label(label_);
v2.PropsSet(property_, value_); v2.PropsSet(property_, value_);
dba2->Commit(); dba2.Commit();
auto v1 = dba1->InsertVertex(); auto v1 = dba1.InsertVertex();
v1.add_label(label_); v1.add_label(label_);
EXPECT_THROW(v1.PropsSet(property_, value_), EXPECT_THROW(v1.PropsSet(property_, value_),
mvcc::SerializationError); mvcc::SerializationError);
@ -168,21 +168,21 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsert) {
gid::Gid gid = 0; gid::Gid gid = 0;
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
gid = v.gid(); gid = v.gid();
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->FindVertex(gid, false); auto v = dba.FindVertex(gid, false);
v.PropsErase(property_); v.PropsErase(property_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
} }
@ -190,33 +190,33 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsert) {
TEST_F(UniqueLabelPropertyTest, InsertRemoveInsertSameTransaction) { TEST_F(UniqueLabelPropertyTest, InsertRemoveInsertSameTransaction) {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
v.PropsErase(property_); v.PropsErase(property_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Commit(); dba.Commit();
} }
TEST_F(UniqueLabelPropertyTest, InsertDropInsert) { TEST_F(UniqueLabelPropertyTest, InsertDropInsert) {
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
dba->DeleteUniqueConstraint(label_, property_); dba.DeleteUniqueConstraint(label_, property_);
dba->Commit(); dba.Commit();
} }
{ {
auto dba = db_.Access(); auto dba = db_.Access();
auto v = dba->InsertVertex(); auto v = dba.InsertVertex();
v.add_label(label_); v.add_label(label_);
v.PropsSet(property_, value_); v.PropsSet(property_, value_);
dba->Commit(); dba.Commit();
} }
} }

View File

@ -35,20 +35,20 @@ class RecoveryTest : public ::testing::Test {
TEST_F(RecoveryTest, TestVerticesRecovered) { TEST_F(RecoveryTest, TestVerticesRecovered) {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_EQ(dba->VerticesCount(), 10); EXPECT_EQ(dba.VerticesCount(), 10);
EXPECT_EQ(dba->VerticesCount(dba->Label("Comment")), 5); EXPECT_EQ(dba.VerticesCount(dba.Label("Comment")), 5);
for (const auto &vertex : dba->Vertices(dba->Label("Comment"), false)) { for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
EXPECT_TRUE(vertex.has_label(dba->Label("Message"))); EXPECT_TRUE(vertex.has_label(dba.Label("Message")));
} }
EXPECT_EQ(dba->VerticesCount(dba->Label("Forum")), 5); EXPECT_EQ(dba.VerticesCount(dba.Label("Forum")), 5);
} }
TEST_F(RecoveryTest, TestPropertyNull) { TEST_F(RecoveryTest, TestPropertyNull) {
auto dba = db_.Access(); auto dba = db_.Access();
bool found = false; bool found = false;
for (const auto &vertex : dba->Vertices(dba->Label("Comment"), false)) { for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
auto id_prop = query::TypedValue(vertex.PropsAt(dba->Property("id"))); auto id_prop = query::TypedValue(vertex.PropsAt(dba.Property("id")));
auto browser = query::TypedValue(vertex.PropsAt(dba->Property("browser"))); auto browser = query::TypedValue(vertex.PropsAt(dba.Property("browser")));
if (id_prop.IsString() && id_prop.Value<std::string>() == "2") { if (id_prop.IsString() && id_prop.Value<std::string>() == "2") {
EXPECT_FALSE(found); EXPECT_FALSE(found);
found = true; found = true;
@ -62,17 +62,17 @@ TEST_F(RecoveryTest, TestPropertyNull) {
TEST_F(RecoveryTest, TestEdgesRecovered) { TEST_F(RecoveryTest, TestEdgesRecovered) {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_EQ(dba->EdgesCount(), 5); EXPECT_EQ(dba.EdgesCount(), 5);
for (const auto &edge : dba->Edges(false)) { for (const auto &edge : dba.Edges(false)) {
EXPECT_TRUE(edge.EdgeType() == dba->EdgeType("POSTED_ON")); EXPECT_TRUE(edge.EdgeType() == dba.EdgeType("POSTED_ON"));
} }
} }
TEST_F(RecoveryTest, TestQuote) { TEST_F(RecoveryTest, TestQuote) {
auto dba = db_.Access(); auto dba = db_.Access();
for (const auto &vertex : dba->Vertices(dba->Label("Comment"), false)) { for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
auto id_prop = query::TypedValue(vertex.PropsAt(dba->Property("id"))); auto id_prop = query::TypedValue(vertex.PropsAt(dba.Property("id")));
auto country = query::TypedValue(vertex.PropsAt(dba->Property("country"))); auto country = query::TypedValue(vertex.PropsAt(dba.Property("country")));
if (id_prop.IsString() && id_prop.Value<std::string>() == "1") { if (id_prop.IsString() && id_prop.Value<std::string>() == "1") {
EXPECT_TRUE(country.IsString()); EXPECT_TRUE(country.IsString());
EXPECT_EQ(country.Value<std::string>(), "United Kingdom"); EXPECT_EQ(country.Value<std::string>(), "United Kingdom");
@ -82,17 +82,17 @@ TEST_F(RecoveryTest, TestQuote) {
TEST_F(RecoveryTest, TestNodeLabelFlag) { TEST_F(RecoveryTest, TestNodeLabelFlag) {
auto dba = db_.Access(); auto dba = db_.Access();
for (const auto &vertex : dba->Vertices(false)) { for (const auto &vertex : dba.Vertices(false)) {
EXPECT_TRUE(vertex.has_label(dba->Label("First"))); EXPECT_TRUE(vertex.has_label(dba.Label("First")));
EXPECT_TRUE(vertex.has_label(dba->Label("Second"))); EXPECT_TRUE(vertex.has_label(dba.Label("Second")));
} }
} }
TEST_F(RecoveryTest, TestRelationshipType) { TEST_F(RecoveryTest, TestRelationshipType) {
auto dba = db_.Access(); auto dba = db_.Access();
EXPECT_EQ(dba->EdgesCount(), 5); EXPECT_EQ(dba.EdgesCount(), 5);
for (const auto &edge : dba->Edges(false)) { for (const auto &edge : dba.Edges(false)) {
EXPECT_TRUE(edge.EdgeType() == dba->EdgeType("TYPE")); EXPECT_TRUE(edge.EdgeType() == dba.EdgeType("TYPE"));
} }
} }