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:
parent
6b62145a59
commit
026c796e06
@ -64,7 +64,7 @@ GraphDb::GraphDb(Config config) : config_(config) {
|
||||
snapshot_creator_->Run(
|
||||
"Snapshot", std::chrono::seconds(config_.snapshot_cycle_sec), [this] {
|
||||
auto dba = this->Access();
|
||||
this->MakeSnapshot(*dba);
|
||||
this->MakeSnapshot(dba);
|
||||
});
|
||||
}
|
||||
|
||||
@ -95,26 +95,21 @@ GraphDb::~GraphDb() {
|
||||
|
||||
if (config_.snapshot_on_exit) {
|
||||
auto dba = this->Access();
|
||||
MakeSnapshot(*dba);
|
||||
MakeSnapshot(dba);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::Access() {
|
||||
// NOTE: We are doing a heap allocation to allow polymorphism. If this poses
|
||||
// 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));
|
||||
GraphDbAccessor GraphDb::Access() {
|
||||
return GraphDbAccessor(this);
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::Access(tx::TransactionId tx_id) {
|
||||
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this, tx_id));
|
||||
GraphDbAccessor GraphDb::Access(tx::TransactionId tx_id) {
|
||||
return GraphDbAccessor(this, tx_id);
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::AccessBlocking(
|
||||
GraphDbAccessor GraphDb::AccessBlocking(
|
||||
std::experimental::optional<tx::TransactionId> parent_tx) {
|
||||
return std::unique_ptr<GraphDbAccessor>(
|
||||
new GraphDbAccessor(*this, parent_tx));
|
||||
return GraphDbAccessor(this, parent_tx);
|
||||
}
|
||||
|
||||
Storage &GraphDb::storage() { return *storage_; }
|
||||
|
@ -92,12 +92,12 @@ class GraphDb {
|
||||
GraphDb &operator=(GraphDb &&) = delete;
|
||||
|
||||
/// Create a new accessor by starting a new transaction.
|
||||
std::unique_ptr<GraphDbAccessor> Access();
|
||||
std::unique_ptr<GraphDbAccessor> AccessBlocking(
|
||||
GraphDbAccessor Access();
|
||||
GraphDbAccessor AccessBlocking(
|
||||
std::experimental::optional<tx::TransactionId> parent_tx =
|
||||
std::experimental::nullopt);
|
||||
/// Create an accessor for a running transaction.
|
||||
std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId);
|
||||
GraphDbAccessor Access(tx::TransactionId);
|
||||
|
||||
Storage &storage();
|
||||
durability::WriteAheadLog &wal();
|
||||
|
@ -16,22 +16,47 @@
|
||||
|
||||
namespace database {
|
||||
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb &db)
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb *db)
|
||||
: db_(db),
|
||||
transaction_(*db.tx_engine().Begin()),
|
||||
transaction_(db->tx_engine().Begin()),
|
||||
transaction_starter_{true} {}
|
||||
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id)
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb *db, tx::TransactionId tx_id)
|
||||
: db_(db),
|
||||
transaction_(*db.tx_engine().RunningTransaction(tx_id)),
|
||||
transaction_(db->tx_engine().RunningTransaction(tx_id)),
|
||||
transaction_starter_{false} {}
|
||||
|
||||
GraphDbAccessor::GraphDbAccessor(
|
||||
GraphDb &db, std::experimental::optional<tx::TransactionId> parent_tx)
|
||||
GraphDb *db, std::experimental::optional<tx::TransactionId> parent_tx)
|
||||
: db_(db),
|
||||
transaction_(*db.tx_engine().BeginBlocking(parent_tx)),
|
||||
transaction_(db->tx_engine().BeginBlocking(parent_tx)),
|
||||
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() {
|
||||
if (transaction_starter_ && !commited_ && !aborted_) {
|
||||
this->Abort();
|
||||
@ -39,53 +64,53 @@ GraphDbAccessor::~GraphDbAccessor() {
|
||||
}
|
||||
|
||||
tx::TransactionId GraphDbAccessor::transaction_id() const {
|
||||
return transaction_.id_;
|
||||
return transaction_->id_;
|
||||
}
|
||||
|
||||
void GraphDbAccessor::AdvanceCommand() {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
db_.tx_engine().Advance(transaction_.id_);
|
||||
db_->tx_engine().Advance(transaction_->id_);
|
||||
}
|
||||
|
||||
void GraphDbAccessor::Commit() {
|
||||
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
|
||||
db_.tx_engine().Commit(transaction_);
|
||||
db_->tx_engine().Commit(*transaction_);
|
||||
commited_ = true;
|
||||
}
|
||||
|
||||
void GraphDbAccessor::Abort() {
|
||||
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
|
||||
db_.tx_engine().Abort(transaction_);
|
||||
db_->tx_engine().Abort(*transaction_);
|
||||
aborted_ = true;
|
||||
}
|
||||
|
||||
bool GraphDbAccessor::should_abort() const {
|
||||
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(
|
||||
std::experimental::optional<gid::Gid> requested_gid) {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
|
||||
auto gid = db_.storage().vertex_generator_.Next(requested_gid);
|
||||
auto vertex_vlist = new mvcc::VersionList<Vertex>(transaction_, gid);
|
||||
auto gid = db_->storage().vertex_generator_.Next(requested_gid);
|
||||
auto vertex_vlist = new mvcc::VersionList<Vertex>(*transaction_, gid);
|
||||
|
||||
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: "
|
||||
<< gid;
|
||||
wal().Emplace(
|
||||
database::StateDelta::CreateVertex(transaction_.id_, vertex_vlist->gid_));
|
||||
database::StateDelta::CreateVertex(transaction_->id_, vertex_vlist->gid_));
|
||||
auto va = VertexAccessor(vertex_vlist, *this);
|
||||
return va;
|
||||
}
|
||||
|
||||
std::experimental::optional<VertexAccessor> GraphDbAccessor::FindVertexOptional(
|
||||
gid::Gid gid, bool current_state) {
|
||||
VertexAccessor record_accessor(db_.storage().LocalAddress<Vertex>(gid),
|
||||
VertexAccessor record_accessor(db_->storage().LocalAddress<Vertex>(gid),
|
||||
*this);
|
||||
if (!record_accessor.Visible(transaction(), current_state))
|
||||
return std::experimental::nullopt;
|
||||
@ -100,7 +125,7 @@ VertexAccessor GraphDbAccessor::FindVertex(gid::Gid gid, bool current_state) {
|
||||
|
||||
std::experimental::optional<EdgeAccessor> GraphDbAccessor::FindEdgeOptional(
|
||||
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))
|
||||
return std::experimental::nullopt;
|
||||
return record_accessor;
|
||||
@ -118,7 +143,7 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
|
||||
|
||||
// Create the index
|
||||
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(
|
||||
"Index is either being created by another transaction or already "
|
||||
"exists.");
|
||||
@ -126,16 +151,16 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
|
||||
|
||||
try {
|
||||
auto dba =
|
||||
db_.AccessBlocking(std::experimental::make_optional(transaction_.id_));
|
||||
db_->AccessBlocking(std::experimental::make_optional(transaction_->id_));
|
||||
|
||||
dba->PopulateIndex(key);
|
||||
dba->EnableIndex(key);
|
||||
dba->Commit();
|
||||
dba.PopulateIndex(key);
|
||||
dba.EnableIndex(key);
|
||||
dba.Commit();
|
||||
} catch (const IndexConstraintViolationException &) {
|
||||
db_.storage().label_property_index_.DeleteIndex(key);
|
||||
db_->storage().label_property_index_.DeleteIndex(key);
|
||||
throw;
|
||||
} catch (const tx::TransactionEngineError &e) {
|
||||
db_.storage().label_property_index_.DeleteIndex(key);
|
||||
db_->storage().label_property_index_.DeleteIndex(key);
|
||||
throw IndexTransactionException(e.what());
|
||||
}
|
||||
}
|
||||
@ -154,7 +179,7 @@ void GraphDbAccessor::PopulateIndex(const LabelPropertyIndex::Key &key) {
|
||||
for (auto vertex : Vertices(key.label_, false)) {
|
||||
if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null)
|
||||
continue;
|
||||
if (!db_.storage().label_property_index_.UpdateOnLabelProperty(
|
||||
if (!db_->storage().label_property_index_.UpdateOnLabelProperty(
|
||||
vertex.address(), vertex.current_)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"Index couldn't be created due to constraint violation!");
|
||||
@ -169,14 +194,14 @@ void GraphDbAccessor::DeleteIndex(storage::Label label,
|
||||
LabelPropertyIndex::Key key(label, property);
|
||||
try {
|
||||
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);
|
||||
dba->wal().Emplace(database::StateDelta::DropIndex(
|
||||
dba->transaction_id(), key.label_, LabelName(key.label_), key.property_,
|
||||
db_->storage().label_property_index_.DeleteIndex(key);
|
||||
dba.wal().Emplace(database::StateDelta::DropIndex(
|
||||
dba.transaction_id(), key.label_, LabelName(key.label_), key.property_,
|
||||
PropertyName(key.property_)));
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
} catch (const tx::TransactionEngineError &e) {
|
||||
throw IndexTransactionException(e.what());
|
||||
}
|
||||
@ -186,37 +211,37 @@ void GraphDbAccessor::BuildUniqueConstraint(storage::Label label,
|
||||
storage::Property property) {
|
||||
try {
|
||||
auto dba =
|
||||
db_.AccessBlocking(std::experimental::make_optional(transaction().id_));
|
||||
if (!db_.storage().unique_label_property_constraints_.AddConstraint(
|
||||
label, property, dba->transaction())) {
|
||||
db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
|
||||
if (!db_->storage().unique_label_property_constraints_.AddConstraint(
|
||||
label, property, dba.transaction())) {
|
||||
// Already exists
|
||||
return;
|
||||
}
|
||||
for (auto v : dba->Vertices(false)) {
|
||||
for (auto v : dba.Vertices(false)) {
|
||||
if (std::find(v.labels().begin(), v.labels().end(), label) !=
|
||||
v.labels().end()) {
|
||||
db_.storage().unique_label_property_constraints_.Update(
|
||||
v, dba->transaction());
|
||||
db_->storage().unique_label_property_constraints_.Update(
|
||||
v, dba.transaction());
|
||||
}
|
||||
}
|
||||
|
||||
dba->wal().Emplace(database::StateDelta::BuildUniqueConstraint(
|
||||
dba->transaction().id_, label, dba->LabelName(label),
|
||||
dba.wal().Emplace(database::StateDelta::BuildUniqueConstraint(
|
||||
dba.transaction().id_, label, dba.LabelName(label),
|
||||
std::vector<storage::Property>{property},
|
||||
std::vector<std::string>{dba->PropertyName(property)}));
|
||||
dba->Commit();
|
||||
std::vector<std::string>{dba.PropertyName(property)}));
|
||||
dba.Commit();
|
||||
} catch (const IndexConstraintViolationException &) {
|
||||
db_.storage().unique_label_property_constraints_.RemoveConstraint(label,
|
||||
db_->storage().unique_label_property_constraints_.RemoveConstraint(label,
|
||||
property);
|
||||
throw IndexConstraintViolationException(
|
||||
"Constraint cannot be built due to existing unique constraint "
|
||||
"violation!");
|
||||
} catch (const tx::TransactionEngineError &e) {
|
||||
db_.storage().unique_label_property_constraints_.RemoveConstraint(label,
|
||||
db_->storage().unique_label_property_constraints_.RemoveConstraint(label,
|
||||
property);
|
||||
throw IndexTransactionException(e.what());
|
||||
} catch (...) {
|
||||
db_.storage().unique_label_property_constraints_.RemoveConstraint(label,
|
||||
db_->storage().unique_label_property_constraints_.RemoveConstraint(label,
|
||||
property);
|
||||
throw;
|
||||
}
|
||||
@ -226,19 +251,19 @@ void GraphDbAccessor::DeleteUniqueConstraint(storage::Label label,
|
||||
storage::Property property) {
|
||||
try {
|
||||
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)) {
|
||||
// Nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
dba->wal().Emplace(database::StateDelta::DropUniqueConstraint(
|
||||
dba->transaction().id_, label, dba->LabelName(label),
|
||||
dba.wal().Emplace(database::StateDelta::DropUniqueConstraint(
|
||||
dba.transaction().id_, label, dba.LabelName(label),
|
||||
std::vector<storage::Property>{property},
|
||||
std::vector<std::string>{dba->PropertyName(property)}));
|
||||
dba->Commit();
|
||||
std::vector<std::string>{dba.PropertyName(property)}));
|
||||
dba.Commit();
|
||||
} catch (const tx::TransactionEngineError &e) {
|
||||
throw IndexTransactionException(e.what());
|
||||
}
|
||||
@ -246,13 +271,13 @@ void GraphDbAccessor::DeleteUniqueConstraint(storage::Label label,
|
||||
|
||||
bool GraphDbAccessor::UniqueConstraintExists(storage::Label label,
|
||||
storage::Property property) const {
|
||||
return db_.storage().unique_label_property_constraints_.Exists(label,
|
||||
return db_->storage().unique_label_property_constraints_.Exists(label,
|
||||
property);
|
||||
}
|
||||
|
||||
std::vector<storage::constraints::LabelProperty>
|
||||
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,
|
||||
@ -261,26 +286,26 @@ void GraphDbAccessor::UpdateOnAddLabel(storage::Label label,
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
auto *vlist_ptr = vertex_accessor.address();
|
||||
|
||||
db_.storage().unique_label_property_constraints_.UpdateOnAddLabel(
|
||||
db_->storage().unique_label_property_constraints_.UpdateOnAddLabel(
|
||||
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)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"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(
|
||||
"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(
|
||||
storage::Label label, const RecordAccessor<Vertex> &accessor) {
|
||||
db_.storage().unique_label_property_constraints_.UpdateOnRemoveLabel(
|
||||
db_->storage().unique_label_property_constraints_.UpdateOnRemoveLabel(
|
||||
label, accessor, transaction());
|
||||
}
|
||||
|
||||
@ -289,10 +314,10 @@ void GraphDbAccessor::UpdateOnAddProperty(
|
||||
const RecordAccessor<Vertex> &vertex_accessor, const Vertex *vertex) {
|
||||
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());
|
||||
|
||||
if (!db_.storage().label_property_index_.UpdateOnProperty(
|
||||
if (!db_->storage().label_property_index_.UpdateOnProperty(
|
||||
property, vertex_accessor.address(), vertex)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"Node couldn't be updated due to unique index violation!");
|
||||
@ -302,10 +327,10 @@ void GraphDbAccessor::UpdateOnAddProperty(
|
||||
void GraphDbAccessor::UpdateOnRemoveProperty(
|
||||
storage::Property property, const RecordAccessor<Vertex> &accessor,
|
||||
const Vertex *vertex) {
|
||||
db_.storage().unique_label_property_constraints_.UpdateOnRemoveProperty(
|
||||
db_->storage().unique_label_property_constraints_.UpdateOnRemoveProperty(
|
||||
property, accessor, transaction());
|
||||
|
||||
if (!db_.storage().existence_constraints_.CheckOnRemoveProperty(vertex,
|
||||
if (!db_->storage().existence_constraints_.CheckOnRemoveProperty(vertex,
|
||||
property)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"Node couldn't be updated due to existence constraint violation!");
|
||||
@ -315,10 +340,10 @@ void GraphDbAccessor::UpdateOnRemoveProperty(
|
||||
void GraphDbAccessor::BuildExistenceConstraint(
|
||||
storage::Label label, const std::vector<storage::Property> &properties) {
|
||||
auto dba =
|
||||
db_.AccessBlocking(std::experimental::make_optional(transaction().id_));
|
||||
db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
|
||||
storage::constraints::ExistenceRule rule{label, properties};
|
||||
|
||||
for (auto v : dba->Vertices(false)) {
|
||||
for (auto v : dba.Vertices(false)) {
|
||||
if (!CheckIfSatisfiesExistenceRule(v.GetOld(), rule)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"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
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> property_names(properties.size());
|
||||
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->transaction().id_, label, dba->LabelName(label), properties,
|
||||
dba.wal().Emplace(database::StateDelta::BuildExistenceConstraint(
|
||||
dba.transaction().id_, label, dba.LabelName(label), properties,
|
||||
property_names));
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
void GraphDbAccessor::DeleteExistenceConstraint(
|
||||
storage::Label label, const std::vector<storage::Property> &properties) {
|
||||
auto dba =
|
||||
db_.AccessBlocking(std::experimental::make_optional(transaction().id_));
|
||||
db_->AccessBlocking(std::experimental::make_optional(transaction().id_));
|
||||
storage::constraints::ExistenceRule rule{label, properties};
|
||||
if (!db_.storage().existence_constraints_.RemoveConstraint(rule)) {
|
||||
if (!db_->storage().existence_constraints_.RemoveConstraint(rule)) {
|
||||
// Nothing was deleted
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> property_names(properties.size());
|
||||
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->transaction().id_, label, dba->LabelName(label), properties,
|
||||
dba.wal().Emplace(database::StateDelta::DropExistenceConstraint(
|
||||
dba.transaction().id_, label, dba.LabelName(label), properties,
|
||||
property_names));
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
bool GraphDbAccessor::ExistenceConstraintExists(
|
||||
storage::Label label,
|
||||
const std::vector<storage::Property> &properties) const {
|
||||
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>
|
||||
GraphDbAccessor::ListExistenceConstraints() const {
|
||||
return db_.storage().existence_constraints_.ListConstraints();
|
||||
return db_->storage().existence_constraints_.ListConstraints();
|
||||
}
|
||||
|
||||
int64_t GraphDbAccessor::VerticesCount() const {
|
||||
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 {
|
||||
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,
|
||||
storage::Property property) const {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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.";
|
||||
return db_.storage().label_property_index_.Count(key);
|
||||
return db_->storage().label_property_index_.Count(key);
|
||||
}
|
||||
|
||||
int64_t GraphDbAccessor::VerticesCount(storage::Label label,
|
||||
@ -397,9 +422,9 @@ int64_t GraphDbAccessor::VerticesCount(storage::Label label,
|
||||
const PropertyValue &value) const {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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.";
|
||||
return db_.storage()
|
||||
return db_->storage()
|
||||
.label_property_index_.PositionAndCount(key, value)
|
||||
.second;
|
||||
}
|
||||
@ -411,7 +436,7 @@ int64_t GraphDbAccessor::VerticesCount(
|
||||
const {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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.";
|
||||
CHECK(lower || upper) << "At least one bound must be provided";
|
||||
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";
|
||||
|
||||
if (!upper) {
|
||||
auto lower_pac = db_.storage().label_property_index_.PositionAndCount(
|
||||
auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
|
||||
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,
|
||||
size - lower_pac.first -
|
||||
(lower.value().IsInclusive() ? 0l : lower_pac.second));
|
||||
|
||||
} 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());
|
||||
return upper.value().IsInclusive() ? upper_pac.first + upper_pac.second
|
||||
: upper_pac.first;
|
||||
|
||||
} else {
|
||||
auto lower_pac = db_.storage().label_property_index_.PositionAndCount(
|
||||
auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
|
||||
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());
|
||||
auto result = upper_pac.first - lower_pac.first;
|
||||
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
|
||||
// due to it getting matched multiple times by some patterns
|
||||
// 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 &&
|
||||
vertex_accessor.out_degree() + vertex_accessor.in_degree() > 0)
|
||||
return false;
|
||||
|
||||
auto *vlist_ptr = vertex_accessor.address();
|
||||
wal().Emplace(database::StateDelta::RemoveVertex(
|
||||
transaction_.id_, vlist_ptr->gid_, check_empty));
|
||||
vlist_ptr->remove(vertex_accessor.current_, transaction_);
|
||||
transaction_->id_, vlist_ptr->gid_, check_empty));
|
||||
vlist_ptr->remove(vertex_accessor.current_, *transaction_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -485,13 +510,13 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
|
||||
VertexAccessor &from, VertexAccessor &to, storage::EdgeType edge_type,
|
||||
std::experimental::optional<gid::Gid> requested_gid) {
|
||||
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>(
|
||||
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
|
||||
// can throw and edge_vlist will not be garbage collected if it is not in
|
||||
// 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: "
|
||||
<< gid;
|
||||
|
||||
@ -506,7 +531,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
|
||||
to.update().in_.emplace(from.address(), edge_vlist, edge_type);
|
||||
|
||||
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)));
|
||||
|
||||
return EdgeAccessor(edge_vlist, *this, from.address(), to.address(),
|
||||
@ -515,7 +540,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
|
||||
|
||||
int64_t GraphDbAccessor::EdgesCount() const {
|
||||
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,
|
||||
@ -525,61 +550,61 @@ void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge,
|
||||
// due to it getting matched multiple times by some patterns
|
||||
// we can only delete it once, so check if it's already deleted
|
||||
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_in_edge) edge.to().RemoveInEdge(edge.address());
|
||||
|
||||
edge.address()->remove(edge.current_, transaction_);
|
||||
wal().Emplace(database::StateDelta::RemoveEdge(transaction_.id_, edge.gid()));
|
||||
edge.address()->remove(edge.current_, *transaction_);
|
||||
wal().Emplace(database::StateDelta::RemoveEdge(transaction_->id_, edge.gid()));
|
||||
}
|
||||
|
||||
storage::Label GraphDbAccessor::Label(const std::string &label_name) {
|
||||
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 {
|
||||
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) {
|
||||
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(
|
||||
storage::EdgeType edge_type) const {
|
||||
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) {
|
||||
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(
|
||||
storage::Property property) const {
|
||||
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) {
|
||||
return db_.counters().Get(name);
|
||||
return db_->counters().Get(name);
|
||||
}
|
||||
|
||||
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> info;
|
||||
for (storage::Label label : db_.storage().labels_index_.Keys()) {
|
||||
for (storage::Label label : db_->storage().labels_index_.Keys()) {
|
||||
info.emplace_back(":" + LabelName(label));
|
||||
}
|
||||
for (LabelPropertyIndex::Key key :
|
||||
db_.storage().label_property_index_.Keys()) {
|
||||
db_->storage().label_property_index_.Keys()) {
|
||||
info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_),
|
||||
PropertyName(key.property_),
|
||||
key.unique_ ? " unique" : ""));
|
||||
@ -591,14 +616,14 @@ std::vector<std::pair<std::string, std::string>> GraphDbAccessor::StorageInfo()
|
||||
const {
|
||||
std::vector<std::pair<std::string, std::string>> info;
|
||||
|
||||
db_.RefreshStat();
|
||||
auto &stat = db_.GetStat();
|
||||
db_->RefreshStat();
|
||||
auto &stat = db_->GetStat();
|
||||
|
||||
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("average_degree", std::to_string(stat.avg_degree));
|
||||
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;
|
||||
}
|
||||
|
@ -42,20 +42,21 @@ class GraphDbAccessor {
|
||||
// concrete GraphDbAccessor type.
|
||||
|
||||
/// Creates a new accessor by starting a new transaction.
|
||||
explicit GraphDbAccessor(GraphDb &db);
|
||||
explicit GraphDbAccessor(GraphDb *db);
|
||||
/// 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);
|
||||
|
||||
public:
|
||||
~GraphDbAccessor();
|
||||
|
||||
GraphDbAccessor(const GraphDbAccessor &other) = delete;
|
||||
GraphDbAccessor(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
|
||||
@ -142,7 +143,7 @@ class GraphDbAccessor {
|
||||
[this](auto id_vlist) {
|
||||
return VertexAccessor(id_vlist.second, *this);
|
||||
},
|
||||
db_.storage().vertices_.access());
|
||||
db_->storage().vertices_.access());
|
||||
|
||||
// filter out the accessors not visible to the current transaction
|
||||
return iter::filter(
|
||||
@ -168,7 +169,7 @@ class GraphDbAccessor {
|
||||
[this](auto vlist) {
|
||||
return VertexAccessor(vlist, *this);
|
||||
},
|
||||
db_.storage().labels_index_.GetVlists(label, transaction_,
|
||||
db_->storage().labels_index_.GetVlists(label, *transaction_,
|
||||
current_state));
|
||||
}
|
||||
|
||||
@ -187,15 +188,15 @@ class GraphDbAccessor {
|
||||
auto Vertices(storage::Label label, storage::Property property,
|
||||
bool current_state) {
|
||||
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)))
|
||||
<< "Label+property index doesn't exist.";
|
||||
return iter::imap(
|
||||
[this](auto vlist) {
|
||||
return VertexAccessor(vlist, *this);
|
||||
},
|
||||
db_.storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), transaction_,
|
||||
db_->storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), *transaction_,
|
||||
current_state));
|
||||
}
|
||||
|
||||
@ -215,7 +216,7 @@ class GraphDbAccessor {
|
||||
auto Vertices(storage::Label label, storage::Property property,
|
||||
const PropertyValue &value, bool current_state) {
|
||||
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)))
|
||||
<< "Label+property index doesn't exist.";
|
||||
CHECK(value.type() != PropertyValue::Type::Null)
|
||||
@ -224,8 +225,8 @@ class GraphDbAccessor {
|
||||
[this](auto vlist) {
|
||||
return VertexAccessor(vlist, *this);
|
||||
},
|
||||
db_.storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), value, transaction_,
|
||||
db_->storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), value, *transaction_,
|
||||
current_state));
|
||||
}
|
||||
|
||||
@ -262,16 +263,16 @@ class GraphDbAccessor {
|
||||
const std::experimental::optional<utils::Bound<PropertyValue>> upper,
|
||||
bool current_state) {
|
||||
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)))
|
||||
<< "Label+property index doesn't exist.";
|
||||
return iter::imap(
|
||||
[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,
|
||||
transaction_, current_state));
|
||||
*transaction_, current_state));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,7 +358,7 @@ class GraphDbAccessor {
|
||||
[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
|
||||
return iter::filter(
|
||||
@ -463,7 +464,7 @@ class GraphDbAccessor {
|
||||
bool LabelPropertyIndexExists(storage::Label label,
|
||||
storage::Property property) const {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -472,7 +473,7 @@ class GraphDbAccessor {
|
||||
*/
|
||||
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
|
||||
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. */
|
||||
bool should_abort() const;
|
||||
|
||||
const tx::Transaction &transaction() const { return transaction_; }
|
||||
const tx::Transaction &transaction() const { return *transaction_; }
|
||||
durability::WriteAheadLog &wal();
|
||||
auto &db() { return db_; }
|
||||
const auto &db() const { return db_; }
|
||||
GraphDb &db() { return *db_; }
|
||||
const GraphDb &db() const { return *db_; }
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
private:
|
||||
GraphDb &db_;
|
||||
tx::Transaction &transaction_;
|
||||
GraphDb *db_;
|
||||
tx::Transaction *transaction_;
|
||||
// Indicates if this db-accessor started the transaction and should Abort it
|
||||
// upon destruction.
|
||||
bool transaction_starter_;
|
||||
|
@ -51,22 +51,17 @@ void GraphDb::AwaitShutdown(std::function<void(void)> call_before_shutdown) {
|
||||
|
||||
void GraphDb::Shutdown() { coordination_.Shutdown(); }
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::Access() {
|
||||
// NOTE: We are doing a heap allocation to allow polymorphism. If this poses
|
||||
// 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));
|
||||
GraphDbAccessor GraphDb::Access() {
|
||||
return GraphDbAccessor(this);
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::Access(tx::TransactionId tx_id) {
|
||||
return std::unique_ptr<GraphDbAccessor>(new GraphDbAccessor(*this, tx_id));
|
||||
GraphDbAccessor GraphDb::Access(tx::TransactionId tx_id) {
|
||||
return GraphDbAccessor(this, tx_id);
|
||||
}
|
||||
|
||||
std::unique_ptr<GraphDbAccessor> GraphDb::AccessBlocking(
|
||||
GraphDbAccessor GraphDb::AccessBlocking(
|
||||
std::experimental::optional<tx::TransactionId> parent_tx) {
|
||||
return std::unique_ptr<GraphDbAccessor>(
|
||||
new GraphDbAccessor(*this, parent_tx));
|
||||
return GraphDbAccessor(this, parent_tx);
|
||||
}
|
||||
|
||||
Storage &GraphDb::storage() { return *storage_; }
|
||||
|
@ -100,11 +100,11 @@ class GraphDb {
|
||||
void Shutdown();
|
||||
|
||||
/// Create a new accessor by starting a new transaction.
|
||||
std::unique_ptr<GraphDbAccessor> Access();
|
||||
std::unique_ptr<GraphDbAccessor> AccessBlocking(
|
||||
GraphDbAccessor Access();
|
||||
GraphDbAccessor AccessBlocking(
|
||||
std::experimental::optional<tx::TransactionId> parent_tx);
|
||||
/// Create an accessor for a running transaction.
|
||||
std::unique_ptr<GraphDbAccessor> Access(tx::TransactionId);
|
||||
GraphDbAccessor Access(tx::TransactionId);
|
||||
|
||||
Storage &storage();
|
||||
raft::RaftInterface *raft();
|
||||
|
@ -16,22 +16,47 @@
|
||||
|
||||
namespace database {
|
||||
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb &db)
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb *db)
|
||||
: db_(db),
|
||||
transaction_(*db.tx_engine().Begin()),
|
||||
transaction_(db->tx_engine().Begin()),
|
||||
transaction_starter_{true} {}
|
||||
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb &db, tx::TransactionId tx_id)
|
||||
GraphDbAccessor::GraphDbAccessor(GraphDb *db, tx::TransactionId tx_id)
|
||||
: db_(db),
|
||||
transaction_(*db.tx_engine().RunningTransaction(tx_id)),
|
||||
transaction_(db->tx_engine().RunningTransaction(tx_id)),
|
||||
transaction_starter_{false} {}
|
||||
|
||||
GraphDbAccessor::GraphDbAccessor(
|
||||
GraphDb &db, std::experimental::optional<tx::TransactionId> parent_tx)
|
||||
GraphDb *db, std::experimental::optional<tx::TransactionId> parent_tx)
|
||||
: db_(db),
|
||||
transaction_(*db.tx_engine().BeginBlocking(parent_tx)),
|
||||
transaction_(db->tx_engine().BeginBlocking(parent_tx)),
|
||||
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() {
|
||||
if (transaction_starter_ && !commited_ && !aborted_) {
|
||||
this->Abort();
|
||||
@ -39,53 +64,53 @@ GraphDbAccessor::~GraphDbAccessor() {
|
||||
}
|
||||
|
||||
tx::TransactionId GraphDbAccessor::transaction_id() const {
|
||||
return transaction_.id_;
|
||||
return transaction_->id_;
|
||||
}
|
||||
|
||||
void GraphDbAccessor::AdvanceCommand() {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
db_.tx_engine().Advance(transaction_.id_);
|
||||
db_->tx_engine().Advance(transaction_->id_);
|
||||
}
|
||||
|
||||
void GraphDbAccessor::Commit() {
|
||||
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
|
||||
db_.tx_engine().Commit(transaction_);
|
||||
db_->tx_engine().Commit(*transaction_);
|
||||
commited_ = true;
|
||||
}
|
||||
|
||||
void GraphDbAccessor::Abort() {
|
||||
DCHECK(!commited_ && !aborted_) << "Already aborted or commited transaction.";
|
||||
db_.tx_engine().Abort(transaction_);
|
||||
db_->tx_engine().Abort(*transaction_);
|
||||
aborted_ = true;
|
||||
}
|
||||
|
||||
bool GraphDbAccessor::should_abort() const {
|
||||
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(
|
||||
std::experimental::optional<gid::Gid> requested_gid) {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
|
||||
auto gid = db_.storage().vertex_generator_.Next(requested_gid);
|
||||
auto vertex_vlist = new mvcc::VersionList<Vertex>(transaction_, gid);
|
||||
auto gid = db_->storage().vertex_generator_.Next(requested_gid);
|
||||
auto vertex_vlist = new mvcc::VersionList<Vertex>(*transaction_, gid);
|
||||
|
||||
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: "
|
||||
<< gid;
|
||||
raft()->Emplace(
|
||||
database::StateDelta::CreateVertex(transaction_.id_, vertex_vlist->gid_));
|
||||
database::StateDelta::CreateVertex(transaction_->id_, vertex_vlist->gid_));
|
||||
auto va = VertexAccessor(vertex_vlist, *this);
|
||||
return va;
|
||||
}
|
||||
|
||||
std::experimental::optional<VertexAccessor> GraphDbAccessor::FindVertexOptional(
|
||||
gid::Gid gid, bool current_state) {
|
||||
VertexAccessor record_accessor(db_.storage().LocalAddress<Vertex>(gid),
|
||||
VertexAccessor record_accessor(db_->storage().LocalAddress<Vertex>(gid),
|
||||
*this);
|
||||
if (!record_accessor.Visible(transaction(), current_state))
|
||||
return std::experimental::nullopt;
|
||||
@ -100,7 +125,7 @@ VertexAccessor GraphDbAccessor::FindVertex(gid::Gid gid, bool current_state) {
|
||||
|
||||
std::experimental::optional<EdgeAccessor> GraphDbAccessor::FindEdgeOptional(
|
||||
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))
|
||||
return std::experimental::nullopt;
|
||||
return record_accessor;
|
||||
@ -118,7 +143,7 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
|
||||
|
||||
// Create the index
|
||||
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(
|
||||
"Index is either being created by another transaction or already "
|
||||
"exists.");
|
||||
@ -126,16 +151,16 @@ void GraphDbAccessor::BuildIndex(storage::Label label,
|
||||
|
||||
try {
|
||||
auto dba =
|
||||
db_.AccessBlocking(std::experimental::make_optional(transaction_.id_));
|
||||
db_->AccessBlocking(std::experimental::make_optional(transaction_->id_));
|
||||
|
||||
dba->PopulateIndex(key);
|
||||
dba->EnableIndex(key);
|
||||
dba->Commit();
|
||||
dba.PopulateIndex(key);
|
||||
dba.EnableIndex(key);
|
||||
dba.Commit();
|
||||
} catch (const IndexConstraintViolationException &) {
|
||||
db_.storage().label_property_index_.DeleteIndex(key);
|
||||
db_->storage().label_property_index_.DeleteIndex(key);
|
||||
throw;
|
||||
} catch (const tx::TransactionEngineError &e) {
|
||||
db_.storage().label_property_index_.DeleteIndex(key);
|
||||
db_->storage().label_property_index_.DeleteIndex(key);
|
||||
throw IndexTransactionException(e.what());
|
||||
}
|
||||
}
|
||||
@ -153,7 +178,7 @@ void GraphDbAccessor::PopulateIndex(const LabelPropertyIndex::Key &key) {
|
||||
for (auto vertex : Vertices(key.label_, false)) {
|
||||
if (vertex.PropsAt(key.property_).type() == PropertyValue::Type::Null)
|
||||
continue;
|
||||
if (!db_.storage().label_property_index_.UpdateOnLabelProperty(
|
||||
if (!db_->storage().label_property_index_.UpdateOnLabelProperty(
|
||||
vertex.address(), vertex.current_)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"Index couldn't be created due to constraint violation!");
|
||||
@ -168,14 +193,14 @@ void GraphDbAccessor::DeleteIndex(storage::Label label,
|
||||
LabelPropertyIndex::Key key(label, property);
|
||||
try {
|
||||
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);
|
||||
dba->raft()->Emplace(database::StateDelta::DropIndex(
|
||||
dba->transaction_id(), key.label_, LabelName(key.label_), key.property_,
|
||||
db_->storage().label_property_index_.DeleteIndex(key);
|
||||
dba.raft()->Emplace(database::StateDelta::DropIndex(
|
||||
dba.transaction_id(), key.label_, LabelName(key.label_), key.property_,
|
||||
PropertyName(key.property_)));
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
} catch (const tx::TransactionEngineError &e) {
|
||||
throw IndexTransactionException(e.what());
|
||||
}
|
||||
@ -187,19 +212,19 @@ void GraphDbAccessor::UpdateLabelIndices(storage::Label label,
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"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(
|
||||
storage::Property property, const RecordAccessor<Vertex> &vertex_accessor,
|
||||
const Vertex *const vertex) {
|
||||
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)) {
|
||||
throw IndexConstraintViolationException(
|
||||
"Node couldn't be updated due to index constraint violation!");
|
||||
@ -208,21 +233,21 @@ void GraphDbAccessor::UpdatePropertyIndex(
|
||||
|
||||
int64_t GraphDbAccessor::VerticesCount() const {
|
||||
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 {
|
||||
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,
|
||||
storage::Property property) const {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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.";
|
||||
return db_.storage().label_property_index_.Count(key);
|
||||
return db_->storage().label_property_index_.Count(key);
|
||||
}
|
||||
|
||||
int64_t GraphDbAccessor::VerticesCount(storage::Label label,
|
||||
@ -230,9 +255,9 @@ int64_t GraphDbAccessor::VerticesCount(storage::Label label,
|
||||
const PropertyValue &value) const {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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.";
|
||||
return db_.storage()
|
||||
return db_->storage()
|
||||
.label_property_index_.PositionAndCount(key, value)
|
||||
.second;
|
||||
}
|
||||
@ -244,7 +269,7 @@ int64_t GraphDbAccessor::VerticesCount(
|
||||
const {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
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.";
|
||||
CHECK(lower || upper) << "At least one bound must be provided";
|
||||
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";
|
||||
|
||||
if (!upper) {
|
||||
auto lower_pac = db_.storage().label_property_index_.PositionAndCount(
|
||||
auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
|
||||
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,
|
||||
size - lower_pac.first -
|
||||
(lower.value().IsInclusive() ? 0l : lower_pac.second));
|
||||
|
||||
} 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());
|
||||
return upper.value().IsInclusive() ? upper_pac.first + upper_pac.second
|
||||
: upper_pac.first;
|
||||
|
||||
} else {
|
||||
auto lower_pac = db_.storage().label_property_index_.PositionAndCount(
|
||||
auto lower_pac = db_->storage().label_property_index_.PositionAndCount(
|
||||
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());
|
||||
auto result = upper_pac.first - lower_pac.first;
|
||||
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
|
||||
// due to it getting matched multiple times by some patterns
|
||||
// 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 &&
|
||||
vertex_accessor.out_degree() + vertex_accessor.in_degree() > 0)
|
||||
return false;
|
||||
|
||||
auto *vlist_ptr = vertex_accessor.address();
|
||||
raft()->Emplace(database::StateDelta::RemoveVertex(
|
||||
transaction_.id_, vlist_ptr->gid_, check_empty));
|
||||
vlist_ptr->remove(vertex_accessor.current_, transaction_);
|
||||
transaction_->id_, vlist_ptr->gid_, check_empty));
|
||||
vlist_ptr->remove(vertex_accessor.current_, *transaction_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -318,13 +343,13 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
|
||||
VertexAccessor &from, VertexAccessor &to, storage::EdgeType edge_type,
|
||||
std::experimental::optional<gid::Gid> requested_gid) {
|
||||
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>(
|
||||
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
|
||||
// can throw and edge_vlist will not be garbage collected if it is not in
|
||||
// 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: "
|
||||
<< gid;
|
||||
|
||||
@ -339,7 +364,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
|
||||
to.update().in_.emplace(from.address(), edge_vlist, edge_type);
|
||||
|
||||
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)));
|
||||
|
||||
return EdgeAccessor(edge_vlist, *this, from.address(), to.address(),
|
||||
@ -348,7 +373,7 @@ EdgeAccessor GraphDbAccessor::InsertEdge(
|
||||
|
||||
int64_t GraphDbAccessor::EdgesCount() const {
|
||||
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,
|
||||
@ -358,61 +383,61 @@ void GraphDbAccessor::RemoveEdge(EdgeAccessor &edge, bool remove_out_edge,
|
||||
// due to it getting matched multiple times by some patterns
|
||||
// we can only delete it once, so check if it's already deleted
|
||||
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_in_edge) edge.to().RemoveInEdge(edge.address());
|
||||
|
||||
edge.address()->remove(edge.current_, transaction_);
|
||||
raft()->Emplace(database::StateDelta::RemoveEdge(transaction_.id_, edge.gid()));
|
||||
edge.address()->remove(edge.current_, *transaction_);
|
||||
raft()->Emplace(database::StateDelta::RemoveEdge(transaction_->id_, edge.gid()));
|
||||
}
|
||||
|
||||
storage::Label GraphDbAccessor::Label(const std::string &label_name) {
|
||||
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 {
|
||||
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) {
|
||||
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(
|
||||
storage::EdgeType edge_type) const {
|
||||
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) {
|
||||
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(
|
||||
storage::Property property) const {
|
||||
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) {
|
||||
return db_.counters().Get(name);
|
||||
return db_->counters().Get(name);
|
||||
}
|
||||
|
||||
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> info;
|
||||
for (storage::Label label : db_.storage().labels_index_.Keys()) {
|
||||
for (storage::Label label : db_->storage().labels_index_.Keys()) {
|
||||
info.emplace_back(":" + LabelName(label));
|
||||
}
|
||||
for (LabelPropertyIndex::Key key :
|
||||
db_.storage().label_property_index_.Keys()) {
|
||||
db_->storage().label_property_index_.Keys()) {
|
||||
info.emplace_back(fmt::format(":{}({}){}", LabelName(key.label_),
|
||||
PropertyName(key.property_),
|
||||
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>>>
|
||||
GraphDbAccessor::StorageInfo() const {
|
||||
return db_.storage_info()->GetStorageInfo();
|
||||
return db_->storage_info()->GetStorageInfo();
|
||||
}
|
||||
|
||||
} // namespace database
|
||||
|
@ -64,20 +64,21 @@ class GraphDbAccessor {
|
||||
// concrete GraphDbAccessor type.
|
||||
|
||||
/// Creates a new accessor by starting a new transaction.
|
||||
explicit GraphDbAccessor(GraphDb &db);
|
||||
explicit GraphDbAccessor(GraphDb *db);
|
||||
/// 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);
|
||||
|
||||
public:
|
||||
~GraphDbAccessor();
|
||||
|
||||
GraphDbAccessor(const GraphDbAccessor &other) = delete;
|
||||
GraphDbAccessor(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
|
||||
@ -164,7 +165,7 @@ class GraphDbAccessor {
|
||||
[this](auto id_vlist) {
|
||||
return VertexAccessor(id_vlist.second, *this);
|
||||
},
|
||||
db_.storage().vertices_.access());
|
||||
db_->storage().vertices_.access());
|
||||
|
||||
// filter out the accessors not visible to the current transaction
|
||||
return iter::filter(
|
||||
@ -188,7 +189,7 @@ class GraphDbAccessor {
|
||||
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
|
||||
return iter::imap(
|
||||
[this](auto vlist) { return VertexAccessor(vlist, *this); },
|
||||
db_.storage().labels_index_.GetVlists(label, transaction_,
|
||||
db_->storage().labels_index_.GetVlists(label, *transaction_,
|
||||
current_state));
|
||||
}
|
||||
|
||||
@ -207,13 +208,13 @@ class GraphDbAccessor {
|
||||
auto Vertices(storage::Label label, storage::Property property,
|
||||
bool current_state) {
|
||||
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)))
|
||||
<< "Label+property index doesn't exist.";
|
||||
return iter::imap(
|
||||
[this](auto vlist) { return VertexAccessor(vlist, *this); },
|
||||
db_.storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), transaction_,
|
||||
db_->storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), *transaction_,
|
||||
current_state));
|
||||
}
|
||||
|
||||
@ -233,15 +234,15 @@ class GraphDbAccessor {
|
||||
auto Vertices(storage::Label label, storage::Property property,
|
||||
const PropertyValue &value, bool current_state) {
|
||||
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)))
|
||||
<< "Label+property index doesn't exist.";
|
||||
CHECK(value.type() != PropertyValue::Type::Null)
|
||||
<< "Can't query index for propery value type null.";
|
||||
return iter::imap(
|
||||
[this](auto vlist) { return VertexAccessor(vlist, *this); },
|
||||
db_.storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), value, transaction_,
|
||||
db_->storage().label_property_index_.GetVlists(
|
||||
LabelPropertyIndex::Key(label, property), value, *transaction_,
|
||||
current_state));
|
||||
}
|
||||
|
||||
@ -278,14 +279,14 @@ class GraphDbAccessor {
|
||||
const std::experimental::optional<utils::Bound<PropertyValue>> upper,
|
||||
bool current_state) {
|
||||
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)))
|
||||
<< "Label+property index doesn't exist.";
|
||||
return iter::imap(
|
||||
[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,
|
||||
transaction_, current_state));
|
||||
*transaction_, current_state));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,7 +370,7 @@ class GraphDbAccessor {
|
||||
// wrap version lists into accessors, which will look for visible versions
|
||||
auto accessors = iter::imap(
|
||||
[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
|
||||
return iter::filter(
|
||||
@ -448,7 +449,7 @@ class GraphDbAccessor {
|
||||
bool LabelPropertyIndexExists(storage::Label label,
|
||||
storage::Property property) const {
|
||||
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));
|
||||
}
|
||||
|
||||
@ -457,7 +458,7 @@ class GraphDbAccessor {
|
||||
*/
|
||||
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
|
||||
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. */
|
||||
bool should_abort() const;
|
||||
|
||||
const tx::Transaction &transaction() const { return transaction_; }
|
||||
const tx::Transaction &transaction() const { return *transaction_; }
|
||||
raft::RaftInterface *raft();
|
||||
auto &db() { return db_; }
|
||||
const auto &db() const { return db_; }
|
||||
@ -622,8 +623,8 @@ class GraphDbAccessor {
|
||||
const Vertex *const vertex);
|
||||
|
||||
private:
|
||||
GraphDb &db_;
|
||||
tx::Transaction &transaction_;
|
||||
GraphDb *db_;
|
||||
tx::Transaction *transaction_;
|
||||
// Indicates if this db-accessor started the transaction and should Abort it
|
||||
// upon destruction.
|
||||
bool transaction_starter_;
|
||||
|
@ -206,13 +206,13 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
|
||||
Value vertex_dv;
|
||||
RETURN_IF_NOT(decoder.ReadValue(&vertex_dv, Value::Type::Vertex));
|
||||
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) {
|
||||
vertex_accessor.add_label(dba->Label(label));
|
||||
vertex_accessor.add_label(dba.Label(label));
|
||||
}
|
||||
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));
|
||||
}
|
||||
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());
|
||||
RETURN_IF_NOT(it_from != vertices.end() && it_to != vertices.end());
|
||||
auto edge_accessor =
|
||||
dba->InsertEdge(it_from->second, it_to->second,
|
||||
dba->EdgeType(edge.type), edge.id.AsUint());
|
||||
dba.InsertEdge(it_from->second, it_to->second,
|
||||
dba.EdgeType(edge.type), edge.id.AsUint());
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
|
||||
reader.ReadType(vertex_count);
|
||||
reader.ReadType(edge_count);
|
||||
if (!reader.Close() || reader.hash() != hash) {
|
||||
dba->Abort();
|
||||
dba.Abort();
|
||||
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;
|
||||
auto &snap = recovery_data->snapshooter_tx_snapshot;
|
||||
if (!snap.empty()) max_id = *std::max_element(snap.begin(), snap.end());
|
||||
dba->db().tx_engine().EnsureNextIdGreater(max_id);
|
||||
dba->Commit();
|
||||
dba.db().tx_engine().EnsureNextIdGreater(max_id);
|
||||
dba.Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -384,7 +384,7 @@ RecoveryTransactions::RecoveryTransactions(database::GraphDb *db) : db_(db) {}
|
||||
void RecoveryTransactions::Begin(const tx::TransactionId &tx_id) {
|
||||
CHECK(accessors_.find(tx_id) == accessors_.end())
|
||||
<< "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) {
|
||||
@ -599,15 +599,15 @@ void RecoverIndexes(database::GraphDb *db,
|
||||
const std::vector<IndexRecoveryData> &indexes) {
|
||||
auto dba = db->Access();
|
||||
for (const auto &index : indexes) {
|
||||
auto label = dba->Label(index.label);
|
||||
auto property = dba->Property(index.property);
|
||||
auto label = dba.Label(index.label);
|
||||
auto property = dba.Property(index.property);
|
||||
if (index.create) {
|
||||
dba->BuildIndex(label, property, index.unique);
|
||||
dba.BuildIndex(label, property, index.unique);
|
||||
} else {
|
||||
dba->DeleteIndex(label, property);
|
||||
dba.DeleteIndex(label, property);
|
||||
}
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
void RecoverExistenceConstraints(
|
||||
@ -615,17 +615,17 @@ void RecoverExistenceConstraints(
|
||||
const std::vector<ExistenceConstraintRecoveryData> &constraints) {
|
||||
auto dba = db->Access();
|
||||
for (auto &constraint : constraints) {
|
||||
auto label = dba->Label(constraint.label);
|
||||
auto label = dba.Label(constraint.label);
|
||||
std::vector<storage::Property> properties;
|
||||
properties.reserve(constraint.properties.size());
|
||||
for (auto &prop : constraint.properties) {
|
||||
properties.push_back(dba->Property(prop));
|
||||
properties.push_back(dba.Property(prop));
|
||||
}
|
||||
|
||||
if (constraint.create) {
|
||||
dba->BuildExistenceConstraint(label, properties);
|
||||
dba.BuildExistenceConstraint(label, properties);
|
||||
} else {
|
||||
dba->DeleteExistenceConstraint(label, properties);
|
||||
dba.DeleteExistenceConstraint(label, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -635,19 +635,19 @@ void RecoverUniqueConstraints(
|
||||
const std::vector<UniqueConstraintRecoveryData> &constraints) {
|
||||
auto dba = db->Access();
|
||||
for (auto &constraint : constraints) {
|
||||
auto label = dba->Label(constraint.label);
|
||||
auto label = dba.Label(constraint.label);
|
||||
std::vector<storage::Property> properties;
|
||||
properties.reserve(constraint.properties.size());
|
||||
for (auto &prop : constraint.properties) {
|
||||
properties.push_back(dba->Property(prop));
|
||||
properties.push_back(dba.Property(prop));
|
||||
}
|
||||
|
||||
DCHECK(properties.size() == 1)
|
||||
<< "Unique constraint with multiple properties is not supported";
|
||||
if (constraint.create) {
|
||||
dba->BuildUniqueConstraint(label, properties[0]);
|
||||
dba.BuildUniqueConstraint(label, properties[0]);
|
||||
} else {
|
||||
dba->DeleteUniqueConstraint(label, properties[0]);
|
||||
dba.DeleteUniqueConstraint(label, properties[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,13 +94,13 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
|
||||
Value vertex_dv;
|
||||
RETURN_IF_NOT(decoder.ReadValue(&vertex_dv, Value::Type::Vertex));
|
||||
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) {
|
||||
vertex_accessor.add_label(dba->Label(label));
|
||||
vertex_accessor.add_label(dba.Label(label));
|
||||
}
|
||||
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));
|
||||
}
|
||||
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());
|
||||
RETURN_IF_NOT(it_from != vertices.end() && it_to != vertices.end());
|
||||
auto edge_accessor =
|
||||
dba->InsertEdge(it_from->second, it_to->second,
|
||||
dba->EdgeType(edge.type), edge.id.AsUint());
|
||||
dba.InsertEdge(it_from->second, it_to->second,
|
||||
dba.EdgeType(edge.type), edge.id.AsUint());
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ bool RecoverSnapshot(const fs::path &snapshot_file, database::GraphDb *db,
|
||||
reader.ReadType(vertex_count);
|
||||
reader.ReadType(edge_count);
|
||||
if (!reader.Close() || reader.hash() != hash) {
|
||||
dba->Abort();
|
||||
dba.Abort();
|
||||
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;
|
||||
auto &snap = recovery_data->snapshooter_tx_snapshot;
|
||||
if (!snap.empty()) max_id = *std::max_element(snap.begin(), snap.end());
|
||||
dba->db().tx_engine().EnsureNextIdGreater(max_id);
|
||||
dba->Commit();
|
||||
dba.db()->tx_engine().EnsureNextIdGreater(max_id);
|
||||
dba.Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -176,15 +176,15 @@ void RecoverIndexes(database::GraphDb *db,
|
||||
const std::vector<IndexRecoveryData> &indexes) {
|
||||
auto dba = db->Access();
|
||||
for (const auto &index : indexes) {
|
||||
auto label = dba->Label(index.label);
|
||||
auto property = dba->Property(index.property);
|
||||
auto label = dba.Label(index.label);
|
||||
auto property = dba.Property(index.property);
|
||||
if (index.create) {
|
||||
dba->BuildIndex(label, property, index.unique);
|
||||
dba.BuildIndex(label, property, index.unique);
|
||||
} else {
|
||||
dba->DeleteIndex(label, property);
|
||||
dba.DeleteIndex(label, property);
|
||||
}
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
} // namespace durability
|
||||
|
@ -131,7 +131,7 @@ void SingleNodeMain() {
|
||||
durability_directory / "telemetry", std::chrono::minutes(10));
|
||||
telemetry->AddCollector("db", [&db]() -> nlohmann::json {
|
||||
auto dba = db.Access();
|
||||
return {{"vertices", dba->VerticesCount()}, {"edges", dba->EdgesCount()}};
|
||||
return {{"vertices", dba.VerticesCount()}, {"edges", dba.EdgesCount()}};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -124,12 +124,21 @@ void KafkaStreamWriter(
|
||||
for (const auto &kv : params)
|
||||
params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
|
||||
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);
|
||||
dba->Commit();
|
||||
#endif
|
||||
} catch (const utils::BasicException &e) {
|
||||
LOG(WARNING) << "[Kafka] query execution failed with an exception: "
|
||||
<< e.what();
|
||||
#ifndef MG_DISTRIBUTED
|
||||
dba.Abort();
|
||||
#else
|
||||
dba->Abort();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -63,12 +63,20 @@ void query::Repl(database::GraphDb *db, query::Interpreter *interpreter) {
|
||||
try {
|
||||
auto dba = db->Access();
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
#ifndef MG_DISTRIBUTED
|
||||
auto results = (*interpreter)(command, dba, {}, false);
|
||||
#else
|
||||
auto results = (*interpreter)(command, *dba, {}, false);
|
||||
#endif
|
||||
stream.Header(results.header());
|
||||
results.PullAll(stream);
|
||||
stream.Summary(results.summary());
|
||||
std::cout << stream;
|
||||
#ifndef MG_DISTRIBUTED
|
||||
dba.Commit();
|
||||
#else
|
||||
dba->Commit();
|
||||
#endif
|
||||
} catch (const query::SyntaxException &e) {
|
||||
std::cout << "SYNTAX EXCEPTION: " << e.what() << std::endl;
|
||||
} catch (const query::LexingException &e) {
|
||||
|
@ -58,7 +58,11 @@ class TransactionEngine final {
|
||||
if (in_explicit_transaction_ && db_accessor_) AdvanceCommand();
|
||||
|
||||
// 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();
|
||||
#endif
|
||||
|
||||
// Interpret the query and return the headers.
|
||||
try {
|
||||
@ -104,13 +108,21 @@ class TransactionEngine final {
|
||||
in_explicit_transaction_ = false;
|
||||
if (!db_accessor_) return;
|
||||
db_accessor_->Abort();
|
||||
#ifndef MG_DISTRIBUTED
|
||||
db_accessor_ = std::experimental::nullopt;
|
||||
#else
|
||||
db_accessor_ = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
database::GraphDb *db_{nullptr};
|
||||
Interpreter *interpreter_{nullptr};
|
||||
#ifndef MG_DISTRIBUTED
|
||||
std::experimental::optional<database::GraphDbAccessor> db_accessor_;
|
||||
#else
|
||||
std::unique_ptr<database::GraphDbAccessor> db_accessor_;
|
||||
#endif
|
||||
// The `query::Interpreter::Results` object MUST be destroyed before the
|
||||
// `database::GraphDbAccessor` is destroyed because the `Results` object holds
|
||||
// references to the `GraphDb` object and will crash the database when
|
||||
@ -123,7 +135,11 @@ class TransactionEngine final {
|
||||
results_ = std::experimental::nullopt;
|
||||
if (!db_accessor_) return;
|
||||
db_accessor_->Commit();
|
||||
#ifndef MG_DISTRIBUTED
|
||||
db_accessor_ = std::experimental::nullopt;
|
||||
#else
|
||||
db_accessor_ = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AdvanceCommand() {
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <kj/std/iostream.h>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <experimental/optional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
@ -982,20 +983,28 @@ void RaftServer::SnapshotThread() {
|
||||
// Compare the log size to the config
|
||||
if (config_.log_size_snapshot_threshold < committed_log_size) {
|
||||
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();
|
||||
VLOG(40) << "[LogCompaction] Creating snapshot.";
|
||||
bool status = durability::MakeSnapshot(*db_, *dba, durability_dir_,
|
||||
snapshot_filename);
|
||||
uint64_t last_included_term = 0;
|
||||
uint64_t last_included_index = 0;
|
||||
std::string 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();
|
||||
|
||||
@ -1187,13 +1196,13 @@ void RaftServer::RecoverSnapshot(const std::string &snapshot_filename) {
|
||||
|
||||
void RaftServer::NoOpCreate() {
|
||||
auto dba = db_->Access();
|
||||
Emplace(database::StateDelta::NoOp(dba->transaction_id()));
|
||||
dba->Commit();
|
||||
Emplace(database::StateDelta::NoOp(dba.transaction_id()));
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
void RaftServer::ApplyStateDeltas(
|
||||
const std::vector<database::StateDelta> &deltas) {
|
||||
std::unique_ptr<database::GraphDbAccessor> dba = nullptr;
|
||||
std::experimental::optional<database::GraphDbAccessor> dba;
|
||||
for (auto &delta : deltas) {
|
||||
switch (delta.type) {
|
||||
case database::StateDelta::Type::TRANSACTION_BEGIN:
|
||||
@ -1204,7 +1213,7 @@ void RaftServer::ApplyStateDeltas(
|
||||
CHECK(dba) << "Missing accessor for transaction"
|
||||
<< delta.transaction_id;
|
||||
dba->Commit();
|
||||
dba = nullptr;
|
||||
dba = std::experimental::nullopt;
|
||||
break;
|
||||
case database::StateDelta::Type::TRANSACTION_ABORT:
|
||||
LOG(FATAL) << "ApplyStateDeltas shouldn't know about aborted "
|
||||
|
@ -59,15 +59,15 @@ void Run(benchmark::State &state, bool enable_constraint) {
|
||||
state.PauseTiming();
|
||||
for (size_t i = 0; i < kNumOfConstraints; ++i) {
|
||||
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;
|
||||
props.reserve(kNumOfPropsInConstraint);
|
||||
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)));
|
||||
}
|
||||
dba->BuildExistenceConstraint(label, props);
|
||||
dba->Commit();
|
||||
dba.BuildExistenceConstraint(label, props);
|
||||
dba.Commit();
|
||||
}
|
||||
state.ResumeTiming();
|
||||
}
|
||||
@ -77,37 +77,37 @@ void Run(benchmark::State &state, bool enable_constraint) {
|
||||
vertices.reserve(kNumOfVertices);
|
||||
for (size_t k = 0; k < kNumOfVertices; ++k) {
|
||||
auto dba = db.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
vertices.push_back(v.gid());
|
||||
|
||||
// Labels and properties that define constraints
|
||||
for (size_t i = 0; i < kNumOfConstraints; ++i) {
|
||||
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)),
|
||||
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);
|
||||
}
|
||||
|
||||
// Add other labels
|
||||
for (auto label : test_set.labels) {
|
||||
v.add_label(dba->Label(label));
|
||||
v.add_label(dba.Label(label));
|
||||
}
|
||||
|
||||
// Add other properties
|
||||
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
|
||||
for (auto gid : vertices) {
|
||||
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());
|
||||
for (auto &label : labels_to_del) {
|
||||
v.remove_label(label);
|
||||
@ -119,9 +119,9 @@ void Run(benchmark::State &state, bool enable_constraint) {
|
||||
// Delete all vertices
|
||||
for (auto gid : vertices) {
|
||||
auto dba = db.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
dba->RemoveVertex(v);
|
||||
dba->Commit();
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
dba.RemoveVertex(v);
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,23 +18,23 @@ class ExpansionBenchFixture : public benchmark::Fixture {
|
||||
void SetUp(const benchmark::State &state) override {
|
||||
db_.emplace();
|
||||
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
|
||||
auto start = dba->InsertVertex();
|
||||
start.add_label(dba->Label("Starting"));
|
||||
auto edge_type = dba->EdgeType("edge_type");
|
||||
auto start = dba.InsertVertex();
|
||||
start.add_label(dba.Label("Starting"));
|
||||
auto edge_type = dba.EdgeType("edge_type");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
auto dest = dba->InsertVertex();
|
||||
dba->InsertEdge(start, dest, edge_type);
|
||||
auto dest = dba.InsertVertex();
|
||||
dba.InsertEdge(start, dest, edge_type);
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
void TearDown(const benchmark::State &) override {
|
||||
auto dba = db_->Access();
|
||||
for (auto vertex : dba->Vertices(false)) dba->DetachRemoveVertex(vertex);
|
||||
dba->Commit();
|
||||
for (auto vertex : dba.Vertices(false)) dba.DetachRemoveVertex(vertex);
|
||||
dba.Commit();
|
||||
db_ = std::experimental::nullopt;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ BENCHMARK_DEFINE_F(ExpansionBenchFixture, Match)(benchmark::State &state) {
|
||||
auto dba = db_->Access();
|
||||
while (state.KeepRunning()) {
|
||||
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();
|
||||
while (state.KeepRunning()) {
|
||||
ResultStreamFaker<query::TypedValue> results;
|
||||
interpreter()(query, *dba, {}, false).PullAll(results);
|
||||
interpreter()(query, dba, {}, false).PullAll(results);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ static void BM_PlanChainedMatches(benchmark::State &state) {
|
||||
auto *query = AddChainedMatches(num_matches, storage);
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query,
|
||||
dba.get());
|
||||
&dba);
|
||||
state.ResumeTiming();
|
||||
auto query_parts =
|
||||
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,
|
||||
database::GraphDb &db) {
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
auto dba = db.Access();
|
||||
for (int vi = 0; vi < vertex_count; ++vi) {
|
||||
for (int index = 0; index < index_count; ++index) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(prop, index);
|
||||
}
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
return std::make_pair("label", "prop");
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
state.ResumeTiming();
|
||||
auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query,
|
||||
dba.get());
|
||||
&dba);
|
||||
auto query_parts =
|
||||
query::plan::CollectQueryParts(symbol_table, storage, query);
|
||||
if (query_parts.query_parts.size() == 0) {
|
||||
@ -132,7 +132,7 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
auto plans = query::plan::MakeLogicalPlanForSingleQuery<
|
||||
query::plan::VariableStartPlanner>(single_query_parts, &ctx);
|
||||
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);
|
||||
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db);
|
||||
auto dba = db.Access();
|
||||
auto vertex_counts = query::plan::MakeVertexCountCache(dba.get());
|
||||
auto vertex_counts = query::plan::MakeVertexCountCache(&dba);
|
||||
query::Parameters parameters;
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
|
@ -14,6 +14,6 @@ int main(int argc, char *argv[]) {
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
RunInteractivePlanning(dba.get());
|
||||
RunInteractivePlanning(&dba);
|
||||
return 0;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class RandomGraphGenerator {
|
||||
auto dba = db_.Access();
|
||||
std::vector<storage::Label> labels;
|
||||
for (const auto &label_name : label_names)
|
||||
labels.push_back(dba->Label(label_name));
|
||||
labels.push_back(dba.Label(label_name));
|
||||
|
||||
Map(
|
||||
[&labels, this](database::GraphDbAccessor &dba) {
|
||||
@ -77,7 +77,7 @@ class RandomGraphGenerator {
|
||||
*/
|
||||
int64_t VertexCount() const {
|
||||
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 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
|
||||
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(
|
||||
[&vertices_from, &vertices_to, edge_type,
|
||||
@ -129,7 +129,7 @@ class RandomGraphGenerator {
|
||||
*/
|
||||
int64_t EdgeCount() const {
|
||||
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 = {}) {
|
||||
if (!predicate) predicate = [](VertexAccessor &) { return true; };
|
||||
auto dba = db_.Access();
|
||||
auto property = dba->Property(prop_name);
|
||||
for (VertexAccessor va : dba->Vertices(false))
|
||||
auto property = dba.Property(prop_name);
|
||||
for (VertexAccessor va : dba.Vertices(false))
|
||||
if (predicate(va)) va.PropsSet(property, value_generator());
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
private:
|
||||
@ -176,7 +176,7 @@ class RandomGraphGenerator {
|
||||
if (!predicate) predicate = [](VertexAccessor &) { return true; };
|
||||
std::vector<VertexAccessor> r_val;
|
||||
auto dba = db_.Access();
|
||||
for (VertexAccessor &item : dba->Vertices(false))
|
||||
for (VertexAccessor &item : dba.Vertices(false))
|
||||
if (predicate(item)) r_val.emplace_back(item);
|
||||
|
||||
return r_val;
|
||||
@ -211,9 +211,9 @@ class RandomGraphGenerator {
|
||||
int apply_count =
|
||||
std::min(elements_per_commit, count_per_thread - i);
|
||||
while (apply_count--) {
|
||||
f(*dba);
|
||||
f(dba);
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
break;
|
||||
} catch (...) {
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ int main(int argc, char *argv[]) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
auto results = query::Interpreter()(argv[1], *dba, {}, false);
|
||||
auto results = query::Interpreter()(argv[1], dba, {}, false);
|
||||
stream.Header(results.header());
|
||||
results.PullAll(stream);
|
||||
stream.Summary(results.summary());
|
||||
|
@ -32,8 +32,8 @@ RC_GTEST_PROP(RandomGraph, RandomGraph, (std::vector<std::string> vertex_labels,
|
||||
auto dba = db.Access();
|
||||
|
||||
for (auto label : vertex_labels) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
vertex_accessor.add_label(dba->Label(label));
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(dba.Label(label));
|
||||
vertex_label_map.insert({vertex_accessor, label});
|
||||
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) {
|
||||
auto from = 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});
|
||||
}
|
||||
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
int edges_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);
|
||||
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++;
|
||||
}
|
||||
for (const auto &edge : dba->Edges(false)) {
|
||||
for (const auto &edge : dba.Edges(false)) {
|
||||
auto type = edge_type_map.at(edge);
|
||||
RC_ASSERT(dba->EdgeTypeName(edge.EdgeType()) == type);
|
||||
RC_ASSERT(dba.EdgeTypeName(edge.EdgeType()) == type);
|
||||
edges_num_check++;
|
||||
}
|
||||
RC_ASSERT(vertices_num_check == vertices_num);
|
||||
|
@ -8,12 +8,14 @@ class SingleNodeDb : public Database {
|
||||
SingleNodeDb() : db_() {}
|
||||
|
||||
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 {
|
||||
auto dba = db_.Access(tx_id);
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
std::unique_ptr<LogicalOperator> MakeBfsOperator(
|
||||
|
@ -166,23 +166,23 @@ TEST(BoltEncoder, VertexAndEdge) {
|
||||
// create vertex
|
||||
database::GraphDb db;
|
||||
auto db_accessor = db.Access();
|
||||
auto va1 = db_accessor->InsertVertex();
|
||||
auto va2 = db_accessor->InsertVertex();
|
||||
auto l1 = db_accessor->Label("label1");
|
||||
auto l2 = db_accessor->Label("label2");
|
||||
auto va1 = db_accessor.InsertVertex();
|
||||
auto va2 = db_accessor.InsertVertex();
|
||||
auto l1 = db_accessor.Label("label1");
|
||||
auto l2 = db_accessor.Label("label2");
|
||||
va1.add_label(l1);
|
||||
va1.add_label(l2);
|
||||
auto p1 = db_accessor->Property("prop1");
|
||||
auto p2 = db_accessor->Property("prop2");
|
||||
auto p1 = db_accessor.Property("prop1");
|
||||
auto p2 = db_accessor.Property("prop2");
|
||||
PropertyValue pv1(12), pv2(200);
|
||||
va1.PropsSet(p1, pv1);
|
||||
va1.PropsSet(p2, pv2);
|
||||
|
||||
// create edge
|
||||
auto et = db_accessor->EdgeType("edgetype");
|
||||
auto ea = db_accessor->InsertEdge(va1, va2, et);
|
||||
auto p3 = db_accessor->Property("prop3");
|
||||
auto p4 = db_accessor->Property("prop4");
|
||||
auto et = db_accessor.EdgeType("edgetype");
|
||||
auto ea = db_accessor.InsertEdge(va1, va2, et);
|
||||
auto p3 = db_accessor.Property("prop3");
|
||||
auto p4 = db_accessor.Property("prop4");
|
||||
PropertyValue pv3(42), pv4(1234);
|
||||
ea.PropsSet(p3, pv3);
|
||||
ea.PropsSet(p4, pv4);
|
||||
|
@ -23,21 +23,21 @@ TEST(LabelsIndex, UniqueInsert) {
|
||||
engine.Commit(*t1);
|
||||
auto t2 = engine.Begin();
|
||||
|
||||
vlist.find(*t2)->labels_.push_back(dba->Label("1"));
|
||||
index.Update(dba->Label("1"), &vlist, vlist.find(*t2));
|
||||
vlist.find(*t2)->labels_.push_back(dba.Label("1"));
|
||||
index.Update(dba.Label("1"), &vlist, vlist.find(*t2));
|
||||
// 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"));
|
||||
index.Update(dba->Label("2"), &vlist, vlist.find(*t2));
|
||||
vlist.find(*t2)->labels_.push_back(dba.Label("2"));
|
||||
index.Update(dba.Label("2"), &vlist, vlist.find(*t2));
|
||||
|
||||
vlist.find(*t2)->labels_.push_back(dba->Label("3"));
|
||||
index.Update(dba->Label("3"), &vlist, vlist.find(*t2));
|
||||
vlist.find(*t2)->labels_.push_back(dba.Label("3"));
|
||||
index.Update(dba.Label("3"), &vlist, vlist.find(*t2));
|
||||
engine.Commit(*t2);
|
||||
|
||||
EXPECT_EQ(index.Count(dba->Label("1")), 1);
|
||||
EXPECT_EQ(index.Count(dba->Label("2")), 1);
|
||||
EXPECT_EQ(index.Count(dba->Label("3")), 1);
|
||||
EXPECT_EQ(index.Count(dba.Label("1")), 1);
|
||||
EXPECT_EQ(index.Count(dba.Label("2")), 1);
|
||||
EXPECT_EQ(index.Count(dba.Label("3")), 1);
|
||||
}
|
||||
|
||||
// Check if index filters duplicates.
|
||||
@ -55,7 +55,7 @@ TEST(LabelsIndex, UniqueFilter) {
|
||||
auto r1v2 = vlist2.find(*t1);
|
||||
EXPECT_NE(vlist1.find(*t1), nullptr);
|
||||
|
||||
auto label1 = dba->Label("1");
|
||||
auto label1 = dba.Label("1");
|
||||
vlist1.find(*t1)->labels_.push_back(label1);
|
||||
vlist2.find(*t1)->labels_.push_back(label1);
|
||||
index.Update(label1, &vlist1, r1v1);
|
||||
@ -98,7 +98,7 @@ TEST(LabelsIndex, Refresh) {
|
||||
EXPECT_NE(v1r1, nullptr);
|
||||
EXPECT_NE(v2r1, nullptr);
|
||||
|
||||
auto label = access->Label("label");
|
||||
auto label = access.Label("label");
|
||||
v1r1->labels_.push_back(label);
|
||||
v2r1->labels_.push_back(label);
|
||||
index.Update(label, &vlist1, v1r1);
|
||||
@ -124,9 +124,9 @@ TEST(LabelsIndex, Refresh) {
|
||||
TEST(LabelsIndexDb, AddGetZeroLabels) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->InsertVertex();
|
||||
vertex.add_label(dba->Label("test"));
|
||||
auto collection = dba->Vertices(dba->Label("test"), false);
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(dba.Label("test"));
|
||||
auto collection = dba.Vertices(dba.Label("test"), false);
|
||||
std::vector<VertexAccessor> collection_vector(collection.begin(),
|
||||
collection.end());
|
||||
EXPECT_EQ(collection_vector.size(), (size_t)0);
|
||||
@ -139,59 +139,59 @@ TEST(LabelsIndexDb, AddGetRemoveLabel) {
|
||||
{
|
||||
auto dba = db.Access();
|
||||
|
||||
auto vertex1 = dba->InsertVertex();
|
||||
vertex1.add_label(dba->Label("test"));
|
||||
auto vertex1 = dba.InsertVertex();
|
||||
vertex1.add_label(dba.Label("test"));
|
||||
|
||||
auto vertex2 = dba->InsertVertex();
|
||||
vertex2.add_label(dba->Label("test2"));
|
||||
auto vertex2 = dba.InsertVertex();
|
||||
vertex2.add_label(dba.Label("test2"));
|
||||
|
||||
auto vertex3 = dba->InsertVertex();
|
||||
vertex3.add_label(dba->Label("test"));
|
||||
auto vertex3 = dba.InsertVertex();
|
||||
vertex3.add_label(dba.Label("test"));
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
} // Finish transaction.
|
||||
{
|
||||
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());
|
||||
auto vertices = dba->Vertices(false);
|
||||
auto vertices = dba.Vertices(false);
|
||||
|
||||
std::vector<VertexAccessor> expected_collection;
|
||||
for (auto vertex : vertices) {
|
||||
if (vertex.has_label(dba->Label("test"))) {
|
||||
if (vertex.has_label(dba.Label("test"))) {
|
||||
expected_collection.push_back(vertex);
|
||||
} 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_TRUE(collection[0].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[1].has_label(dba->Label("test2")));
|
||||
dba->RemoveVertex(collection[0]); // Remove from database and test if
|
||||
EXPECT_TRUE(collection[0].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[1].has_label(dba.Label("test2")));
|
||||
dba.RemoveVertex(collection[0]); // Remove from database and test if
|
||||
// index won't return it.
|
||||
|
||||
// Remove label from the vertex and add new label.
|
||||
collection[1].remove_label(dba->Label("test"));
|
||||
collection[1].add_label(dba->Label("test2"));
|
||||
dba->Commit();
|
||||
collection[1].remove_label(dba.Label("test"));
|
||||
collection[1].add_label(dba.Label("test2"));
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
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());
|
||||
auto vertices = dba->Vertices(false);
|
||||
auto vertices = dba.Vertices(false);
|
||||
|
||||
std::vector<VertexAccessor> expected_collection;
|
||||
for (auto vertex : vertices) {
|
||||
if (vertex.has_label(dba->Label("test"))) {
|
||||
if (vertex.has_label(dba.Label("test"))) {
|
||||
expected_collection.push_back(vertex);
|
||||
} else {
|
||||
EXPECT_TRUE(vertex.has_label(dba->Label("test2")));
|
||||
EXPECT_TRUE(vertex.has_label(dba.Label("test2")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,10 @@ class LabelPropertyIndexComplexTest : public ::testing::Test {
|
||||
virtual void SetUp() {
|
||||
auto accessor = db_.Access();
|
||||
|
||||
label = accessor->Label("label");
|
||||
property = accessor->Property("property");
|
||||
label2 = accessor->Label("label2");
|
||||
property2 = accessor->Property("property2");
|
||||
label = accessor.Label("label");
|
||||
property = accessor.Property("property");
|
||||
label2 = accessor.Label("label2");
|
||||
property2 = accessor.Property("property2");
|
||||
|
||||
key = new LabelPropertyIndex::Key(label, property);
|
||||
EXPECT_EQ(index.CreateIndex(*key), true);
|
||||
@ -60,8 +60,8 @@ class LabelPropertyIndexComplexTest : public ::testing::Test {
|
||||
TEST(LabelPropertyIndex, CreateIndex) {
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
LabelPropertyIndex::Key key(accessor->Label("test"),
|
||||
accessor->Property("test2"));
|
||||
LabelPropertyIndex::Key key(accessor.Label("test"),
|
||||
accessor.Property("test2"));
|
||||
LabelPropertyIndex index;
|
||||
EXPECT_EQ(index.CreateIndex(key), true);
|
||||
EXPECT_EQ(index.CreateIndex(key), false);
|
||||
@ -70,8 +70,8 @@ TEST(LabelPropertyIndex, CreateIndex) {
|
||||
TEST(LabelPropertyIndex, DeleteIndex) {
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
LabelPropertyIndex::Key key(accessor->Label("test"),
|
||||
accessor->Property("test2"));
|
||||
LabelPropertyIndex::Key key(accessor.Label("test"),
|
||||
accessor.Property("test2"));
|
||||
LabelPropertyIndex index;
|
||||
EXPECT_EQ(index.CreateIndex(key), true);
|
||||
EXPECT_EQ(index.CreateIndex(key), false);
|
||||
@ -82,8 +82,8 @@ TEST(LabelPropertyIndex, DeleteIndex) {
|
||||
TEST(LabelPropertyIndex, IndexExistance) {
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
LabelPropertyIndex::Key key(accessor->Label("test"),
|
||||
accessor->Property("test2"));
|
||||
LabelPropertyIndex::Key key(accessor.Label("test"),
|
||||
accessor.Property("test2"));
|
||||
LabelPropertyIndex index;
|
||||
EXPECT_EQ(index.CreateIndex(key), true);
|
||||
// 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) {
|
||||
GraphDb db;
|
||||
auto accessor = db.Access();
|
||||
auto label = accessor->Label("label");
|
||||
auto property = accessor->Property("property");
|
||||
auto label = accessor.Label("label");
|
||||
auto property = accessor.Property("property");
|
||||
LabelPropertyIndex::Key key(label, property);
|
||||
LabelPropertyIndex index;
|
||||
EXPECT_EQ(index.CreateIndex(key), true);
|
||||
|
@ -17,16 +17,16 @@ TEST(TransactionTimeout, TransactionTimeout) {
|
||||
};
|
||||
{
|
||||
auto dba = db.Access();
|
||||
interpret(*dba, "MATCH (n) RETURN n");
|
||||
interpret(dba, "MATCH (n) RETURN n");
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
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);
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
interpret(*dba, "MATCH (n) RETURN n");
|
||||
interpret(dba, "MATCH (n) RETURN n");
|
||||
}
|
||||
}
|
||||
|
@ -218,24 +218,24 @@ void CompareDbs(database::GraphDb &a, database::GraphDb &b) {
|
||||
auto dba_b = b.Access();
|
||||
|
||||
{
|
||||
auto index_a = dba_a->IndexInfo();
|
||||
auto index_b = dba_b->IndexInfo();
|
||||
auto index_a = dba_a.IndexInfo();
|
||||
auto index_b = dba_b.IndexInfo();
|
||||
EXPECT_TRUE(
|
||||
index_a.size() == index_b.size() &&
|
||||
std::is_permutation(index_a.begin(), index_a.end(), index_b.begin()))
|
||||
<< "Indexes not equal [" << utils::Join(index_a, ", ") << "] != ["
|
||||
<< utils::Join(index_b, ", ");
|
||||
}
|
||||
EXPECT_TRUE(CompareExistenceConstraints(*dba_a, *dba_b));
|
||||
EXPECT_TRUE(CompareUniqueConstraints(*dba_a, *dba_b));
|
||||
EXPECT_TRUE(CompareExistenceConstraints(dba_a, dba_b));
|
||||
EXPECT_TRUE(CompareUniqueConstraints(dba_a, dba_b));
|
||||
|
||||
auto is_permutation_props = [&dba_a, &dba_b](const auto &p1_id,
|
||||
const auto &p2_id) {
|
||||
std::vector<std::pair<std::string, query::TypedValue>> p1;
|
||||
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 : p2_id) p2.push_back({dba_b->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});
|
||||
|
||||
// Don't use a binary predicate which depends on different value getters
|
||||
// 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;
|
||||
for (auto v_a : dba_a->Vertices(false)) {
|
||||
for (auto v_a : dba_a.Vertices(false)) {
|
||||
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_EQ(v_a.labels().size(), v_b->labels().size());
|
||||
std::vector<std::string> v_a_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_b->labels()) v_b_labels.push_back(dba_b->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));
|
||||
EXPECT_TRUE(std::is_permutation(v_a_labels.begin(), v_a_labels.end(),
|
||||
v_b_labels.begin()));
|
||||
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()),
|
||||
vertices_a_count);
|
||||
}
|
||||
{
|
||||
int edges_a_count = 0;
|
||||
for (auto e_a : dba_a->Edges(false)) {
|
||||
for (auto e_a : dba_a.Edges(false)) {
|
||||
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) << "Edge not found, id: " << e_a.gid();
|
||||
EXPECT_EQ(dba_a->EdgeTypeName(e_a.EdgeType()),
|
||||
dba_b->EdgeTypeName(e_b->EdgeType()));
|
||||
EXPECT_EQ(dba_a.EdgeTypeName(e_a.EdgeType()),
|
||||
dba_b.EdgeTypeName(e_b->EdgeType()));
|
||||
EXPECT_EQ(e_a.from().gid(), e_b->from().gid());
|
||||
EXPECT_EQ(e_a.to().gid(), e_b->to().gid());
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -327,8 +327,8 @@ void MakeDb(database::GraphDbAccessor &dba, int scale,
|
||||
|
||||
void MakeDb(database::GraphDb &db, int scale, std::vector<int> indices = {}) {
|
||||
auto dba = db.Access();
|
||||
MakeDb(*dba, scale, indices);
|
||||
dba->Commit();
|
||||
MakeDb(dba, scale, indices);
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
class Durability : public ::testing::Test {
|
||||
@ -365,7 +365,7 @@ class Durability : public ::testing::Test {
|
||||
|
||||
void MakeSnapshot(database::GraphDb &db, int snapshot_max_retained = -1) {
|
||||
auto dba = db.Access();
|
||||
ASSERT_TRUE(durability::MakeSnapshot(db, *dba, durability_dir_,
|
||||
ASSERT_TRUE(durability::MakeSnapshot(db, dba, durability_dir_,
|
||||
snapshot_max_retained));
|
||||
}
|
||||
|
||||
@ -393,18 +393,18 @@ TEST_F(Durability, WalEncoding) {
|
||||
config.durability_enabled = true;
|
||||
database::GraphDb db{config};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
auto v0 = dba.InsertVertex();
|
||||
ASSERT_EQ(v0.gid(), gid0);
|
||||
v0.add_label(dba->Label("l0"));
|
||||
v0.PropsSet(dba->Property("p0"), 42);
|
||||
auto v1 = dba->InsertVertex();
|
||||
v0.add_label(dba.Label("l0"));
|
||||
v0.PropsSet(dba.Property("p0"), 42);
|
||||
auto v1 = dba.InsertVertex();
|
||||
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);
|
||||
e0.PropsSet(dba->Property("p0"), std::vector<PropertyValue>{1, 2, 3});
|
||||
dba->BuildIndex(dba->Label("l1"), dba->Property("p1"), false);
|
||||
dba->DeleteIndex(dba->Label("l1"), dba->Property("p1"));
|
||||
dba->Commit();
|
||||
e0.PropsSet(dba.Property("p0"), std::vector<PropertyValue>{1, 2, 3});
|
||||
dba.BuildIndex(dba.Label("l1"), dba.Property("p1"), false);
|
||||
dba.DeleteIndex(dba.Label("l1"), dba.Property("p1"));
|
||||
dba.Commit();
|
||||
|
||||
db.wal().Flush();
|
||||
}
|
||||
@ -478,25 +478,25 @@ TEST_F(Durability, SnapshotEncoding) {
|
||||
{
|
||||
database::GraphDb db{DbConfig()};
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex();
|
||||
auto v0 = dba.InsertVertex();
|
||||
ASSERT_EQ(v0.gid(), gid0);
|
||||
v0.add_label(dba->Label("l0"));
|
||||
v0.PropsSet(dba->Property("p0"), 42);
|
||||
auto v1 = dba->InsertVertex();
|
||||
v0.add_label(dba.Label("l0"));
|
||||
v0.PropsSet(dba.Property("p0"), 42);
|
||||
auto v1 = dba.InsertVertex();
|
||||
ASSERT_EQ(v1.gid(), gid1);
|
||||
v1.add_label(dba->Label("l0"));
|
||||
v1.add_label(dba->Label("l1"));
|
||||
auto v2 = dba->InsertVertex();
|
||||
v1.add_label(dba.Label("l0"));
|
||||
v1.add_label(dba.Label("l1"));
|
||||
auto v2 = dba.InsertVertex();
|
||||
ASSERT_EQ(v2.gid(), gid2);
|
||||
v2.PropsSet(dba->Property("p0"), true);
|
||||
v2.PropsSet(dba->Property("p1"), "Johnny");
|
||||
auto e0 = dba->InsertEdge(v0, v1, dba->EdgeType("et0"));
|
||||
v2.PropsSet(dba.Property("p0"), true);
|
||||
v2.PropsSet(dba.Property("p1"), "Johnny");
|
||||
auto e0 = dba.InsertEdge(v0, v1, dba.EdgeType("et0"));
|
||||
ASSERT_EQ(e0.gid(), gid0);
|
||||
e0.PropsSet(dba->Property("p0"), std::vector<PropertyValue>{1, 2, 3});
|
||||
auto e1 = dba->InsertEdge(v2, v1, dba->EdgeType("et1"));
|
||||
e0.PropsSet(dba.Property("p0"), std::vector<PropertyValue>{1, 2, 3});
|
||||
auto e1 = dba.InsertEdge(v2, v1, dba.EdgeType("et1"));
|
||||
ASSERT_EQ(e1.gid(), gid1);
|
||||
dba->BuildIndex(dba->Label("l1"), dba->Property("p1"), false);
|
||||
dba->Commit();
|
||||
dba.BuildIndex(dba.Label("l1"), dba.Property("p1"), false);
|
||||
dba.Commit();
|
||||
MakeSnapshot(db);
|
||||
}
|
||||
|
||||
@ -665,33 +665,33 @@ TEST_F(Durability, SnapshotAndWalRecoveryAfterComplexTxSituation) {
|
||||
|
||||
// The first transaction modifies and commits.
|
||||
auto dba_1 = db.Access();
|
||||
MakeDb(*dba_1, 100);
|
||||
dba_1->Commit();
|
||||
MakeDb(dba_1, 100);
|
||||
dba_1.Commit();
|
||||
|
||||
// The second transaction will commit after snapshot.
|
||||
auto dba_2 = db.Access();
|
||||
MakeDb(*dba_2, 100);
|
||||
MakeDb(dba_2, 100);
|
||||
|
||||
// The third transaction modifies and commits.
|
||||
auto dba_3 = db.Access();
|
||||
MakeDb(*dba_3, 100);
|
||||
dba_3->Commit();
|
||||
MakeDb(dba_3, 100);
|
||||
dba_3.Commit();
|
||||
|
||||
MakeSnapshot(db); // Snapshooter takes the fourth transaction.
|
||||
dba_2->Commit();
|
||||
dba_2.Commit();
|
||||
|
||||
// The fifth transaction starts and commits after snapshot.
|
||||
auto dba_5 = db.Access();
|
||||
MakeDb(*dba_5, 100);
|
||||
dba_5->Commit();
|
||||
MakeDb(dba_5, 100);
|
||||
dba_5.Commit();
|
||||
|
||||
// The sixth transaction will not commit at all.
|
||||
auto dba_6 = db.Access();
|
||||
MakeDb(*dba_6, 100);
|
||||
MakeDb(dba_6, 100);
|
||||
|
||||
auto VisibleVertexCount = [](database::GraphDb &db) {
|
||||
auto dba = db.Access();
|
||||
auto vertices = dba->Vertices(false);
|
||||
auto vertices = dba.Vertices(false);
|
||||
return std::distance(vertices.begin(), vertices.end());
|
||||
};
|
||||
ASSERT_EQ(VisibleVertexCount(db), 400);
|
||||
@ -805,8 +805,8 @@ TEST_F(Durability, WorkerIdRecovery) {
|
||||
EXPECT_EQ(recovered.WorkerId(), config.worker_id);
|
||||
CompareDbs(db, recovered);
|
||||
auto dba = recovered.Access();
|
||||
EXPECT_NE(dba->VerticesCount(), 0);
|
||||
EXPECT_NE(dba->EdgesCount(), 0);
|
||||
EXPECT_NE(dba.VerticesCount(), 0);
|
||||
EXPECT_NE(dba.EdgesCount(), 0);
|
||||
recovered.Shutdown();
|
||||
EXPECT_TRUE(recovered.AwaitShutdown());
|
||||
}
|
||||
@ -820,8 +820,8 @@ TEST_F(Durability, WorkerIdRecovery) {
|
||||
database::Master recovered{config};
|
||||
EXPECT_NE(recovered.WorkerId(), db.WorkerId());
|
||||
auto dba = recovered.Access();
|
||||
EXPECT_EQ(dba->VerticesCount(), 0);
|
||||
EXPECT_EQ(dba->EdgesCount(), 0);
|
||||
EXPECT_EQ(dba.VerticesCount(), 0);
|
||||
EXPECT_EQ(dba.EdgesCount(), 0);
|
||||
recovered.Shutdown();
|
||||
EXPECT_TRUE(recovered.AwaitShutdown());
|
||||
}
|
||||
@ -843,8 +843,8 @@ TEST_F(Durability, SequentialRecovery) {
|
||||
|
||||
auto init_db = [](database::GraphDb &db) {
|
||||
auto dba = db.Access();
|
||||
for (int i = 0; i < kNumVertices; ++i) dba->InsertVertex(i);
|
||||
dba->Commit();
|
||||
for (int i = 0; i < kNumVertices; ++i) dba.InsertVertex(i);
|
||||
dba.Commit();
|
||||
};
|
||||
|
||||
auto run_updates = [&random_int](database::GraphDb &db,
|
||||
@ -854,14 +854,14 @@ TEST_F(Durability, SequentialRecovery) {
|
||||
threads.emplace_back([&random_int, &db, &keep_running]() {
|
||||
while (keep_running) {
|
||||
auto dba = db.Access();
|
||||
auto v = dba->FindVertex(random_int(kNumVertices), false);
|
||||
auto v = dba.FindVertex(random_int(kNumVertices), false);
|
||||
try {
|
||||
v.PropsSet(dba->Property("prop"), random_int(100));
|
||||
v.PropsSet(dba.Property("prop"), random_int(100));
|
||||
} catch (utils::LockTimeoutException &) {
|
||||
} catch (mvcc::SerializationError &) {
|
||||
}
|
||||
dba->InsertVertex();
|
||||
dba->Commit();
|
||||
dba.InsertVertex();
|
||||
dba.Commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -918,7 +918,7 @@ TEST_F(Durability, ContainsDurabilityFilesSnapshot) {
|
||||
{
|
||||
database::GraphDb db{DbConfig()};
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba.InsertVertex();
|
||||
MakeSnapshot(db);
|
||||
}
|
||||
ASSERT_TRUE(durability::ContainsDurabilityFiles(durability_dir_));
|
||||
@ -929,8 +929,8 @@ TEST_F(Durability, ContainsDurabilityFilesWal) {
|
||||
{
|
||||
database::GraphDb db{DbConfig(true, false)};
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->Commit();
|
||||
dba.InsertVertex();
|
||||
dba.Commit();
|
||||
db.wal().Flush();
|
||||
}
|
||||
ASSERT_TRUE(durability::ContainsDurabilityFiles(durability_dir_));
|
||||
@ -941,7 +941,7 @@ TEST_F(Durability, MoveToBackupSnapshot) {
|
||||
{
|
||||
database::GraphDb db{DbConfig()};
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba.InsertVertex();
|
||||
MakeSnapshot(db);
|
||||
}
|
||||
|
||||
@ -955,8 +955,8 @@ TEST_F(Durability, MoveToBackupWal) {
|
||||
{
|
||||
database::GraphDb db{DbConfig(true, false)};
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->Commit();
|
||||
dba.InsertVertex();
|
||||
dba.Commit();
|
||||
db.wal().Flush();
|
||||
}
|
||||
|
||||
@ -971,32 +971,32 @@ TEST_F(Durability, UniqueIndexRecoverySnapshotAndWal) {
|
||||
database::GraphDb db{config};
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("A");
|
||||
auto property = dba->Property("x");
|
||||
auto label = dba.Label("A");
|
||||
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.PropsSet(property, 5);
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
// create snapshot with build index and vertex
|
||||
MakeSnapshot(db);
|
||||
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("A");
|
||||
auto property = dba->Property("x");
|
||||
auto label = dba.Label("A");
|
||||
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.PropsSet(property, 5);
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
// create wal with drop index and vertex
|
||||
db.wal().Flush();
|
||||
@ -1015,22 +1015,22 @@ TEST_F(Durability, UniqueIndexRecoveryWal) {
|
||||
database::GraphDb db{config};
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("A");
|
||||
auto property = dba->Property("x");
|
||||
auto label = dba.Label("A");
|
||||
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.PropsSet(property, 5);
|
||||
|
||||
dba->DeleteIndex(label, property);
|
||||
dba.DeleteIndex(label, property);
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(label);
|
||||
v1.PropsSet(property, 5);
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
db.wal().Flush();
|
||||
{
|
||||
@ -1047,21 +1047,21 @@ TEST_F(Durability, ExistenceConstraintRecoveryWal) {
|
||||
{
|
||||
// Fill database with some data
|
||||
auto dba = db.Access();
|
||||
DbGenerator gen(*dba);
|
||||
dba->InsertVertex();
|
||||
DbGenerator gen(dba);
|
||||
dba.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
auto l1 = dba->Label("l1");
|
||||
std::vector<storage::Property> p1{dba->Property("p1"), dba->Property("p2")};
|
||||
dba->BuildExistenceConstraint(l1, p1);
|
||||
auto l1 = dba.Label("l1");
|
||||
std::vector<storage::Property> p1{dba.Property("p1"), dba.Property("p2")};
|
||||
dba.BuildExistenceConstraint(l1, p1);
|
||||
gen.InsertEdge();
|
||||
auto l2 = dba->Label("l2");
|
||||
std::vector<storage::Property> p2{dba->Property("p3"), dba->Property("p4")};
|
||||
dba->BuildExistenceConstraint(l2, p2);
|
||||
auto l2 = dba.Label("l2");
|
||||
std::vector<storage::Property> p2{dba.Property("p3"), dba.Property("p4")};
|
||||
dba.BuildExistenceConstraint(l2, p2);
|
||||
gen.InsertVertex();
|
||||
gen.InsertEdge();
|
||||
dba->DeleteExistenceConstraint(l1, p1);
|
||||
dba->Commit();
|
||||
dba.DeleteExistenceConstraint(l1, p1);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
// Recover and compare
|
||||
@ -1078,34 +1078,34 @@ TEST_F(Durability, ExistenceConstraintRecoverySnapshotAndWal) {
|
||||
{
|
||||
// Fill database with some data
|
||||
auto dba = db.Access();
|
||||
DbGenerator gen(*dba);
|
||||
dba->InsertVertex();
|
||||
DbGenerator gen(dba);
|
||||
dba.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
auto l1 = dba->Label("l1");
|
||||
std::vector<storage::Property> p1{dba->Property("p1"), dba->Property("p2")};
|
||||
dba->BuildExistenceConstraint(l1, p1);
|
||||
auto l1 = dba.Label("l1");
|
||||
std::vector<storage::Property> p1{dba.Property("p1"), dba.Property("p2")};
|
||||
dba.BuildExistenceConstraint(l1, p1);
|
||||
gen.InsertEdge();
|
||||
auto l2 = dba->Label("l2");
|
||||
std::vector<storage::Property> p2{dba->Property("p3"), dba->Property("p4")};
|
||||
dba->BuildExistenceConstraint(l2, p2);
|
||||
auto l2 = dba.Label("l2");
|
||||
std::vector<storage::Property> p2{dba.Property("p3"), dba.Property("p4")};
|
||||
dba.BuildExistenceConstraint(l2, p2);
|
||||
gen.InsertVertex();
|
||||
gen.InsertEdge();
|
||||
dba->DeleteExistenceConstraint(l1, p1);
|
||||
dba->Commit();
|
||||
dba.DeleteExistenceConstraint(l1, p1);
|
||||
dba.Commit();
|
||||
}
|
||||
// create snapshot with build existence constraint
|
||||
MakeSnapshot(db);
|
||||
{
|
||||
auto dba = db.Access();
|
||||
DbGenerator gen(*dba);
|
||||
DbGenerator gen(dba);
|
||||
gen.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
|
||||
auto l3 = dba->Label("l3");
|
||||
std::vector<storage::Property> p3{dba->Property("p5"), dba->Property("p6")};
|
||||
dba->BuildExistenceConstraint(l3, p3);
|
||||
dba->Commit();
|
||||
auto l3 = dba.Label("l3");
|
||||
std::vector<storage::Property> p3{dba.Property("p5"), dba.Property("p6")};
|
||||
dba.BuildExistenceConstraint(l3, p3);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
// Recover and compare
|
||||
@ -1122,21 +1122,21 @@ TEST_F(Durability, UniqueConstraintRecoveryWal) {
|
||||
{
|
||||
// Fill database with some data
|
||||
auto dba = db.Access();
|
||||
DbGenerator gen(*dba);
|
||||
dba->InsertVertex();
|
||||
DbGenerator gen(dba);
|
||||
dba.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
auto l1 = dba->Label("l1");
|
||||
auto p1 = dba->Property("p1");
|
||||
dba->BuildUniqueConstraint(l1, p1);
|
||||
auto l1 = dba.Label("l1");
|
||||
auto p1 = dba.Property("p1");
|
||||
dba.BuildUniqueConstraint(l1, p1);
|
||||
gen.InsertEdge();
|
||||
auto l2 = dba->Label("l2");
|
||||
auto p2 = dba->Property("p2");
|
||||
dba->BuildUniqueConstraint(l2, p2);
|
||||
auto l2 = dba.Label("l2");
|
||||
auto p2 = dba.Property("p2");
|
||||
dba.BuildUniqueConstraint(l2, p2);
|
||||
gen.InsertVertex();
|
||||
gen.InsertEdge();
|
||||
dba->DeleteUniqueConstraint(l1, p1);
|
||||
dba->Commit();
|
||||
dba.DeleteUniqueConstraint(l1, p1);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
// Recover and compare
|
||||
@ -1153,34 +1153,34 @@ TEST_F(Durability, UniqueConstraintRecoverySnapshotAndWal) {
|
||||
{
|
||||
// Fill database with some data
|
||||
auto dba = db.Access();
|
||||
DbGenerator gen(*dba);
|
||||
dba->InsertVertex();
|
||||
DbGenerator gen(dba);
|
||||
dba.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
auto l1 = dba->Label("l1");
|
||||
auto p1 = dba->Property("p1");
|
||||
dba->BuildUniqueConstraint(l1, p1);
|
||||
auto l1 = dba.Label("l1");
|
||||
auto p1 = dba.Property("p1");
|
||||
dba.BuildUniqueConstraint(l1, p1);
|
||||
gen.InsertEdge();
|
||||
auto l2 = dba->Label("l2");
|
||||
auto p2 = dba->Property("p2");
|
||||
dba->BuildUniqueConstraint(l2, p2);
|
||||
auto l2 = dba.Label("l2");
|
||||
auto p2 = dba.Property("p2");
|
||||
dba.BuildUniqueConstraint(l2, p2);
|
||||
gen.InsertVertex();
|
||||
gen.InsertEdge();
|
||||
dba->DeleteUniqueConstraint(l1, p1);
|
||||
dba->Commit();
|
||||
dba.DeleteUniqueConstraint(l1, p1);
|
||||
dba.Commit();
|
||||
}
|
||||
// create snapshot with build unique constraint
|
||||
MakeSnapshot(db);
|
||||
{
|
||||
auto dba = db.Access();
|
||||
DbGenerator gen(*dba);
|
||||
DbGenerator gen(dba);
|
||||
gen.InsertVertex();
|
||||
gen.InsertVertex();
|
||||
|
||||
auto l3 = dba->Label("l3");
|
||||
auto p3 = dba->Property("p3");
|
||||
dba->BuildUniqueConstraint(l3, p3);
|
||||
dba->Commit();
|
||||
auto l3 = dba.Label("l3");
|
||||
auto p3 = dba.Property("p3");
|
||||
dba.BuildUniqueConstraint(l3, p3);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
// Recover and compare
|
||||
|
@ -9,11 +9,11 @@ class ExistenceConstraintsTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto dba = db_.Access();
|
||||
label_ = dba->Label("label");
|
||||
property_ = dba->Property("property");
|
||||
label_ = dba.Label("label");
|
||||
property_ = dba.Property("property");
|
||||
properties_ = {property_};
|
||||
rule_ = {label_, properties_};
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
storage::constraints::ExistenceConstraints constraints_;
|
||||
@ -27,33 +27,33 @@ class ExistenceConstraintsTest : public ::testing::Test {
|
||||
TEST_F(ExistenceConstraintsTest, BuildDrop) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
EXPECT_FALSE(dba->ExistenceConstraintExists(label_, properties_));
|
||||
dba->Commit();
|
||||
EXPECT_FALSE(dba.ExistenceConstraintExists(label_, properties_));
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->BuildExistenceConstraint(label_, properties_);
|
||||
EXPECT_TRUE(dba->ExistenceConstraintExists(label_, properties_));
|
||||
dba->Commit();
|
||||
dba.BuildExistenceConstraint(label_, properties_);
|
||||
EXPECT_TRUE(dba.ExistenceConstraintExists(label_, properties_));
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->DeleteExistenceConstraint(label_, properties_);
|
||||
EXPECT_FALSE(dba->ExistenceConstraintExists(label_, properties_));
|
||||
dba->Commit();
|
||||
dba.DeleteExistenceConstraint(label_, properties_);
|
||||
EXPECT_FALSE(dba.ExistenceConstraintExists(label_, properties_));
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExistenceConstraintsTest, BuildWithViolation) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
EXPECT_THROW(dba->BuildExistenceConstraint(label_, properties_),
|
||||
EXPECT_THROW(dba.BuildExistenceConstraint(label_, properties_),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
}
|
||||
@ -61,12 +61,12 @@ TEST_F(ExistenceConstraintsTest, BuildWithViolation) {
|
||||
TEST_F(ExistenceConstraintsTest, InsertFail) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->BuildExistenceConstraint(label_, properties_);
|
||||
dba->Commit();
|
||||
dba.BuildExistenceConstraint(label_, properties_);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
EXPECT_THROW(v.add_label(label_),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
@ -75,36 +75,36 @@ TEST_F(ExistenceConstraintsTest, InsertFail) {
|
||||
TEST_F(ExistenceConstraintsTest, InsertPass) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->BuildExistenceConstraint(label_, properties_);
|
||||
dba->Commit();
|
||||
dba.BuildExistenceConstraint(label_, properties_);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property_, PropertyValue("Something"));
|
||||
v.add_label(label_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ExistenceConstraintsTest, RemoveFail) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->BuildExistenceConstraint(label_, properties_);
|
||||
dba->Commit();
|
||||
dba.BuildExistenceConstraint(label_, properties_);
|
||||
dba.Commit();
|
||||
}
|
||||
gid::Gid gid;
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property_, PropertyValue("Something"));
|
||||
v.add_label(label_);
|
||||
gid = v.gid();
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
EXPECT_THROW(v.PropsErase(property_),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
@ -113,24 +113,24 @@ TEST_F(ExistenceConstraintsTest, RemoveFail) {
|
||||
TEST_F(ExistenceConstraintsTest, RemovePass) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->BuildExistenceConstraint(label_, properties_);
|
||||
dba->Commit();
|
||||
dba.BuildExistenceConstraint(label_, properties_);
|
||||
dba.Commit();
|
||||
}
|
||||
gid::Gid gid;
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property_, PropertyValue("Something"));
|
||||
v.add_label(label_);
|
||||
gid = v.gid();
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
v.remove_label(label_);
|
||||
v.PropsErase(property_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,28 +11,28 @@ TEST(GraphDbTest, GarbageCollectIndices) {
|
||||
database::Config config;
|
||||
config.gc_cycle_sec = -1;
|
||||
database::GraphDb graph_db{config};
|
||||
std::unique_ptr<database::GraphDbAccessor> dba = graph_db.Access();
|
||||
auto dba = graph_db.Access();
|
||||
|
||||
auto commit = [&] {
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
dba = graph_db.Access();
|
||||
};
|
||||
auto label = dba->Label("label");
|
||||
auto property = dba->Property("property");
|
||||
dba->BuildIndex(label, property, false);
|
||||
auto label = dba.Label("label");
|
||||
auto property = dba.Property("property");
|
||||
dba.BuildIndex(label, property, false);
|
||||
commit();
|
||||
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(property, 42);
|
||||
commit();
|
||||
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 1);
|
||||
auto vertex_transferred = dba->Transfer(vertex);
|
||||
dba->RemoveVertex(vertex_transferred.value());
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 1);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 1);
|
||||
auto vertex_transferred = dba.Transfer(vertex);
|
||||
dba.RemoveVertex(vertex_transferred.value());
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 1);
|
||||
commit();
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 1);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 1);
|
||||
graph_db.CollectGarbage();
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 0);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 0);
|
||||
}
|
||||
|
@ -21,19 +21,19 @@ TEST(GraphDbAccessorTest, InsertVertex) {
|
||||
auto accessor = db.Access();
|
||||
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(Count(accessor->Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor->Vertices(true)), 1);
|
||||
accessor->AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 1);
|
||||
EXPECT_EQ(accessor.InsertVertex().gid(), generator.Next());
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor.Vertices(true)), 1);
|
||||
accessor.AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 1);
|
||||
|
||||
EXPECT_EQ(accessor->InsertVertex().gid(), generator.Next());
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(accessor->Vertices(true)), 2);
|
||||
accessor->AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 2);
|
||||
EXPECT_EQ(accessor.InsertVertex().gid(), generator.Next());
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(accessor.Vertices(true)), 2);
|
||||
accessor.AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 2);
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, UniqueVertexId) {
|
||||
@ -45,7 +45,7 @@ TEST(GraphDbAccessorTest, UniqueVertexId) {
|
||||
threads.emplace_back([&db, &ids]() {
|
||||
auto dba = db.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;
|
||||
auto accessor = db.Access();
|
||||
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 0);
|
||||
|
||||
auto va1 = accessor->InsertVertex();
|
||||
accessor->AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 1);
|
||||
auto va1 = accessor.InsertVertex();
|
||||
accessor.AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 1);
|
||||
|
||||
EXPECT_TRUE(accessor->RemoveVertex(va1));
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(accessor->Vertices(true)), 0);
|
||||
accessor->AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor->Vertices(true)), 0);
|
||||
EXPECT_TRUE(accessor.RemoveVertex(va1));
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(accessor.Vertices(true)), 0);
|
||||
accessor.AdvanceCommand();
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor.Vertices(true)), 0);
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) {
|
||||
@ -76,23 +76,23 @@ TEST(GraphDbAccessorTest, RemoveVertexDifferentTransaction) {
|
||||
// first transaction creates a vertex
|
||||
{
|
||||
auto accessor = db.Access();
|
||||
accessor->InsertVertex();
|
||||
accessor->Commit();
|
||||
accessor.InsertVertex();
|
||||
accessor.Commit();
|
||||
}
|
||||
// second transaction checks that it sees it, and deletes it
|
||||
{
|
||||
auto accessor = db.Access();
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(accessor->Vertices(true)), 1);
|
||||
for (auto vertex_accessor : accessor->Vertices(false))
|
||||
accessor->RemoveVertex(vertex_accessor);
|
||||
accessor->Commit();
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(accessor.Vertices(true)), 1);
|
||||
for (auto vertex_accessor : accessor.Vertices(false))
|
||||
accessor.RemoveVertex(vertex_accessor);
|
||||
accessor.Commit();
|
||||
}
|
||||
// third transaction checks that it does not see the vertex
|
||||
{
|
||||
auto accessor = db.Access();
|
||||
EXPECT_EQ(Count(accessor->Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor->Vertices(true)), 0);
|
||||
EXPECT_EQ(Count(accessor.Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(accessor.Vertices(true)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,21 +100,21 @@ TEST(GraphDbAccessorTest, InsertEdge) {
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto va1 = dba->InsertVertex();
|
||||
auto va2 = dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
auto va1 = dba.InsertVertex();
|
||||
auto va2 = dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(va1.in_degree(), 0);
|
||||
EXPECT_EQ(va1.out_degree(), 0);
|
||||
EXPECT_EQ(va2.in_degree(), 0);
|
||||
EXPECT_EQ(va2.out_degree(), 0);
|
||||
|
||||
// setup (v1) - [:likes] -> (v2)
|
||||
dba->InsertEdge(va1, va2, dba->EdgeType("likes"));
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 0);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 1);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 1);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 1);
|
||||
dba.InsertEdge(va1, va2, dba.EdgeType("likes"));
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 0);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 1);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 1);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 1);
|
||||
EXPECT_EQ(va1.out().begin()->to(), va2);
|
||||
EXPECT_EQ(va2.in().begin()->from(), va1);
|
||||
EXPECT_EQ(va1.in_degree(), 0);
|
||||
@ -123,12 +123,12 @@ TEST(GraphDbAccessorTest, InsertEdge) {
|
||||
EXPECT_EQ(va2.out_degree(), 0);
|
||||
|
||||
// setup (v1) - [:likes] -> (v2) <- [:hates] - (v3)
|
||||
auto va3 = dba->InsertVertex();
|
||||
dba->InsertEdge(va3, va2, dba->EdgeType("hates"));
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 1);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 2);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 2);
|
||||
auto va3 = dba.InsertVertex();
|
||||
dba.InsertEdge(va3, va2, dba.EdgeType("hates"));
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 1);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 2);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 2);
|
||||
EXPECT_EQ(va3.out().begin()->to(), va2);
|
||||
EXPECT_EQ(va1.in_degree(), 0);
|
||||
EXPECT_EQ(va1.out_degree(), 1);
|
||||
@ -146,12 +146,12 @@ TEST(GraphDbAccessorTest, UniqueEdgeId) {
|
||||
for (int i = 0; i < 50; i++) {
|
||||
threads.emplace_back([&db, &ids]() {
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto edge_type = dba->EdgeType("edge_type");
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge_type = dba.EdgeType("edge_type");
|
||||
auto access = ids.access();
|
||||
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();
|
||||
|
||||
// setup (v1) - [:likes] -> (v2) <- [:hates] - (v3)
|
||||
auto va1 = dba->InsertVertex();
|
||||
auto va2 = dba->InsertVertex();
|
||||
auto va3 = dba->InsertVertex();
|
||||
dba->InsertEdge(va1, va2, dba->EdgeType("likes"));
|
||||
dba->InsertEdge(va3, va2, dba->EdgeType("hates"));
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 2);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 2);
|
||||
auto va1 = dba.InsertVertex();
|
||||
auto va2 = dba.InsertVertex();
|
||||
auto va3 = dba.InsertVertex();
|
||||
dba.InsertEdge(va1, va2, dba.EdgeType("likes"));
|
||||
dba.InsertEdge(va3, va2, dba.EdgeType("hates"));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 2);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 2);
|
||||
|
||||
// remove all [:hates] edges
|
||||
for (auto edge : dba->Edges(false))
|
||||
if (edge.EdgeType() == dba->EdgeType("hates")) dba->RemoveEdge(edge);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 2);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 1);
|
||||
for (auto edge : dba.Edges(false))
|
||||
if (edge.EdgeType() == dba.EdgeType("hates")) dba.RemoveEdge(edge);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 2);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 1);
|
||||
|
||||
// current state: (v1) - [:likes] -> (v2), (v3)
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 1);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 1);
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 3);
|
||||
EXPECT_EQ(Count(dba->Vertices(true)), 3);
|
||||
for (auto edge : dba->Edges(false)) {
|
||||
EXPECT_EQ(edge.EdgeType(), dba->EdgeType("likes"));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 1);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 1);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 3);
|
||||
EXPECT_EQ(Count(dba.Vertices(true)), 3);
|
||||
for (auto edge : dba.Edges(false)) {
|
||||
EXPECT_EQ(edge.EdgeType(), dba.EdgeType("likes"));
|
||||
auto v1 = edge.from();
|
||||
auto v2 = edge.to();
|
||||
|
||||
// ensure correct connectivity for all the vertices
|
||||
for (auto vertex : dba->Vertices(false)) {
|
||||
for (auto vertex : dba.Vertices(false)) {
|
||||
if (vertex == v1) {
|
||||
EXPECT_EQ(vertex.in_degree(), 0);
|
||||
EXPECT_EQ(vertex.out_degree(), 1);
|
||||
@ -212,69 +212,69 @@ TEST(GraphDbAccessorTest, DetachRemoveVertex) {
|
||||
|
||||
// setup (v0)- []->(v1)<-[]-(v2)<-[]-(v3)
|
||||
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");
|
||||
dba->InsertEdge(vertices[0], vertices[1], edge_type);
|
||||
dba->InsertEdge(vertices[2], vertices[1], edge_type);
|
||||
dba->InsertEdge(vertices[3], vertices[2], edge_type);
|
||||
auto edge_type = dba.EdgeType("type");
|
||||
dba.InsertEdge(vertices[0], vertices[1], edge_type);
|
||||
dba.InsertEdge(vertices[2], vertices[1], edge_type);
|
||||
dba.InsertEdge(vertices[3], vertices[2], edge_type);
|
||||
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
|
||||
// ensure that plain remove does NOT work
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 4);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 3);
|
||||
EXPECT_FALSE(dba->RemoveVertex(vertices[0]));
|
||||
EXPECT_FALSE(dba->RemoveVertex(vertices[1]));
|
||||
EXPECT_FALSE(dba->RemoveVertex(vertices[2]));
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 4);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 3);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 4);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 3);
|
||||
EXPECT_FALSE(dba.RemoveVertex(vertices[0]));
|
||||
EXPECT_FALSE(dba.RemoveVertex(vertices[1]));
|
||||
EXPECT_FALSE(dba.RemoveVertex(vertices[2]));
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 4);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 3);
|
||||
|
||||
dba->DetachRemoveVertex(vertices[2]);
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 4);
|
||||
EXPECT_EQ(Count(dba->Vertices(true)), 3);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 3);
|
||||
EXPECT_EQ(Count(dba->Edges(true)), 1);
|
||||
dba->AdvanceCommand();
|
||||
dba.DetachRemoveVertex(vertices[2]);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 4);
|
||||
EXPECT_EQ(Count(dba.Vertices(true)), 3);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 3);
|
||||
EXPECT_EQ(Count(dba.Edges(true)), 1);
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 3);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 1);
|
||||
EXPECT_TRUE(dba->RemoveVertex(vertices[3]));
|
||||
EXPECT_EQ(Count(dba->Vertices(true)), 2);
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 3);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 3);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 1);
|
||||
EXPECT_TRUE(dba.RemoveVertex(vertices[3]));
|
||||
EXPECT_EQ(Count(dba.Vertices(true)), 2);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 3);
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 2);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 1);
|
||||
for (auto va : dba->Vertices(false)) EXPECT_FALSE(dba->RemoveVertex(va));
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 2);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 1);
|
||||
for (auto va : dba.Vertices(false)) EXPECT_FALSE(dba.RemoveVertex(va));
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 2);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 1);
|
||||
for (auto va : dba->Vertices(false)) {
|
||||
EXPECT_FALSE(dba->RemoveVertex(va));
|
||||
dba->DetachRemoveVertex(va);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 2);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 1);
|
||||
for (auto va : dba.Vertices(false)) {
|
||||
EXPECT_FALSE(dba.RemoveVertex(va));
|
||||
dba.DetachRemoveVertex(va);
|
||||
break;
|
||||
}
|
||||
EXPECT_EQ(Count(dba->Vertices(true)), 1);
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 2);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(Count(dba.Vertices(true)), 1);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 2);
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 1);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 0);
|
||||
|
||||
// remove the last vertex, it has no connections
|
||||
// so that should work
|
||||
for (auto va : dba->Vertices(false)) EXPECT_TRUE(dba->RemoveVertex(va));
|
||||
dba->AdvanceCommand();
|
||||
for (auto va : dba.Vertices(false)) EXPECT_TRUE(dba.RemoveVertex(va));
|
||||
dba.AdvanceCommand();
|
||||
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 0);
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) {
|
||||
@ -288,107 +288,107 @@ TEST(GraphDbAccessorTest, DetachRemoveVertexMultiple) {
|
||||
// with cycles too!
|
||||
int N = 7;
|
||||
std::vector<VertexAccessor> vertices;
|
||||
auto edge_type = dba->EdgeType("edge");
|
||||
for (int i = 0; i < N; ++i) vertices.emplace_back(dba->InsertVertex());
|
||||
auto edge_type = dba.EdgeType("edge");
|
||||
for (int i = 0; i < N; ++i) vertices.emplace_back(dba.InsertVertex());
|
||||
for (int j = 0; j < N; ++j)
|
||||
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();
|
||||
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), N);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), N * N);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), N);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), N * N);
|
||||
|
||||
// detach delete one edge
|
||||
dba->DetachRemoveVertex(vertices[0]);
|
||||
dba->AdvanceCommand();
|
||||
dba.DetachRemoveVertex(vertices[0]);
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), N - 1);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), (N - 1) * (N - 1));
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), N - 1);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), (N - 1) * (N - 1));
|
||||
|
||||
// detach delete two neighboring edges
|
||||
dba->DetachRemoveVertex(vertices[1]);
|
||||
dba->DetachRemoveVertex(vertices[2]);
|
||||
dba->AdvanceCommand();
|
||||
dba.DetachRemoveVertex(vertices[1]);
|
||||
dba.DetachRemoveVertex(vertices[2]);
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), N - 3);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), (N - 3) * (N - 3));
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), N - 3);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), (N - 3) * (N - 3));
|
||||
|
||||
// detach delete everything, buwahahahaha
|
||||
for (int l = 3; l < N; ++l) dba->DetachRemoveVertex(vertices[l]);
|
||||
dba->AdvanceCommand();
|
||||
for (int l = 3; l < N; ++l) dba.DetachRemoveVertex(vertices[l]);
|
||||
dba.AdvanceCommand();
|
||||
for (auto &vertex : vertices) vertex.Reconstruct();
|
||||
EXPECT_EQ(Count(dba->Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(dba->Edges(false)), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(false)), 0);
|
||||
EXPECT_EQ(Count(dba.Edges(false)), 0);
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, Labels) {
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
Label label_friend = dba->Label("friend");
|
||||
EXPECT_EQ(label_friend, dba->Label("friend"));
|
||||
EXPECT_NE(label_friend, dba->Label("friend2"));
|
||||
EXPECT_EQ(dba->LabelName(label_friend), "friend");
|
||||
Label label_friend = dba.Label("friend");
|
||||
EXPECT_EQ(label_friend, dba.Label("friend"));
|
||||
EXPECT_NE(label_friend, dba.Label("friend2"));
|
||||
EXPECT_EQ(dba.LabelName(label_friend), "friend");
|
||||
|
||||
// test that getting labels through a different accessor works
|
||||
EXPECT_EQ(label_friend, db.Access()->Label("friend"));
|
||||
EXPECT_NE(label_friend, db.Access()->Label("friend2"));
|
||||
EXPECT_EQ(label_friend, db.Access().Label("friend"));
|
||||
EXPECT_NE(label_friend, db.Access().Label("friend2"));
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, EdgeTypes) {
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
EdgeType edge_type = dba->EdgeType("likes");
|
||||
EXPECT_EQ(edge_type, dba->EdgeType("likes"));
|
||||
EXPECT_NE(edge_type, dba->EdgeType("hates"));
|
||||
EXPECT_EQ(dba->EdgeTypeName(edge_type), "likes");
|
||||
EdgeType edge_type = dba.EdgeType("likes");
|
||||
EXPECT_EQ(edge_type, dba.EdgeType("likes"));
|
||||
EXPECT_NE(edge_type, dba.EdgeType("hates"));
|
||||
EXPECT_EQ(dba.EdgeTypeName(edge_type), "likes");
|
||||
|
||||
// test that getting labels through a different accessor works
|
||||
EXPECT_EQ(edge_type, db.Access()->EdgeType("likes"));
|
||||
EXPECT_NE(edge_type, db.Access()->EdgeType("hates"));
|
||||
EXPECT_EQ(edge_type, db.Access().EdgeType("likes"));
|
||||
EXPECT_NE(edge_type, db.Access().EdgeType("hates"));
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, Properties) {
|
||||
GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
Property prop = dba->Property("name");
|
||||
EXPECT_EQ(prop, dba->Property("name"));
|
||||
EXPECT_NE(prop, dba->Property("surname"));
|
||||
EXPECT_EQ(dba->PropertyName(prop), "name");
|
||||
Property prop = dba.Property("name");
|
||||
EXPECT_EQ(prop, dba.Property("name"));
|
||||
EXPECT_NE(prop, dba.Property("surname"));
|
||||
EXPECT_EQ(dba.PropertyName(prop), "name");
|
||||
|
||||
// test that getting labels through a different accessor works
|
||||
EXPECT_EQ(prop, db.Access()->Property("name"));
|
||||
EXPECT_NE(prop, db.Access()->Property("surname"));
|
||||
EXPECT_EQ(prop, db.Access().Property("name"));
|
||||
EXPECT_NE(prop, db.Access().Property("surname"));
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorTest, Transfer) {
|
||||
GraphDb db;
|
||||
|
||||
auto dba1 = db.Access();
|
||||
auto prop = dba1->Property("property");
|
||||
VertexAccessor v1 = dba1->InsertVertex();
|
||||
auto prop = dba1.Property("property");
|
||||
VertexAccessor v1 = dba1.InsertVertex();
|
||||
v1.PropsSet(prop, 1);
|
||||
VertexAccessor v2 = dba1->InsertVertex();
|
||||
VertexAccessor v2 = dba1.InsertVertex();
|
||||
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);
|
||||
|
||||
// make dba2 that has dba1 in it's snapshot, so data isn't visible
|
||||
auto dba2 = db.Access();
|
||||
EXPECT_EQ(dba2->Transfer(v1), std::experimental::nullopt);
|
||||
EXPECT_EQ(dba2->Transfer(e12), std::experimental::nullopt);
|
||||
EXPECT_EQ(dba2.Transfer(v1), std::experimental::nullopt);
|
||||
EXPECT_EQ(dba2.Transfer(e12), std::experimental::nullopt);
|
||||
|
||||
// make dba3 that does not have dba1 in it's snapshot
|
||||
dba1->Commit();
|
||||
dba1.Commit();
|
||||
auto dba3 = db.Access();
|
||||
// we can transfer accessors even though the GraphDbAccessor they
|
||||
// belong to is not alive anymore
|
||||
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(v1)->PropsAt(prop).Value<int64_t>(), 1);
|
||||
EXPECT_EQ(dba3.Transfer(e12)->PropsAt(prop).Value<int64_t>(), 12);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -24,19 +24,19 @@ auto Count(TIterable iterable) {
|
||||
class GraphDbAccessorIndex : public testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()};
|
||||
storage::Property property = dba->Property("property");
|
||||
storage::Label label = dba->Label("label");
|
||||
storage::EdgeType edge_type = dba->EdgeType("edge_type");
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
storage::Property property = dba.Property("property");
|
||||
storage::Label label = dba.Label("label");
|
||||
storage::EdgeType edge_type = dba.EdgeType("edge_type");
|
||||
|
||||
auto AddVertex() {
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
return vertex;
|
||||
}
|
||||
|
||||
auto AddVertex(int property_value) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(property, property_value);
|
||||
return vertex;
|
||||
@ -44,106 +44,106 @@ class GraphDbAccessorIndex : public testing::Test {
|
||||
|
||||
// commits the current dba, and replaces it with a new one
|
||||
void Commit() {
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
dba = db.Access();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelIndexCount) {
|
||||
auto label2 = dba->Label("label2");
|
||||
EXPECT_EQ(dba->VerticesCount(label), 0);
|
||||
EXPECT_EQ(dba->VerticesCount(label2), 0);
|
||||
EXPECT_EQ(dba->VerticesCount(), 0);
|
||||
for (int i = 0; i < 11; ++i) dba->InsertVertex().add_label(label);
|
||||
for (int i = 0; i < 17; ++i) dba->InsertVertex().add_label(label2);
|
||||
auto label2 = dba.Label("label2");
|
||||
EXPECT_EQ(dba.VerticesCount(label), 0);
|
||||
EXPECT_EQ(dba.VerticesCount(label2), 0);
|
||||
EXPECT_EQ(dba.VerticesCount(), 0);
|
||||
for (int i = 0; i < 11; ++i) dba.InsertVertex().add_label(label);
|
||||
for (int i = 0; i < 17; ++i) dba.InsertVertex().add_label(label2);
|
||||
// even though xxx_count functions in database::GraphDbAccessor can
|
||||
// over-estaimate in this situation they should be exact (nothing was ever
|
||||
// deleted)
|
||||
EXPECT_EQ(dba->VerticesCount(label), 11);
|
||||
EXPECT_EQ(dba->VerticesCount(label2), 17);
|
||||
EXPECT_EQ(dba->VerticesCount(), 28);
|
||||
EXPECT_EQ(dba.VerticesCount(label), 11);
|
||||
EXPECT_EQ(dba.VerticesCount(label2), 17);
|
||||
EXPECT_EQ(dba.VerticesCount(), 28);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelIndexIteration) {
|
||||
// add 10 vertices, check visibility
|
||||
for (int i = 0; i < 10; i++) AddVertex();
|
||||
EXPECT_EQ(Count(dba->Vertices(label, false)), 0);
|
||||
EXPECT_EQ(Count(dba->Vertices(label, true)), 10);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, false)), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, true)), 10);
|
||||
Commit();
|
||||
EXPECT_EQ(Count(dba->Vertices(label, false)), 10);
|
||||
EXPECT_EQ(Count(dba->Vertices(label, true)), 10);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, false)), 10);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, true)), 10);
|
||||
|
||||
// remove 3 vertices, check visibility
|
||||
int deleted = 0;
|
||||
for (auto vertex : dba->Vertices(false)) {
|
||||
dba->RemoveVertex(vertex);
|
||||
for (auto vertex : dba.Vertices(false)) {
|
||||
dba.RemoveVertex(vertex);
|
||||
if (++deleted >= 3) break;
|
||||
}
|
||||
EXPECT_EQ(Count(dba->Vertices(label, false)), 10);
|
||||
EXPECT_EQ(Count(dba->Vertices(label, true)), 7);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, false)), 10);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, true)), 7);
|
||||
Commit();
|
||||
EXPECT_EQ(Count(dba->Vertices(label, false)), 7);
|
||||
EXPECT_EQ(Count(dba->Vertices(label, true)), 7);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, false)), 7);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, true)), 7);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, EdgesCount) {
|
||||
auto edge_type2 = dba->EdgeType("edge_type2");
|
||||
EXPECT_EQ(dba->EdgesCount(), 0);
|
||||
auto edge_type2 = dba.EdgeType("edge_type2");
|
||||
EXPECT_EQ(dba.EdgesCount(), 0);
|
||||
|
||||
auto v1 = AddVertex();
|
||||
auto v2 = AddVertex();
|
||||
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 < 11; ++i) dba.InsertEdge(v1, v2, edge_type);
|
||||
for (int i = 0; i < 17; ++i) dba.InsertEdge(v1, v2, edge_type2);
|
||||
// even though xxx_count functions in database::GraphDbAccessor can
|
||||
// over-estaimate in this situation they should be exact (nothing was ever
|
||||
// deleted)
|
||||
EXPECT_EQ(dba->EdgesCount(), 28);
|
||||
EXPECT_EQ(dba.EdgesCount(), 28);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuild) {
|
||||
AddVertex(0);
|
||||
|
||||
Commit();
|
||||
dba->BuildIndex(label, property, false);
|
||||
dba.BuildIndex(label, property, false);
|
||||
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)
|
||||
auto label2 = dba->Label("label2");
|
||||
auto property2 = dba->Property("property2");
|
||||
dba->BuildIndex(label2, property, false);
|
||||
dba->BuildIndex(label, property2, false);
|
||||
auto label2 = dba.Label("label2");
|
||||
auto property2 = dba.Property("property2");
|
||||
dba.BuildIndex(label2, property, false);
|
||||
dba.BuildIndex(label, property2, false);
|
||||
Commit();
|
||||
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 1);
|
||||
EXPECT_EQ(dba->VerticesCount(label2, property), 0);
|
||||
EXPECT_EQ(dba->VerticesCount(label, property2), 0);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 1);
|
||||
EXPECT_EQ(dba.VerticesCount(label2, property), 0);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property2), 0);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexDelete) {
|
||||
dba->BuildIndex(label, property, false);
|
||||
dba.BuildIndex(label, property, false);
|
||||
Commit();
|
||||
EXPECT_TRUE(dba->LabelPropertyIndexExists(label, property));
|
||||
EXPECT_TRUE(dba.LabelPropertyIndexExists(label, property));
|
||||
|
||||
dba->DeleteIndex(label, property);
|
||||
dba.DeleteIndex(label, property);
|
||||
Commit();
|
||||
|
||||
EXPECT_FALSE(dba->LabelPropertyIndexExists(label, property));
|
||||
EXPECT_FALSE(dba.LabelPropertyIndexExists(label, property));
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexBuildTwice) {
|
||||
dba->BuildIndex(label, property, false);
|
||||
EXPECT_THROW(dba->BuildIndex(label, property, false), utils::BasicException);
|
||||
dba.BuildIndex(label, property, false);
|
||||
EXPECT_THROW(dba.BuildIndex(label, property, false), utils::BasicException);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyIndexCount) {
|
||||
dba->BuildIndex(label, property, false);
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 0);
|
||||
EXPECT_EQ(Count(dba->Vertices(label, property, true)), 0);
|
||||
dba.BuildIndex(label, property, false);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, property, true)), 0);
|
||||
for (int i = 0; i < 14; ++i) AddVertex(0);
|
||||
EXPECT_EQ(dba->VerticesCount(label, property), 14);
|
||||
EXPECT_EQ(Count(dba->Vertices(label, property, true)), 14);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property), 14);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, property, true)), 14);
|
||||
}
|
||||
|
||||
TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
|
||||
@ -158,8 +158,8 @@ TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
|
||||
auto dba = db.Access();
|
||||
try {
|
||||
// This could either pass or throw.
|
||||
dba->BuildIndex(dba->Label("l" + std::to_string(index)),
|
||||
dba->Property("p" + std::to_string(index)), false);
|
||||
dba.BuildIndex(dba.Label("l" + std::to_string(index)),
|
||||
dba.Property("p" + std::to_string(index)), false);
|
||||
// If it throws, make sure the exception is right.
|
||||
} catch (const database::IndexTransactionException &e) {
|
||||
// Nothing to see here, move along.
|
||||
@ -186,7 +186,7 @@ TEST(GraphDbAccessorIndexApi, LabelPropertyBuildIndexConcurrent) {
|
||||
x, testing::AllOf(testing::Ge(center - 2), testing::Le(center + 2)));
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
|
||||
dba->BuildIndex(label, property, false);
|
||||
dba.BuildIndex(label, property, false);
|
||||
|
||||
// add some vertices without the property
|
||||
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);
|
||||
|
||||
// test estimates for exact value count
|
||||
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, 30), 100);
|
||||
EXPECT_WITH_MARGIN(dba->VerticesCount(label, property, 39), 100);
|
||||
EXPECT_EQ(dba->VerticesCount(label, property, 40), 0);
|
||||
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, 30), 100);
|
||||
EXPECT_WITH_MARGIN(dba.VerticesCount(label, property, 39), 100);
|
||||
EXPECT_EQ(dba.VerticesCount(label, property, 40), 0);
|
||||
|
||||
// helper functions
|
||||
auto Inclusive = [](int64_t value) {
|
||||
@ -213,7 +213,7 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
|
||||
utils::MakeBoundExclusive(PropertyValue(value)));
|
||||
};
|
||||
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;
|
||||
@ -232,27 +232,27 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueCount) {
|
||||
#undef EXPECT_WITH_MARGIN
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyValueIteration) {
|
||||
dba->BuildIndex(label, property, false);
|
||||
dba.BuildIndex(label, property, false);
|
||||
Commit();
|
||||
|
||||
// insert 10 verties and and check visibility
|
||||
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, true)), 10);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, property, 12, false)), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, property, 12, true)), 10);
|
||||
Commit();
|
||||
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, false)), 10);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, property, 12, true)), 10);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
|
||||
dba->BuildIndex(label, property, false);
|
||||
dba.BuildIndex(label, property, false);
|
||||
Commit();
|
||||
|
||||
std::vector<PropertyValue> expected_property_value(50, 0);
|
||||
|
||||
// strings
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
vertex_accessor.PropsSet(property,
|
||||
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.
|
||||
for (int i = 9; i >= 0; --i) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
vertex_accessor.PropsSet(property, static_cast<bool>(i / 5));
|
||||
expected_property_value[10 + i] = vertex_accessor.PropsAt(property);
|
||||
@ -268,14 +268,14 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
|
||||
|
||||
// integers
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
vertex_accessor.PropsSet(property, i);
|
||||
expected_property_value[20 + 2 * i] = vertex_accessor.PropsAt(property);
|
||||
}
|
||||
// doubles
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
vertex_accessor.PropsSet(property, static_cast<double>(i + 0.5));
|
||||
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.
|
||||
for (int i = 9; i >= 0; --i) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
std::vector<PropertyValue> value;
|
||||
value.push_back(PropertyValue(i));
|
||||
@ -304,16 +304,16 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
|
||||
auto shuffled = maps;
|
||||
std::random_shuffle(shuffled.begin(), shuffled.end());
|
||||
for (const auto &map : shuffled) {
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
vertex_accessor.PropsSet(property, map);
|
||||
}
|
||||
|
||||
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, false)), 0);
|
||||
EXPECT_EQ(Count(dba.Vertices(label, property, true)), 54);
|
||||
|
||||
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);
|
||||
EXPECT_EQ(property_value.type(), expected_property_value[cnt].type());
|
||||
switch (property_value.type()) {
|
||||
@ -373,19 +373,19 @@ TEST_F(GraphDbAccessorIndex, LabelPropertyValueSorting) {
|
||||
class GraphDbAccessorIndexRange : public GraphDbAccessorIndex {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
dba->BuildIndex(label, property, false);
|
||||
dba.BuildIndex(label, property, false);
|
||||
for (int i = 0; i < 100; i++) AddVertex(i / 10);
|
||||
|
||||
ASSERT_EQ(Count(dba->Vertices(false)), 0);
|
||||
ASSERT_EQ(Count(dba->Vertices(true)), 100);
|
||||
ASSERT_EQ(Count(dba.Vertices(false)), 0);
|
||||
ASSERT_EQ(Count(dba.Vertices(true)), 100);
|
||||
Commit();
|
||||
ASSERT_EQ(Count(dba->Vertices(false)), 100);
|
||||
ASSERT_EQ(Count(dba.Vertices(false)), 100);
|
||||
}
|
||||
|
||||
auto Vertices(std::experimental::optional<utils::Bound<PropertyValue>> lower,
|
||||
std::experimental::optional<utils::Bound<PropertyValue>> upper,
|
||||
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) {
|
||||
@ -456,7 +456,7 @@ TEST_F(GraphDbAccessorIndexRange, RangeInterationIncompatibleTypes) {
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnInsert) {
|
||||
dba->BuildIndex(label, property, true);
|
||||
dba.BuildIndex(label, property, true);
|
||||
Commit();
|
||||
AddVertex(0);
|
||||
EXPECT_THROW(AddVertex(0), database::IndexConstraintViolationException);
|
||||
@ -466,14 +466,14 @@ TEST_F(GraphDbAccessorIndex, UniqueConstraintViolationOnBuild) {
|
||||
AddVertex(0);
|
||||
AddVertex(0);
|
||||
Commit();
|
||||
EXPECT_THROW(dba->BuildIndex(label, property, true),
|
||||
EXPECT_THROW(dba.BuildIndex(label, property, true),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
|
||||
TEST_F(GraphDbAccessorIndex, UniqueConstraintUpdateProperty) {
|
||||
dba->BuildIndex(label, property, true);
|
||||
dba.BuildIndex(label, property, true);
|
||||
AddVertex(0);
|
||||
auto vertex_accessor = dba->InsertVertex();
|
||||
auto vertex_accessor = dba.InsertVertex();
|
||||
vertex_accessor.add_label(label);
|
||||
vertex_accessor.PropsSet(property, 10);
|
||||
|
||||
|
@ -21,7 +21,7 @@ class InterpreterTest : public ::testing::Test {
|
||||
const std::map<std::string, PropertyValue> ¶ms = {}) {
|
||||
auto dba = db_.Access();
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
auto results = interpreter_(query, *dba, params, false);
|
||||
auto results = interpreter_(query, dba, params, false);
|
||||
stream.Header(results.header());
|
||||
results.PullAll(stream);
|
||||
stream.Summary(results.summary());
|
||||
@ -148,17 +148,17 @@ TEST_F(InterpreterTest, Bfs) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto add_node = [&](int level, bool reachable) {
|
||||
auto node = dba->InsertVertex();
|
||||
node.PropsSet(dba->Property(kId), id++);
|
||||
node.PropsSet(dba->Property(kReachable), reachable);
|
||||
auto node = dba.InsertVertex();
|
||||
node.PropsSet(dba.Property(kId), id++);
|
||||
node.PropsSet(dba.Property(kReachable), reachable);
|
||||
levels[level].push_back(node);
|
||||
return node;
|
||||
};
|
||||
|
||||
auto add_edge = [&](VertexAccessor &v1, VertexAccessor &v2,
|
||||
bool reachable) {
|
||||
auto edge = dba->InsertEdge(v1, v2, dba->EdgeType("edge"));
|
||||
edge.PropsSet(dba->Property(kReachable), reachable);
|
||||
auto edge = dba.InsertEdge(v1, v2, dba.EdgeType("edge"));
|
||||
edge.PropsSet(dba.Property(kReachable), reachable);
|
||||
};
|
||||
|
||||
// Add source node.
|
||||
@ -196,7 +196,7 @@ TEST_F(InterpreterTest, Bfs) {
|
||||
add_edge(node1, node2, false);
|
||||
}
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
auto dba = db_.Access();
|
||||
@ -204,7 +204,7 @@ TEST_F(InterpreterTest, Bfs) {
|
||||
auto results = interpreter_(
|
||||
"MATCH (n {id: 0})-[r *bfs..5 (e, n | n.reachable and "
|
||||
"e.reachable)]->(m) RETURN r",
|
||||
*dba, {}, false);
|
||||
dba, {}, false);
|
||||
stream.Header(results.header());
|
||||
results.PullAll(stream);
|
||||
stream.Summary(results.summary());
|
||||
@ -225,14 +225,14 @@ TEST_F(InterpreterTest, Bfs) {
|
||||
EXPECT_EQ(edges.size(), expected_level);
|
||||
// Check that starting node is correct.
|
||||
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);
|
||||
for (int i = 1; i < static_cast<int>(edges.size()); ++i) {
|
||||
// Check that edges form a connected path.
|
||||
EXPECT_EQ(edges[i - 1].to(), edges[i].from());
|
||||
}
|
||||
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.
|
||||
EXPECT_TRUE(matched_ids.insert(matched_id).second);
|
||||
// Check that shortest path was found.
|
||||
@ -249,7 +249,7 @@ TEST_F(InterpreterTest, CreateIndexInMulticommandTransaction) {
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
auto dba = db_.Access();
|
||||
ASSERT_THROW(
|
||||
interpreter_("CREATE INDEX ON :X(y)", *dba, {}, true).PullAll(stream),
|
||||
interpreter_("CREATE INDEX ON :X(y)", dba, {}, true).PullAll(stream),
|
||||
query::IndexInMulticommandTxException);
|
||||
}
|
||||
|
||||
@ -261,17 +261,17 @@ TEST_F(InterpreterTest, ShortestPath) {
|
||||
interpreter_(
|
||||
"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)",
|
||||
*dba, {}, true)
|
||||
dba, {}, true)
|
||||
.PullAll(stream);
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
ResultStreamFaker<query::TypedValue> stream;
|
||||
auto dba = db_.Access();
|
||||
auto results =
|
||||
interpreter_("MATCH (n)-[e *wshortest 5 (e, n | e.w) ]->(m) return e",
|
||||
*dba, {}, false);
|
||||
dba, {}, false);
|
||||
stream.Header(results.header());
|
||||
results.PullAll(stream);
|
||||
stream.Summary(results.summary());
|
||||
@ -289,7 +289,7 @@ TEST_F(InterpreterTest, ShortestPath) {
|
||||
|
||||
std::vector<std::string> datum;
|
||||
for (const auto &edge : edges) {
|
||||
datum.push_back(dba->EdgeTypeName(edge.EdgeType()));
|
||||
datum.push_back(dba.EdgeTypeName(edge.EdgeType()));
|
||||
}
|
||||
|
||||
bool any_match = false;
|
||||
|
@ -26,14 +26,13 @@ using namespace nlohmann;
|
||||
|
||||
class PrintToJsonTest : public ::testing::Test {
|
||||
protected:
|
||||
PrintToJsonTest() : db(), dba_ptr(db.Access()), dba(*dba_ptr) {}
|
||||
PrintToJsonTest() : db(), dba(db.Access()) {}
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr;
|
||||
database::GraphDbAccessor &dba;
|
||||
database::GraphDbAccessor dba;
|
||||
|
||||
Symbol GetSymbol(std::string name) {
|
||||
return symbol_table.CreateSymbol(name, true);
|
||||
|
@ -24,9 +24,9 @@ using MiscParam = CostEstimator<database::GraphDbAccessor>::MiscParam;
|
||||
class QueryCostEstimator : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()};
|
||||
storage::Label label = dba->Label("label");
|
||||
storage::Property property = dba->Property("property");
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
storage::Label label = dba.Label("label");
|
||||
storage::Property property = dba.Property("property");
|
||||
|
||||
// we incrementally build the logical operator plan
|
||||
// start it off with Once
|
||||
@ -39,7 +39,7 @@ class QueryCostEstimator : public ::testing::Test {
|
||||
|
||||
void SetUp() {
|
||||
// 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();
|
||||
}
|
||||
|
||||
@ -53,16 +53,16 @@ class QueryCostEstimator : public ::testing::Test {
|
||||
void AddVertices(int vertex_count, int labeled_count,
|
||||
int property_count = 0) {
|
||||
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 < property_count) vertex.PropsSet(property, i);
|
||||
}
|
||||
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
auto Cost() {
|
||||
CostEstimator<database::GraphDbAccessor> cost_estimator(dba.get(), parameters_);
|
||||
CostEstimator<database::GraphDbAccessor> cost_estimator(&dba, parameters_);
|
||||
last_op_->Accept(cost_estimator);
|
||||
return cost_estimator.cost();
|
||||
}
|
||||
|
@ -30,14 +30,14 @@ namespace {
|
||||
class ExpressionEvaluatorTest : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba{db.Access()};
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
|
||||
AstStorage storage;
|
||||
EvaluationContext ctx;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
Frame frame{128};
|
||||
ExpressionEvaluator eval{&frame, symbol_table, ctx, dba.get(),
|
||||
ExpressionEvaluator eval{&frame, symbol_table, ctx, &dba,
|
||||
GraphView::OLD};
|
||||
|
||||
Identifier *CreateIdentifierWithValue(std::string name,
|
||||
@ -51,8 +51,8 @@ class ExpressionEvaluatorTest : public ::testing::Test {
|
||||
|
||||
template <class TExpression>
|
||||
auto Eval(TExpression *expr) {
|
||||
ctx.properties = NamesToProperties(storage.properties_, dba.get());
|
||||
ctx.labels = NamesToLabels(storage.labels_, dba.get());
|
||||
ctx.properties = NamesToProperties(storage.properties_, &dba);
|
||||
ctx.labels = NamesToLabels(storage.labels_, &dba);
|
||||
return expr->Accept(eval);
|
||||
}
|
||||
};
|
||||
@ -410,10 +410,10 @@ TEST_F(ExpressionEvaluatorTest, MapIndexing) {
|
||||
}
|
||||
|
||||
TEST_F(ExpressionEvaluatorTest, VertexAndEdgeIndexing) {
|
||||
auto edge_type = dba->EdgeType("edge_type");
|
||||
auto prop = dba->Property("prop");
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto e11 = dba->InsertEdge(v1, v1, edge_type);
|
||||
auto edge_type = dba.EdgeType("edge_type");
|
||||
auto prop = dba.Property("prop");
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto e11 = dba.InsertEdge(v1, v1, edge_type);
|
||||
v1.PropsSet(prop, 42);
|
||||
e11.PropsSet(prop, 43);
|
||||
|
||||
@ -624,10 +624,10 @@ TEST_F(ExpressionEvaluatorTest, IsNullOperator) {
|
||||
}
|
||||
|
||||
TEST_F(ExpressionEvaluatorTest, LabelsTest) {
|
||||
auto v1 = dba->InsertVertex();
|
||||
v1.add_label(dba->Label("ANIMAL"));
|
||||
v1.add_label(dba->Label("DOG"));
|
||||
v1.add_label(dba->Label("NICE_DOG"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(dba.Label("ANIMAL"));
|
||||
v1.add_label(dba.Label("DOG"));
|
||||
v1.add_label(dba.Label("NICE_DOG"));
|
||||
auto *identifier = storage.Create<Identifier>("n");
|
||||
auto node_symbol = symbol_table.CreateSymbol("n", true);
|
||||
identifier->MapTo(node_symbol);
|
||||
@ -893,9 +893,9 @@ TEST_F(ExpressionEvaluatorTest, RegexMatch) {
|
||||
class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
|
||||
protected:
|
||||
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::make_pair("height", dba->Property("height"));
|
||||
std::make_pair("height", dba.Property("height"));
|
||||
Identifier *identifier = storage.Create<Identifier>("element");
|
||||
Symbol symbol = symbol_table.CreateSymbol("element", true);
|
||||
|
||||
@ -909,7 +909,7 @@ class ExpressionEvaluatorPropertyLookup : public ExpressionEvaluatorTest {
|
||||
};
|
||||
|
||||
TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.PropsSet(prop_age.second, 10);
|
||||
frame[symbol] = v1;
|
||||
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
||||
@ -917,9 +917,9 @@ TEST_F(ExpressionEvaluatorPropertyLookup, Vertex) {
|
||||
}
|
||||
|
||||
TEST_F(ExpressionEvaluatorPropertyLookup, Edge) {
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("edge_type"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("edge_type"));
|
||||
e12.PropsSet(prop_age.second, 10);
|
||||
frame[symbol] = e12;
|
||||
EXPECT_EQ(Value(prop_age).ValueInt(), 10);
|
||||
@ -973,14 +973,14 @@ class FunctionTest : public ExpressionEvaluatorTest {
|
||||
TEST_F(FunctionTest, EndNode) {
|
||||
ASSERT_THROW(EvaluateFunction("ENDNODE", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("ENDNODE", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
v1.add_label(dba->Label("label1"));
|
||||
auto v2 = dba->InsertVertex();
|
||||
v2.add_label(dba->Label("label2"));
|
||||
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(dba.Label("label1"));
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.add_label(dba.Label("label2"));
|
||||
auto e = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
|
||||
ASSERT_TRUE(EvaluateFunction("ENDNODE", {e})
|
||||
.ValueVertex()
|
||||
.has_label(dba->Label("label2")));
|
||||
.has_label(dba.Label("label2")));
|
||||
ASSERT_THROW(EvaluateFunction("ENDNODE", {2}), QueryRuntimeException);
|
||||
}
|
||||
|
||||
@ -998,13 +998,13 @@ TEST_F(FunctionTest, Head) {
|
||||
TEST_F(FunctionTest, Properties) {
|
||||
ASSERT_THROW(EvaluateFunction("PROPERTIES", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("PROPERTIES", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
v1.PropsSet(dba->Property("height"), 5);
|
||||
v1.PropsSet(dba->Property("age"), 10);
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("type1"));
|
||||
e.PropsSet(dba->Property("height"), 3);
|
||||
e.PropsSet(dba->Property("age"), 15);
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.PropsSet(dba.Property("height"), 5);
|
||||
v1.PropsSet(dba.Property("age"), 10);
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto e = dba.InsertEdge(v1, v2, dba.EdgeType("type1"));
|
||||
e.PropsSet(dba.Property("height"), 3);
|
||||
e.PropsSet(dba.Property("age"), 15);
|
||||
|
||||
auto prop_values_to_int = [](TypedValue t) {
|
||||
std::unordered_map<std::string, int> properties;
|
||||
@ -1047,11 +1047,11 @@ TEST_F(FunctionTest, Size) {
|
||||
3);
|
||||
ASSERT_THROW(EvaluateFunction("SIZE", {5}), QueryRuntimeException);
|
||||
|
||||
auto v0 = dba->InsertVertex();
|
||||
auto v0 = dba.InsertVertex();
|
||||
query::Path path(v0);
|
||||
EXPECT_EQ(EvaluateFunction("SIZE", {path}).ValueInt(), 0);
|
||||
auto v1 = dba->InsertVertex();
|
||||
path.Expand(dba->InsertEdge(v0, v1, dba->EdgeType("type")));
|
||||
auto v1 = dba.InsertVertex();
|
||||
path.Expand(dba.InsertEdge(v0, v1, dba.EdgeType("type")));
|
||||
path.Expand(v1);
|
||||
EXPECT_EQ(EvaluateFunction("SIZE", {path}).ValueInt(), 1);
|
||||
}
|
||||
@ -1059,25 +1059,25 @@ TEST_F(FunctionTest, Size) {
|
||||
TEST_F(FunctionTest, StartNode) {
|
||||
ASSERT_THROW(EvaluateFunction("STARTNODE", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("STARTNODE", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
v1.add_label(dba->Label("label1"));
|
||||
auto v2 = dba->InsertVertex();
|
||||
v2.add_label(dba->Label("label2"));
|
||||
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(dba.Label("label1"));
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.add_label(dba.Label("label2"));
|
||||
auto e = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
|
||||
ASSERT_TRUE(EvaluateFunction("STARTNODE", {e})
|
||||
.ValueVertex()
|
||||
.has_label(dba->Label("label1")));
|
||||
.has_label(dba.Label("label1")));
|
||||
ASSERT_THROW(EvaluateFunction("STARTNODE", {2}), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(FunctionTest, Degree) {
|
||||
ASSERT_THROW(EvaluateFunction("DEGREE", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("DEGREE", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
|
||||
dba->InsertEdge(v3, v2, dba->EdgeType("t"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
|
||||
dba.InsertEdge(v3, v2, dba.EdgeType("t"));
|
||||
ASSERT_EQ(EvaluateFunction("DEGREE", {v1}).ValueInt(), 1);
|
||||
ASSERT_EQ(EvaluateFunction("DEGREE", {v2}).ValueInt(), 2);
|
||||
ASSERT_EQ(EvaluateFunction("DEGREE", {v3}).ValueInt(), 1);
|
||||
@ -1088,11 +1088,11 @@ TEST_F(FunctionTest, Degree) {
|
||||
TEST_F(FunctionTest, InDegree) {
|
||||
ASSERT_THROW(EvaluateFunction("INDEGREE", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("INDEGREE", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
|
||||
dba->InsertEdge(v3, v2, dba->EdgeType("t"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
|
||||
dba.InsertEdge(v3, v2, dba.EdgeType("t"));
|
||||
ASSERT_EQ(EvaluateFunction("INDEGREE", {v1}).ValueInt(), 0);
|
||||
ASSERT_EQ(EvaluateFunction("INDEGREE", {v2}).ValueInt(), 2);
|
||||
ASSERT_EQ(EvaluateFunction("INDEGREE", {v3}).ValueInt(), 0);
|
||||
@ -1103,11 +1103,11 @@ TEST_F(FunctionTest, InDegree) {
|
||||
TEST_F(FunctionTest, OutDegree) {
|
||||
ASSERT_THROW(EvaluateFunction("OUTDEGREE", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("OUTDEGREE", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
|
||||
dba->InsertEdge(v3, v2, dba->EdgeType("t"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto e12 = dba.InsertEdge(v1, v2, dba.EdgeType("t"));
|
||||
dba.InsertEdge(v3, v2, dba.EdgeType("t"));
|
||||
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v1}).ValueInt(), 1);
|
||||
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v2}).ValueInt(), 0);
|
||||
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v3}).ValueInt(), 1);
|
||||
@ -1154,11 +1154,11 @@ TEST_F(FunctionTest, ToInteger) {
|
||||
TEST_F(FunctionTest, Type) {
|
||||
ASSERT_THROW(EvaluateFunction("TYPE", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("TYPE", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
v1.add_label(dba->Label("label1"));
|
||||
auto v2 = dba->InsertVertex();
|
||||
v2.add_label(dba->Label("label2"));
|
||||
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("type1"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(dba.Label("label1"));
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.add_label(dba.Label("label2"));
|
||||
auto e = dba.InsertEdge(v1, v2, dba.EdgeType("type1"));
|
||||
ASSERT_EQ(EvaluateFunction("TYPE", {e}).ValueString(), "type1");
|
||||
ASSERT_THROW(EvaluateFunction("TYPE", {2}), QueryRuntimeException);
|
||||
}
|
||||
@ -1166,9 +1166,9 @@ TEST_F(FunctionTest, Type) {
|
||||
TEST_F(FunctionTest, Labels) {
|
||||
ASSERT_THROW(EvaluateFunction("LABELS", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("LABELS", {TypedValue::Null}).IsNull());
|
||||
auto v = dba->InsertVertex();
|
||||
v.add_label(dba->Label("label1"));
|
||||
v.add_label(dba->Label("label2"));
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(dba.Label("label1"));
|
||||
v.add_label(dba.Label("label2"));
|
||||
std::vector<std::string> labels;
|
||||
auto _labels = EvaluateFunction("LABELS", {v}).ValueList();
|
||||
for (auto label : _labels) {
|
||||
@ -1185,11 +1185,11 @@ TEST_F(FunctionTest, NodesRelationships) {
|
||||
EXPECT_TRUE(EvaluateFunction("RELATIONSHIPS", {TypedValue::Null}).IsNull());
|
||||
|
||||
{
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto e1 = dba->InsertEdge(v1, v2, dba->EdgeType("Type"));
|
||||
auto e2 = dba->InsertEdge(v2, v3, dba->EdgeType("Type"));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto e1 = dba.InsertEdge(v1, v2, dba.EdgeType("Type"));
|
||||
auto e2 = dba.InsertEdge(v2, v3, dba.EdgeType("Type"));
|
||||
query::Path path(v1, e1, v2, e2, v3);
|
||||
|
||||
auto _nodes = EvaluateFunction("NODES", {path}).ValueList();
|
||||
@ -1240,13 +1240,13 @@ TEST_F(FunctionTest, Range) {
|
||||
TEST_F(FunctionTest, Keys) {
|
||||
ASSERT_THROW(EvaluateFunction("KEYS", {}), QueryRuntimeException);
|
||||
ASSERT_TRUE(EvaluateFunction("KEYS", {TypedValue::Null}).IsNull());
|
||||
auto v1 = dba->InsertVertex();
|
||||
v1.PropsSet(dba->Property("height"), 5);
|
||||
v1.PropsSet(dba->Property("age"), 10);
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("type1"));
|
||||
e.PropsSet(dba->Property("width"), 3);
|
||||
e.PropsSet(dba->Property("age"), 15);
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.PropsSet(dba.Property("height"), 5);
|
||||
v1.PropsSet(dba.Property("age"), 10);
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto e = dba.InsertEdge(v1, v2, dba.EdgeType("type1"));
|
||||
e.PropsSet(dba.Property("width"), 3);
|
||||
e.PropsSet(dba.Property("age"), 15);
|
||||
|
||||
auto prop_keys_to_string = [](TypedValue t) {
|
||||
std::vector<std::string> keys;
|
||||
@ -1482,9 +1482,9 @@ TEST_F(FunctionTest, CounterSet) {
|
||||
}
|
||||
|
||||
TEST_F(FunctionTest, Id) {
|
||||
auto va = dba->InsertVertex();
|
||||
auto ea = dba->InsertEdge(va, va, dba->EdgeType("edge"));
|
||||
auto vb = dba->InsertVertex();
|
||||
auto va = dba.InsertVertex();
|
||||
auto ea = dba.InsertEdge(va, va, dba.EdgeType("edge"));
|
||||
auto vb = dba.InsertVertex();
|
||||
EXPECT_EQ(EvaluateFunction("ID", {va}).ValueInt(), 0);
|
||||
EXPECT_EQ(EvaluateFunction("ID", {ea}).ValueInt(), 0);
|
||||
EXPECT_EQ(EvaluateFunction("ID", {vb}).ValueInt(), 1);
|
||||
@ -1495,7 +1495,7 @@ TEST_F(FunctionTest, Id) {
|
||||
|
||||
/* TODO: FIXME
|
||||
TEST_F(FunctionTest, WorkerIdException) {
|
||||
auto va = dba->InsertVertex();
|
||||
auto va = dba.InsertVertex();
|
||||
EXPECT_THROW(EvaluateFunction("WORKERID", {}), QueryRuntimeException);
|
||||
EXPECT_THROW(EvaluateFunction("WORKERID", {va, va}), QueryRuntimeException);
|
||||
}
|
||||
@ -1503,7 +1503,7 @@ TEST_F(FunctionTest, WorkerIdException) {
|
||||
|
||||
/* TODO: FIXME
|
||||
TEST_F(FunctionTest, WorkerIdSingleNode) {
|
||||
auto va = dba->InsertVertex();
|
||||
auto va = dba.InsertVertex();
|
||||
EXPECT_EQ(EvaluateFunction("WORKERID", {va}).ValueInt(), 0);
|
||||
}
|
||||
*/
|
||||
|
@ -28,8 +28,7 @@ TEST(QueryPlan, Accumulate) {
|
||||
|
||||
auto check = [&](bool accumulate) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
auto prop = dba.Property("x");
|
||||
|
||||
auto v1 = dba.InsertVertex();
|
||||
@ -96,7 +95,7 @@ TEST(QueryPlan, AccumulateAdvance) {
|
||||
auto accumulate = std::make_shared<Accumulate>(
|
||||
create, std::vector<Symbol>{node.symbol}, advance);
|
||||
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));
|
||||
};
|
||||
check(false);
|
||||
@ -146,8 +145,7 @@ std::shared_ptr<Produce> MakeAggregationProduce(
|
||||
class QueryPlanAggregateOps : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
|
||||
database::GraphDbAccessor &dba{*dba_ptr};
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
storage::Property prop = dba.Property("prop");
|
||||
|
||||
AstStorage storage;
|
||||
@ -286,8 +284,7 @@ TEST(QueryPlan, AggregateGroupByValues) {
|
||||
// Also test the "remember" part of the Aggregation API as final results are
|
||||
// obtained via a property lookup of a remembered node.
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// a vector of PropertyValue to be set as property values on vertices
|
||||
// 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
|
||||
// of values in our groups
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto prop1 = dba.Property("prop1");
|
||||
auto prop2 = dba.Property("prop2");
|
||||
@ -387,7 +383,7 @@ TEST(QueryPlan, AggregateNoInput) {
|
||||
auto two = LITERAL(2);
|
||||
auto produce = MakeAggregationProduce(nullptr, symbol_table, storage, {two},
|
||||
{Aggregation::Op::COUNT}, {}, {});
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
EXPECT_EQ(1, results.size());
|
||||
EXPECT_EQ(1, results[0].size());
|
||||
@ -405,8 +401,7 @@ TEST(QueryPlan, AggregateCountEdgeCases) {
|
||||
// - 2 vertices in database, property set on both
|
||||
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
auto prop = dba.Property("prop");
|
||||
|
||||
AstStorage storage;
|
||||
@ -458,8 +453,7 @@ TEST(QueryPlan, AggregateFirstValueTypes) {
|
||||
// type check
|
||||
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto prop_string = dba.Property("string");
|
||||
@ -515,8 +509,7 @@ TEST(QueryPlan, AggregateTypes) {
|
||||
// (that logic is defined and tested by TypedValue)
|
||||
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto p1 = dba.Property("p1"); // has only string props
|
||||
dba.InsertVertex().PropsSet(p1, "string");
|
||||
@ -592,7 +585,7 @@ TEST(QueryPlan, Unwind) {
|
||||
->MapTo(symbol_table.CreateSymbol("y_ne", true));
|
||||
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);
|
||||
ASSERT_EQ(4, results.size());
|
||||
const std::vector<int> expected_x_card{3, 3, 3, 1};
|
||||
|
@ -31,23 +31,23 @@ TEST(QueryPlan, Skip) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n1");
|
||||
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));
|
||||
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(0, PullAll(*skip, &context));
|
||||
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(0, PullAll(*skip, &context));
|
||||
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(1, PullAll(*skip, &context));
|
||||
|
||||
for (int i = 0; i < 10; ++i) dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
for (int i = 0; i < 10; ++i) dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(11, PullAll(*skip, &context));
|
||||
}
|
||||
|
||||
@ -61,23 +61,23 @@ TEST(QueryPlan, Limit) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n1");
|
||||
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));
|
||||
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(1, PullAll(*skip, &context));
|
||||
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(2, PullAll(*skip, &context));
|
||||
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(2, PullAll(*skip, &context));
|
||||
|
||||
for (int i = 0; i < 10; ++i) dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
for (int i = 0; i < 10; ++i) dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
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
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -100,16 +100,15 @@ TEST(QueryPlan, CreateLimit) {
|
||||
auto c = std::make_shared<CreateNode>(n.op_, m);
|
||||
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));
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(3, CountIterable(dba->Vertices(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(3, CountIterable(dba.Vertices(false)));
|
||||
}
|
||||
|
||||
TEST(QueryPlan, OrderBy) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto prop = dba.Property("prop");
|
||||
@ -168,8 +167,7 @@ TEST(QueryPlan, OrderBy) {
|
||||
|
||||
TEST(QueryPlan, OrderByMultiple) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
@ -224,8 +222,7 @@ TEST(QueryPlan, OrderByMultiple) {
|
||||
|
||||
TEST(QueryPlan, OrderByExceptions) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto prop = dba.Property("prop");
|
||||
|
@ -18,8 +18,7 @@ using namespace query::plan;
|
||||
|
||||
TEST(QueryPlan, CreateNodeWithAttributes) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
storage::Label label = dba.Label("Person");
|
||||
auto property = PROPERTY_PAIR("prop");
|
||||
@ -54,8 +53,7 @@ TEST(QueryPlan, CreateNodeWithAttributes) {
|
||||
TEST(QueryPlan, CreateReturn) {
|
||||
// test CREATE (n:Person {age: 42}) RETURN n, n.age
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
storage::Label label = dba.Label("Person");
|
||||
auto property = PROPERTY_PAIR("property");
|
||||
@ -94,8 +92,7 @@ TEST(QueryPlan, CreateReturn) {
|
||||
|
||||
TEST(QueryPlan, CreateExpand) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
storage::Label label_node_1 = dba.Label("Node1");
|
||||
storage::Label label_node_2 = dba.Label("Node2");
|
||||
@ -169,10 +166,10 @@ TEST(QueryPlan, MatchCreateNode) {
|
||||
auto dba = db.Access();
|
||||
|
||||
// add three nodes we'll match and expand-create from
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
SymbolTable symbol_table;
|
||||
AstStorage storage;
|
||||
@ -185,11 +182,11 @@ TEST(QueryPlan, MatchCreateNode) {
|
||||
// creation op
|
||||
auto create_node = std::make_shared<CreateNode>(n_scan_all.op_, m);
|
||||
|
||||
EXPECT_EQ(CountIterable(dba->Vertices(false)), 3);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(false)), 3);
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
PullAll(*create_node, &context);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(CountIterable(dba->Vertices(false)), 6);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(false)), 6);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, MatchCreateExpand) {
|
||||
@ -197,23 +194,23 @@ TEST(QueryPlan, MatchCreateExpand) {
|
||||
auto dba = db.Access();
|
||||
|
||||
// add three nodes we'll match and expand-create from
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
// storage::Label label_node_1 = dba->Label("Node1");
|
||||
// storage::Label label_node_2 = dba->Label("Node2");
|
||||
// storage::Property property = dba->Label("prop");
|
||||
storage::EdgeType edge_type = dba->EdgeType("edge_type");
|
||||
// storage::Label label_node_1 = dba.Label("Node1");
|
||||
// storage::Label label_node_2 = dba.Label("Node2");
|
||||
// storage::Property property = dba.Label("prop");
|
||||
storage::EdgeType edge_type = dba.EdgeType("edge_type");
|
||||
|
||||
SymbolTable symbol_table;
|
||||
AstStorage storage;
|
||||
|
||||
auto test_create_path = [&](bool cycle, int expected_nodes_created,
|
||||
int expected_edges_created) {
|
||||
int before_v = CountIterable(dba->Vertices(false));
|
||||
int before_e = CountIterable(dba->Edges(false));
|
||||
int before_v = CountIterable(dba.Vertices(false));
|
||||
int before_e = CountIterable(dba.Edges(false));
|
||||
|
||||
// data for the first node
|
||||
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_,
|
||||
n_scan_all.sym_, cycle);
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
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);
|
||||
EXPECT_EQ(CountIterable(dba->Edges(false)) - before_e,
|
||||
EXPECT_EQ(CountIterable(dba.Edges(false)) - before_e,
|
||||
expected_edges_created);
|
||||
};
|
||||
|
||||
@ -249,15 +246,15 @@ TEST(QueryPlan, Delete) {
|
||||
|
||||
// make a fully-connected (one-direction, no cycles) with 4 nodes
|
||||
std::vector<VertexAccessor> vertices;
|
||||
for (int i = 0; i < 4; ++i) vertices.push_back(dba->InsertVertex());
|
||||
auto type = dba->EdgeType("type");
|
||||
for (int i = 0; i < 4; ++i) vertices.push_back(dba.InsertVertex());
|
||||
auto type = dba.EdgeType("type");
|
||||
for (int j = 0; j < 4; ++j)
|
||||
for (int k = j + 1; k < 4; ++k)
|
||||
dba->InsertEdge(vertices[j], vertices[k], type);
|
||||
dba.InsertEdge(vertices[j], vertices[k], type);
|
||||
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(4, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(6, CountIterable(dba->Edges(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(4, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(6, CountIterable(dba.Edges(false)));
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -268,11 +265,11 @@ TEST(QueryPlan, Delete) {
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
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);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(4, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(6, CountIterable(dba->Edges(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(4, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(6, CountIterable(dba.Edges(false)));
|
||||
}
|
||||
|
||||
// detach delete a single vertex
|
||||
@ -282,11 +279,11 @@ TEST(QueryPlan, Delete) {
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
n.op_, std::vector<Expression *>{n_get}, true);
|
||||
Frame frame(symbol_table.max_position());
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
delete_op->MakeCursor(*dba)->Pull(frame, context);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(3, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(3, CountIterable(dba->Edges(false)));
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
delete_op->MakeCursor(dba)->Pull(frame, context);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(3, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(3, CountIterable(dba.Edges(false)));
|
||||
}
|
||||
|
||||
// delete all remaining edges
|
||||
@ -298,11 +295,11 @@ TEST(QueryPlan, Delete) {
|
||||
auto r_get = storage.Create<Identifier>("r")->MapTo(r_m.edge_sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
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);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(3, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(0, CountIterable(dba->Edges(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(3, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(0, CountIterable(dba.Edges(false)));
|
||||
}
|
||||
|
||||
// delete all remaining vertices
|
||||
@ -311,11 +308,11 @@ TEST(QueryPlan, Delete) {
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
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);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(0, CountIterable(dba->Edges(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(0, CountIterable(dba.Edges(false)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,12 +332,12 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
dba->InsertEdge(v1, v2, dba->EdgeType("T"));
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(1, CountIterable(dba->Edges(false)));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, dba.EdgeType("T"));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(1, CountIterable(dba.Edges(false)));
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -357,11 +354,11 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
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));
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(0, CountIterable(dba->Edges(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(0, CountIterable(dba.Edges(false)));
|
||||
};
|
||||
|
||||
test_delete(true);
|
||||
@ -370,8 +367,7 @@ TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
|
||||
TEST(QueryPlan, DeleteReturn) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// make a fully-connected (one-direction, no cycles) with 4 nodes
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
@ -415,7 +411,7 @@ TEST(QueryPlan, DeleteNull) {
|
||||
auto once = std::make_shared<Once>();
|
||||
auto delete_op = std::make_shared<plan::Delete>(
|
||||
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));
|
||||
}
|
||||
|
||||
@ -431,8 +427,8 @@ TEST(QueryPlan, DeleteAdvance) {
|
||||
// we are not yet compatible with that
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -443,14 +439,13 @@ TEST(QueryPlan, DeleteAdvance) {
|
||||
n.op_, std::vector<Expression *>{n_get}, false);
|
||||
auto advance = std::make_shared<Accumulate>(
|
||||
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);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, SetProperty) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// graph with 4 vertices in connected pairs
|
||||
// the origin vertex in each par and both edges
|
||||
@ -506,16 +501,16 @@ TEST(QueryPlan, SetProperties) {
|
||||
auto dba = db.Access();
|
||||
|
||||
// graph: ({a: 0})-[:R {b:1}]->({c:2})
|
||||
auto prop_a = dba->Property("a");
|
||||
auto prop_b = dba->Property("b");
|
||||
auto prop_c = dba->Property("c");
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto e = dba->InsertEdge(v1, v2, dba->EdgeType("R"));
|
||||
auto prop_a = dba.Property("a");
|
||||
auto prop_b = dba.Property("b");
|
||||
auto prop_c = dba.Property("c");
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto e = dba.InsertEdge(v1, v2, dba.EdgeType("R"));
|
||||
v1.PropsSet(prop_a, 0);
|
||||
e.PropsSet(prop_b, 1);
|
||||
v2.PropsSet(prop_c, 2);
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -536,12 +531,12 @@ TEST(QueryPlan, SetProperties) {
|
||||
std::make_shared<plan::SetProperties>(r_m.op_, n.sym_, r_ident, op);
|
||||
auto set_m_to_r = std::make_shared<plan::SetProperties>(
|
||||
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));
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
EXPECT_EQ(CountIterable(dba->Edges(false)), 1);
|
||||
for (EdgeAccessor edge : dba->Edges(false)) {
|
||||
EXPECT_EQ(CountIterable(dba.Edges(false)), 1);
|
||||
for (EdgeAccessor edge : dba.Edges(false)) {
|
||||
VertexAccessor from = edge.from();
|
||||
EXPECT_EQ(from.Properties().size(), update ? 2 : 1);
|
||||
if (update) {
|
||||
@ -574,12 +569,12 @@ TEST(QueryPlan, SetLabels) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto label1 = dba->Label("label1");
|
||||
auto label2 = dba->Label("label2");
|
||||
auto label3 = dba->Label("label3");
|
||||
dba->InsertVertex().add_label(label1);
|
||||
dba->InsertVertex().add_label(label1);
|
||||
dba->AdvanceCommand();
|
||||
auto label1 = dba.Label("label1");
|
||||
auto label2 = dba.Label("label2");
|
||||
auto label3 = dba.Label("label3");
|
||||
dba.InsertVertex().add_label(label1);
|
||||
dba.InsertVertex().add_label(label1);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -587,10 +582,10 @@ TEST(QueryPlan, SetLabels) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto label_set = std::make_shared<plan::SetLabels>(
|
||||
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));
|
||||
|
||||
for (VertexAccessor vertex : dba->Vertices(false)) {
|
||||
for (VertexAccessor vertex : dba.Vertices(false)) {
|
||||
vertex.SwitchNew();
|
||||
EXPECT_EQ(3, vertex.labels().size());
|
||||
EXPECT_TRUE(vertex.has_label(label2));
|
||||
@ -600,8 +595,7 @@ TEST(QueryPlan, SetLabels) {
|
||||
|
||||
TEST(QueryPlan, RemoveProperty) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// graph with 4 vertices in connected pairs
|
||||
// the origin vertex in each par and both edges
|
||||
@ -655,17 +649,17 @@ TEST(QueryPlan, RemoveLabels) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto label1 = dba->Label("label1");
|
||||
auto label2 = dba->Label("label2");
|
||||
auto label3 = dba->Label("label3");
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto label1 = dba.Label("label1");
|
||||
auto label2 = dba.Label("label2");
|
||||
auto label3 = dba.Label("label3");
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(label1);
|
||||
v1.add_label(label2);
|
||||
v1.add_label(label3);
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.add_label(label1);
|
||||
v2.add_label(label3);
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -673,10 +667,10 @@ TEST(QueryPlan, RemoveLabels) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto label_remove = std::make_shared<plan::RemoveLabels>(
|
||||
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));
|
||||
|
||||
for (VertexAccessor vertex : dba->Vertices(false)) {
|
||||
for (VertexAccessor vertex : dba.Vertices(false)) {
|
||||
vertex.SwitchNew();
|
||||
EXPECT_EQ(1, vertex.labels().size());
|
||||
EXPECT_FALSE(vertex.has_label(label1));
|
||||
@ -686,8 +680,7 @@ TEST(QueryPlan, RemoveLabels) {
|
||||
|
||||
TEST(QueryPlan, NodeFilterSet) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
// Create a graph such that (v1 {prop: 42}) is connected to v2 and v3.
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
@ -730,8 +723,7 @@ TEST(QueryPlan, NodeFilterSet) {
|
||||
|
||||
TEST(QueryPlan, FilterRemove) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
// Create a graph such that (v1 {prop: 42}) is connected to v2 and v3.
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
@ -769,10 +761,10 @@ TEST(QueryPlan, FilterRemove) {
|
||||
TEST(QueryPlan, SetRemove) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto label1 = dba->Label("label1");
|
||||
auto label2 = dba->Label("label2");
|
||||
dba->AdvanceCommand();
|
||||
auto v = dba.InsertVertex();
|
||||
auto label1 = dba.Label("label1");
|
||||
auto label2 = dba.Label("label2");
|
||||
dba.AdvanceCommand();
|
||||
// Create operations which match (v) and set and remove v :label.
|
||||
// The expected result is single (v) as it was at the start.
|
||||
AstStorage storage;
|
||||
@ -783,9 +775,9 @@ TEST(QueryPlan, SetRemove) {
|
||||
scan_all.op_, scan_all.sym_, std::vector<storage::Label>{label1, label2});
|
||||
auto rem = std::make_shared<plan::RemoveLabels>(
|
||||
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));
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
v.Reconstruct();
|
||||
EXPECT_FALSE(v.has_label(label1));
|
||||
EXPECT_FALSE(v.has_label(label2));
|
||||
@ -799,8 +791,7 @@ TEST(QueryPlan, Merge) {
|
||||
// and sets some property (for result validation)
|
||||
// - merge_create branch just sets some other property
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, dba.EdgeType("Type"));
|
||||
@ -855,18 +846,17 @@ TEST(QueryPlan, MergeNoInput) {
|
||||
auto create = std::make_shared<CreateNode>(nullptr, node);
|
||||
auto merge = std::make_shared<plan::Merge>(nullptr, create, create);
|
||||
|
||||
EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(1, PullAll(*merge, &context));
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(1, CountIterable(dba->Vertices(false)));
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
|
||||
}
|
||||
|
||||
TEST(QueryPlan, SetPropertyOnNull) {
|
||||
// SET (Null).prop = 42
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
@ -892,8 +882,8 @@ TEST(QueryPlan, SetPropertiesOnNull) {
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto set_op = std::make_shared<plan::SetProperties>(
|
||||
optional, n.sym_, n_ident, plan::SetProperties::Op::REPLACE);
|
||||
EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(1, PullAll(*set_op, &context));
|
||||
}
|
||||
|
||||
@ -901,7 +891,7 @@ TEST(QueryPlan, SetLabelsOnNull) {
|
||||
// OPTIONAL MATCH (n) SET n :label
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("label");
|
||||
auto label = dba.Label("label");
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
@ -909,16 +899,15 @@ TEST(QueryPlan, SetLabelsOnNull) {
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto set_op = std::make_shared<plan::SetLabels>(
|
||||
optional, n.sym_, std::vector<storage::Label>{label});
|
||||
EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(1, PullAll(*set_op, &context));
|
||||
}
|
||||
|
||||
TEST(QueryPlan, RemovePropertyOnNull) {
|
||||
// REMOVE (Null).prop
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto prop = PROPERTY_PAIR("property");
|
||||
@ -935,7 +924,7 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
|
||||
// OPTIONAL MATCH (n) REMOVE n :label
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("label");
|
||||
auto label = dba.Label("label");
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
@ -943,15 +932,14 @@ TEST(QueryPlan, RemoveLabelsOnNull) {
|
||||
std::vector<Symbol>{n.sym_});
|
||||
auto remove_op = std::make_shared<plan::RemoveLabels>(
|
||||
optional, n.sym_, std::vector<storage::Label>{label});
|
||||
EXPECT_EQ(0, CountIterable(dba->Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, dba.get());
|
||||
EXPECT_EQ(0, CountIterable(dba.Vertices(false)));
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_EQ(1, PullAll(*remove_op, &context));
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteSetProperty) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
// Add a single vertex.
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
@ -973,8 +961,7 @@ TEST(QueryPlan, DeleteSetProperty) {
|
||||
|
||||
TEST(QueryPlan, DeleteSetPropertiesFromMap) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
// Add a single vertex.
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
@ -1001,8 +988,7 @@ TEST(QueryPlan, DeleteSetPropertiesFromMap) {
|
||||
|
||||
TEST(QueryPlan, DeleteSetPropertiesFromVertex) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
// Add a single vertex.
|
||||
{
|
||||
auto v = dba.InsertVertex();
|
||||
@ -1031,9 +1017,9 @@ TEST(QueryPlan, DeleteRemoveLabels) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Add a single vertex.
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(1, CountIterable(dba->Vertices(false)));
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
// 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 delete_op = std::make_shared<plan::Delete>(
|
||||
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 context = MakeContext(storage, symbol_table, dba.get());
|
||||
auto context = MakeContext(storage, symbol_table, &dba);
|
||||
EXPECT_THROW(PullAll(*rem_op, &context), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteRemoveProperty) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
// Add a single vertex.
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
|
@ -17,15 +17,15 @@ DECLARE_bool(query_cost_planner);
|
||||
class QueryExecution : public testing::Test {
|
||||
protected:
|
||||
std::experimental::optional<database::GraphDb> db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_;
|
||||
std::experimental::optional<database::GraphDbAccessor> dba_;
|
||||
|
||||
void SetUp() {
|
||||
db_.emplace();
|
||||
dba_ = db_->Access();
|
||||
dba_.emplace(db_->Access());
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
dba_ = nullptr;
|
||||
dba_ = std::experimental::nullopt;
|
||||
db_ = std::experimental::nullopt;
|
||||
}
|
||||
|
||||
|
@ -27,18 +27,18 @@ using namespace query::plan;
|
||||
class MatchReturnFixture : public testing::Test {
|
||||
protected:
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
database::GraphDbAccessor dba_{db_.Access()};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
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>
|
||||
std::vector<TResult> Results(std::shared_ptr<Produce> &op) {
|
||||
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))
|
||||
res.emplace_back(row[0].Value<TResult>());
|
||||
return res;
|
||||
@ -47,7 +47,7 @@ class MatchReturnFixture : public testing::Test {
|
||||
|
||||
TEST_F(MatchReturnFixture, MatchReturn) {
|
||||
AddVertices(2);
|
||||
dba_->AdvanceCommand();
|
||||
dba_.AdvanceCommand();
|
||||
|
||||
auto test_pull_count = [&](GraphView graph_view) {
|
||||
auto scan_all =
|
||||
@ -56,22 +56,22 @@ TEST_F(MatchReturnFixture, MatchReturn) {
|
||||
NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
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);
|
||||
};
|
||||
|
||||
EXPECT_EQ(2, test_pull_count(GraphView::NEW));
|
||||
EXPECT_EQ(2, test_pull_count(GraphView::OLD));
|
||||
dba_->InsertVertex();
|
||||
dba_.InsertVertex();
|
||||
EXPECT_EQ(3, test_pull_count(GraphView::NEW));
|
||||
EXPECT_EQ(2, test_pull_count(GraphView::OLD));
|
||||
dba_->AdvanceCommand();
|
||||
dba_.AdvanceCommand();
|
||||
EXPECT_EQ(3, test_pull_count(GraphView::OLD));
|
||||
}
|
||||
|
||||
TEST_F(MatchReturnFixture, MatchReturnPath) {
|
||||
AddVertices(2);
|
||||
dba_->AdvanceCommand();
|
||||
dba_.AdvanceCommand();
|
||||
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "n", nullptr);
|
||||
Symbol path_sym = symbol_table.CreateSymbol("path", true);
|
||||
@ -84,7 +84,7 @@ TEST_F(MatchReturnFixture, MatchReturnPath) {
|
||||
auto results = Results<query::Path>(produce);
|
||||
ASSERT_EQ(results.size(), 2);
|
||||
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);
|
||||
EXPECT_TRUE(std::is_permutation(expected_paths.begin(), expected_paths.end(),
|
||||
results.begin()));
|
||||
@ -94,9 +94,9 @@ TEST(QueryPlan, MatchReturnCartesian) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
dba->InsertVertex().add_label(dba->Label("l1"));
|
||||
dba->InsertVertex().add_label(dba->Label("l2"));
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex().add_label(dba.Label("l1"));
|
||||
dba.InsertVertex().add_label(dba.Label("l2"));
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -110,7 +110,7 @@ TEST(QueryPlan, MatchReturnCartesian) {
|
||||
NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_2", true));
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 4);
|
||||
// ensure the result ordering is OK:
|
||||
@ -126,9 +126,9 @@ TEST(QueryPlan, StandaloneReturn) {
|
||||
auto dba = db.Access();
|
||||
|
||||
// add a few nodes to the database
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -137,7 +137,7 @@ TEST(QueryPlan, StandaloneReturn) {
|
||||
auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output);
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 1);
|
||||
EXPECT_EQ(results[0].size(), 1);
|
||||
@ -146,8 +146,7 @@ TEST(QueryPlan, StandaloneReturn) {
|
||||
|
||||
TEST(QueryPlan, NodeFilterLabelsAndProperties) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// add a few nodes to the database
|
||||
storage::Label label = dba.Label("Label");
|
||||
@ -207,33 +206,33 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
|
||||
auto dba = db.Access();
|
||||
|
||||
// add a few nodes to the database
|
||||
storage::Label label1 = dba->Label("label1");
|
||||
storage::Label label2 = dba->Label("label2");
|
||||
storage::Label label3 = dba->Label("label3");
|
||||
storage::Label label1 = dba.Label("label1");
|
||||
storage::Label label2 = dba.Label("label2");
|
||||
storage::Label label3 = dba.Label("label3");
|
||||
// the test will look for nodes that have label1 and label2
|
||||
dba->InsertVertex(); // NOT accepted
|
||||
dba->InsertVertex().add_label(label1); // NOT accepted
|
||||
dba->InsertVertex().add_label(label2); // NOT accepted
|
||||
dba->InsertVertex().add_label(label3); // NOT accepted
|
||||
auto v1 = dba->InsertVertex(); // YES accepted
|
||||
dba.InsertVertex(); // NOT accepted
|
||||
dba.InsertVertex().add_label(label1); // NOT accepted
|
||||
dba.InsertVertex().add_label(label2); // NOT accepted
|
||||
dba.InsertVertex().add_label(label3); // NOT accepted
|
||||
auto v1 = dba.InsertVertex(); // YES accepted
|
||||
v1.add_label(label1);
|
||||
v1.add_label(label2);
|
||||
auto v2 = dba->InsertVertex(); // NOT accepted
|
||||
auto v2 = dba.InsertVertex(); // NOT accepted
|
||||
v2.add_label(label1);
|
||||
v2.add_label(label3);
|
||||
auto v3 = dba->InsertVertex(); // YES accepted
|
||||
auto v3 = dba.InsertVertex(); // YES accepted
|
||||
v3.add_label(label1);
|
||||
v3.add_label(label2);
|
||||
v3.add_label(label3);
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
// make a scan all
|
||||
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(label2)));
|
||||
n.node_->labels_.emplace_back(storage.GetLabelIx(dba.LabelName(label1)));
|
||||
n.node_->labels_.emplace_back(storage.GetLabelIx(dba.LabelName(label2)));
|
||||
|
||||
// node filtering
|
||||
auto *filter_expr =
|
||||
@ -246,7 +245,7 @@ TEST(QueryPlan, NodeFilterMultipleLabels) {
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 2);
|
||||
}
|
||||
@ -256,14 +255,14 @@ TEST(QueryPlan, Cartesian) {
|
||||
auto dba = db.Access();
|
||||
|
||||
auto add_vertex = [&dba](std::string label) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
vertex.add_label(dba->Label(label));
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(dba.Label(label));
|
||||
return vertex;
|
||||
};
|
||||
|
||||
std::vector<VertexAccessor> vertices{add_vertex("v1"), add_vertex("v2"),
|
||||
add_vertex("v3")};
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -284,7 +283,7 @@ TEST(QueryPlan, Cartesian) {
|
||||
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 9);
|
||||
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);
|
||||
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 0);
|
||||
}
|
||||
@ -326,14 +325,14 @@ TEST(QueryPlan, CartesianThreeWay) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto add_vertex = [&dba](std::string label) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
vertex.add_label(dba->Label(label));
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(dba.Label(label));
|
||||
return vertex;
|
||||
};
|
||||
|
||||
std::vector<VertexAccessor> vertices{add_vertex("v1"), add_vertex("v2"),
|
||||
add_vertex("v3")};
|
||||
dba->AdvanceCommand();
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -362,7 +361,7 @@ TEST(QueryPlan, CartesianThreeWay) {
|
||||
l.op_, l_symbols);
|
||||
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 27);
|
||||
int id = 0;
|
||||
@ -381,23 +380,23 @@ TEST(QueryPlan, CartesianThreeWay) {
|
||||
class ExpandFixture : public testing::Test {
|
||||
protected:
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
database::GraphDbAccessor dba_{db_.Access()};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
// make a V-graph (v3)<-[r2]-(v1)-[r1]->(v2)
|
||||
VertexAccessor v1 = dba_->InsertVertex();
|
||||
VertexAccessor v2 = dba_->InsertVertex();
|
||||
VertexAccessor v3 = dba_->InsertVertex();
|
||||
storage::EdgeType edge_type = dba_->EdgeType("Edge");
|
||||
EdgeAccessor r1 = dba_->InsertEdge(v1, v2, edge_type);
|
||||
EdgeAccessor r2 = dba_->InsertEdge(v1, v3, edge_type);
|
||||
VertexAccessor v1 = dba_.InsertVertex();
|
||||
VertexAccessor v2 = dba_.InsertVertex();
|
||||
VertexAccessor v3 = dba_.InsertVertex();
|
||||
storage::EdgeType edge_type = dba_.EdgeType("Edge");
|
||||
EdgeAccessor r1 = dba_.InsertEdge(v1, v2, edge_type);
|
||||
EdgeAccessor r2 = dba_.InsertEdge(v1, v3, edge_type);
|
||||
|
||||
void SetUp() override {
|
||||
v1.add_label(dba_->Label("l1"));
|
||||
v2.add_label(dba_->Label("l2"));
|
||||
v3.add_label(dba_->Label("l3"));
|
||||
dba_->AdvanceCommand();
|
||||
v1.add_label(dba_.Label("l1"));
|
||||
v2.add_label(dba_.Label("l2"));
|
||||
v3.add_label(dba_.Label("l3"));
|
||||
dba_.AdvanceCommand();
|
||||
}
|
||||
};
|
||||
|
||||
@ -412,7 +411,7 @@ TEST_F(ExpandFixture, Expand) {
|
||||
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
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);
|
||||
};
|
||||
|
||||
@ -420,15 +419,15 @@ TEST_F(ExpandFixture, Expand) {
|
||||
v1.Reconstruct();
|
||||
v2.Reconstruct();
|
||||
v3.Reconstruct();
|
||||
dba_->InsertEdge(v1, v2, edge_type);
|
||||
dba_->InsertEdge(v1, v3, edge_type);
|
||||
dba_.InsertEdge(v1, v2, 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::IN, 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::IN, 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::IN, 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);
|
||||
|
||||
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);
|
||||
ASSERT_EQ(results.size(), 2);
|
||||
std::vector<query::Path> results_paths;
|
||||
@ -478,11 +477,11 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
using map_int = std::unordered_map<int, int>;
|
||||
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
database::GraphDbAccessor dba_{db_.Access()};
|
||||
// labels for layers in the double chain
|
||||
std::vector<storage::Label> labels;
|
||||
// for all the edges
|
||||
storage::EdgeType edge_type = dba_->EdgeType("edge_type");
|
||||
storage::EdgeType edge_type = dba_.EdgeType("edge_type");
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -496,26 +495,26 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
std::vector<VertexAccessor> layer;
|
||||
for (int from_layer_ind = -1; from_layer_ind < chain_length - 1;
|
||||
from_layer_ind++) {
|
||||
std::vector<VertexAccessor> new_layer{dba_->InsertVertex(),
|
||||
dba_->InsertVertex()};
|
||||
auto label = dba_->Label(std::to_string(from_layer_ind + 1));
|
||||
std::vector<VertexAccessor> new_layer{dba_.InsertVertex(),
|
||||
dba_.InsertVertex()};
|
||||
auto label = dba_.Label(std::to_string(from_layer_ind + 1));
|
||||
labels.push_back(label);
|
||||
for (size_t v_to_ind = 0; v_to_ind < new_layer.size(); v_to_ind++) {
|
||||
auto &v_to = new_layer[v_to_ind];
|
||||
v_to.add_label(label);
|
||||
for (size_t v_from_ind = 0; v_from_ind < layer.size(); v_from_ind++) {
|
||||
auto &v_from = layer[v_from_ind];
|
||||
auto edge = dba_->InsertEdge(v_from, v_to, edge_type);
|
||||
edge.PropsSet(dba_->Property("p"),
|
||||
auto edge = dba_.InsertEdge(v_from, v_to, edge_type);
|
||||
edge.PropsSet(dba_.Property("p"),
|
||||
fmt::format("V{}{}->V{}{}", from_layer_ind, v_from_ind,
|
||||
from_layer_ind + 1, v_to_ind));
|
||||
}
|
||||
}
|
||||
layer = new_layer;
|
||||
}
|
||||
dba_->AdvanceCommand();
|
||||
ASSERT_EQ(CountIterable(dba_->Vertices(false)), 2 * chain_length);
|
||||
ASSERT_EQ(CountIterable(dba_->Edges(false)), 4 * (chain_length - 1));
|
||||
dba_.AdvanceCommand();
|
||||
ASSERT_EQ(CountIterable(dba_.Vertices(false)), 2 * chain_length);
|
||||
ASSERT_EQ(CountIterable(dba_.Edges(false)), 4 * (chain_length - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -543,7 +542,7 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
n_from.op_,
|
||||
storage.Create<query::LabelsTest>(
|
||||
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_sym = symbol_table.CreateSymbol(node_to, true);
|
||||
@ -588,8 +587,8 @@ class QueryPlanExpandVariable : public testing::Test {
|
||||
template <typename TResult>
|
||||
auto GetResults(std::shared_ptr<LogicalOperator> input_op, Symbol symbol) {
|
||||
Frame frame(symbol_table.max_position());
|
||||
auto cursor = input_op->MakeCursor(*dba_);
|
||||
auto context = MakeContext(storage, symbol_table, dba_.get());
|
||||
auto cursor = input_op->MakeCursor(dba_);
|
||||
auto context = MakeContext(storage, symbol_table, &dba_);
|
||||
std::vector<TResult> results;
|
||||
while (cursor->Pull(frame, context))
|
||||
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<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 &e2 : e1.to().out())
|
||||
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
|
||||
// PROPERTY_LOOKUP macro requirements
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
|
||||
database::GraphDbAccessor &dba{*dba_ptr};
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
std::pair<std::string, storage::Property> prop = PROPERTY_PAIR("property");
|
||||
storage::EdgeType edge_type = dba.EdgeType("edge_type");
|
||||
|
||||
@ -1139,17 +1137,17 @@ TEST(QueryPlan, ExpandOptional) {
|
||||
SymbolTable symbol_table;
|
||||
|
||||
// graph (v2 {p: 2})<-[:T]-(v1 {p: 1})-[:T]->(v3 {p: 2})
|
||||
auto prop = dba->Property("p");
|
||||
auto edge_type = dba->EdgeType("T");
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto prop = dba.Property("p");
|
||||
auto edge_type = dba.EdgeType("T");
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.PropsSet(prop, 1);
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.PropsSet(prop, 2);
|
||||
dba->InsertEdge(v1, v2, edge_type);
|
||||
auto v3 = dba->InsertVertex();
|
||||
dba.InsertEdge(v1, v2, edge_type);
|
||||
auto v3 = dba.InsertVertex();
|
||||
v3.PropsSet(prop, 2);
|
||||
dba->InsertEdge(v1, v3, edge_type);
|
||||
dba->AdvanceCommand();
|
||||
dba.InsertEdge(v1, v3, edge_type);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
// MATCH (n) OPTIONAL MATCH (n)-[r]->(m)
|
||||
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_))
|
||||
->MapTo(symbol_table.CreateSymbol("m", true));
|
||||
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);
|
||||
ASSERT_EQ(4, results.size());
|
||||
int v1_is_n_count = 0;
|
||||
@ -1203,7 +1201,7 @@ TEST(QueryPlan, OptionalMatchEmptyDB) {
|
||||
auto optional = std::make_shared<plan::Optional>(nullptr, n.op_,
|
||||
std::vector<Symbol>{n.sym_});
|
||||
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);
|
||||
ASSERT_EQ(1, results.size());
|
||||
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_))
|
||||
->MapTo(symbol_table.CreateSymbol("m", true));
|
||||
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);
|
||||
EXPECT_EQ(0, results.size());
|
||||
}
|
||||
@ -1240,13 +1238,13 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph with 2 connected, unlabeled nodes.
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto edge_type = dba->EdgeType("edge_type");
|
||||
dba->InsertEdge(v1, v2, edge_type);
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(1, CountIterable(dba->Edges(false)));
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge_type = dba.EdgeType("edge_type");
|
||||
dba.InsertEdge(v1, v2, edge_type);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
EXPECT_EQ(1, CountIterable(dba.Edges(false)));
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
// OPTIONAL MATCH (n :missing)
|
||||
@ -1279,7 +1277,7 @@ TEST(QueryPlan, OptionalMatchThenExpandToMissingNode) {
|
||||
auto m_ne = NEXPR("m", IDENT("m")->MapTo(m.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("m", true));
|
||||
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);
|
||||
EXPECT_EQ(0, results.size());
|
||||
}
|
||||
@ -1290,12 +1288,12 @@ TEST(QueryPlan, ExpandExistingNode) {
|
||||
|
||||
// make a graph (v1)->(v2) that
|
||||
// has a recursive edge (v1)->(v1)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto edge_type = dba->EdgeType("Edge");
|
||||
dba->InsertEdge(v1, v1, edge_type);
|
||||
dba->InsertEdge(v1, v2, edge_type);
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge_type = dba.EdgeType("Edge");
|
||||
dba.InsertEdge(v1, v1, edge_type);
|
||||
dba.InsertEdge(v1, v2, edge_type);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1315,7 +1313,7 @@ TEST(QueryPlan, ExpandExistingNode) {
|
||||
NEXPR("n", IDENT("n")->MapTo(n.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
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);
|
||||
EXPECT_EQ(results.size(), expected_result_count);
|
||||
};
|
||||
@ -1330,9 +1328,9 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v = dba->InsertVertex();
|
||||
dba->InsertEdge(v, v, dba->EdgeType("et"));
|
||||
dba->AdvanceCommand();
|
||||
auto v = dba.InsertVertex();
|
||||
dba.InsertEdge(v, v, dba.EdgeType("et"));
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1341,14 +1339,13 @@ TEST(QueryPlan, ExpandBothCycleEdgeCase) {
|
||||
auto r_ =
|
||||
MakeExpand(storage, symbol_table, n.op_, n.sym_, "r",
|
||||
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));
|
||||
}
|
||||
|
||||
TEST(QueryPlan, EdgeFilter) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// make an N-star expanding from (v1)
|
||||
// where only one edge will qualify
|
||||
@ -1419,15 +1416,15 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto type_1 = dba->EdgeType("type_1");
|
||||
auto type_2 = dba->EdgeType("type_2");
|
||||
auto type_3 = dba->EdgeType("type_3");
|
||||
dba->InsertEdge(v1, v2, type_1);
|
||||
dba->InsertEdge(v1, v2, type_2);
|
||||
dba->InsertEdge(v1, v2, type_3);
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto type_1 = dba.EdgeType("type_1");
|
||||
auto type_2 = dba.EdgeType("type_2");
|
||||
auto type_3 = dba.EdgeType("type_3");
|
||||
dba.InsertEdge(v1, v2, type_1);
|
||||
dba.InsertEdge(v1, v2, type_2);
|
||||
dba.InsertEdge(v1, v2, type_3);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1443,15 +1440,14 @@ TEST(QueryPlan, EdgeFilterMultipleTypes) {
|
||||
NEXPR("m", IDENT("m")->MapTo(r_m.node_sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 2);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Filter) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
|
||||
// add a 6 nodes with property 'prop', 2 have true as value
|
||||
auto property = PROPERTY_PAIR("property");
|
||||
@ -1480,12 +1476,12 @@ TEST(QueryPlan, EdgeUniquenessFilter) {
|
||||
auto dba = db.Access();
|
||||
|
||||
// make a graph that has (v1)->(v2) and a recursive edge (v1)->(v1)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto edge_type = dba->EdgeType("edge_type");
|
||||
dba->InsertEdge(v1, v2, edge_type);
|
||||
dba->InsertEdge(v1, v1, edge_type);
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge_type = dba.EdgeType("edge_type");
|
||||
dba.InsertEdge(v1, v2, edge_type);
|
||||
dba.InsertEdge(v1, v1, edge_type);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
auto check_expand_results = [&](bool edge_uniqueness) {
|
||||
AstStorage storage;
|
||||
@ -1503,7 +1499,7 @@ TEST(QueryPlan, EdgeUniquenessFilter) {
|
||||
if (edge_uniqueness)
|
||||
last_op = std::make_shared<EdgeUniquenessFilter>(
|
||||
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);
|
||||
};
|
||||
|
||||
@ -1536,7 +1532,7 @@ TEST(QueryPlan, Distinct) {
|
||||
auto x_ne = NEXPR("x", x_expr);
|
||||
x_ne->MapTo(symbol_table.CreateSymbol("x_ne", true));
|
||||
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);
|
||||
ASSERT_EQ(output.size(), results.size());
|
||||
auto output_it = output.begin();
|
||||
@ -1560,12 +1556,12 @@ TEST(QueryPlan, ScanAllByLabel) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Add a vertex with a label and one without.
|
||||
auto label = dba->Label("label");
|
||||
auto labeled_vertex = dba->InsertVertex();
|
||||
auto label = dba.Label("label");
|
||||
auto labeled_vertex = dba.InsertVertex();
|
||||
labeled_vertex.add_label(label);
|
||||
dba->InsertVertex();
|
||||
dba->AdvanceCommand();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
dba.InsertVertex();
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
// MATCH (n :label)
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1575,7 +1571,7 @@ TEST(QueryPlan, ScanAllByLabel) {
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all_by_label.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
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);
|
||||
ASSERT_EQ(results.size(), 1);
|
||||
auto result_row = results[0];
|
||||
@ -1586,8 +1582,8 @@ TEST(QueryPlan, ScanAllByLabel) {
|
||||
TEST(QueryPlan, ScanAllByLabelProperty) {
|
||||
database::GraphDb db;
|
||||
// Add 5 vertices with same label, but with different property values.
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
// vertex property values that will be stored into the DB
|
||||
// clang-format off
|
||||
std::vector<PropertyValue> values{
|
||||
@ -1598,15 +1594,15 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
|
||||
{
|
||||
auto dba = db.Access();
|
||||
for (const auto &value : values) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(prop, value);
|
||||
}
|
||||
dba->Commit();
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
dba.Commit();
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
}
|
||||
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,
|
||||
TypedValue upper, Bound::Type upper_type,
|
||||
@ -1620,7 +1616,7 @@ TEST(QueryPlan, ScanAllByLabelProperty) {
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
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);
|
||||
ASSERT_EQ(results.size(), expected.size());
|
||||
for (size_t i = 0; i < expected.size(); i++) {
|
||||
@ -1657,21 +1653,21 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
|
||||
database::GraphDb db;
|
||||
// Add 2 vertices with same label, but with property values that cannot be
|
||||
// compared. On the other hand, equality works fine.
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto number_vertex = dba->InsertVertex();
|
||||
auto number_vertex = dba.InsertVertex();
|
||||
number_vertex.add_label(label);
|
||||
number_vertex.PropsSet(prop, 42);
|
||||
auto string_vertex = dba->InsertVertex();
|
||||
auto string_vertex = dba.InsertVertex();
|
||||
string_vertex.add_label(label);
|
||||
string_vertex.PropsSet(prop, "string");
|
||||
dba->Commit();
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
dba.Commit();
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
}
|
||||
auto dba = db.Access();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
// MATCH (n :label {prop: 42})
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1681,7 +1677,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
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);
|
||||
ASSERT_EQ(results.size(), 1);
|
||||
const auto &row = results[0];
|
||||
@ -1694,20 +1690,20 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualityNoError) {
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
{
|
||||
auto dba = db.Access();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(prop, i);
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
auto dba = db.Access();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
// MATCH (m), (n :label {prop: m})
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1716,26 +1712,26 @@ TEST(QueryPlan, ScanAllByLabelPropertyValueError) {
|
||||
ident_m->MapTo(scan_all.sym_);
|
||||
auto scan_index = MakeScanAllByLabelPropertyValue(
|
||||
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);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
{
|
||||
auto dba = db.Access();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(prop, i);
|
||||
}
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
auto dba = db.Access();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
// MATCH (m), (n :label {prop: m})
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1748,7 +1744,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
storage, symbol_table, "n", label, prop, "prop",
|
||||
Bound{ident_m, Bound::Type::INCLUSIVE}, std::experimental::nullopt,
|
||||
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);
|
||||
}
|
||||
{
|
||||
@ -1757,7 +1753,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
storage, symbol_table, "n", label, prop, "prop",
|
||||
std::experimental::nullopt, 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);
|
||||
}
|
||||
{
|
||||
@ -1766,7 +1762,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeError) {
|
||||
storage, symbol_table, "n", label, prop, "prop",
|
||||
Bound{ident_m, Bound::Type::INCLUSIVE},
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1776,20 +1772,20 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
|
||||
// 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
|
||||
// yield no results.
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
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.PropsSet(prop, 42);
|
||||
dba->Commit();
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
dba.Commit();
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
}
|
||||
auto dba = db.Access();
|
||||
EXPECT_EQ(2, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(2, CountIterable(dba.Vertices(false)));
|
||||
// MATCH (n :label {prop: 42})
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1800,7 +1796,7 @@ TEST(QueryPlan, ScanAllByLabelPropertyEqualNull) {
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
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);
|
||||
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
|
||||
// the other does not. Checking if the value is between nulls, should
|
||||
// yield no results.
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
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.PropsSet(prop, 42);
|
||||
dba->Commit();
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
dba.Commit();
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
}
|
||||
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
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1835,25 +1831,25 @@ TEST(QueryPlan, ScanAllByLabelPropertyRangeNull) {
|
||||
auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("n", true));
|
||||
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);
|
||||
EXPECT_EQ(results.size(), 0);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label);
|
||||
v.PropsSet(prop, 2);
|
||||
dba->Commit();
|
||||
db.Access()->BuildIndex(label, prop, false);
|
||||
dba.Commit();
|
||||
db.Access().BuildIndex(label, prop, false);
|
||||
}
|
||||
auto dba = db.Access();
|
||||
EXPECT_EQ(1, CountIterable(dba->Vertices(false)));
|
||||
EXPECT_EQ(1, CountIterable(dba.Vertices(false)));
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
@ -1869,14 +1865,14 @@ TEST(QueryPlan, ScanAllByLabelPropertyNoValueInIndexContinuation) {
|
||||
auto scan_all = MakeScanAllByLabelPropertyValue(
|
||||
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);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto prop = db.Access()->Property("prop");
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
|
||||
// Insert vertices
|
||||
const int vertex_count = 300, vertex_prop_count = 50;
|
||||
@ -1884,18 +1880,18 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
|
||||
for (int i = 0; i < vertex_count; ++i) {
|
||||
auto dba = db.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label);
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -1909,7 +1905,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
NEXPR("n", IDENT("n")->MapTo(scan_all_by_label_property_value.sym_))
|
||||
->MapTo(symbol_table.CreateSymbol("named_expression_1", true));
|
||||
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);
|
||||
};
|
||||
|
||||
@ -1917,8 +1913,7 @@ TEST(QueryPlan, ScanAllEqualsScanAllByLabelProperty) {
|
||||
auto count_with_scan_all = [&db, &prop](int prop_value, int prop_count) {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
auto scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
auto e = PROPERTY_LOOKUP(IDENT("n")->MapTo(scan_all.sym_),
|
||||
std::make_pair("prop", prop));
|
||||
|
@ -18,11 +18,10 @@ using testing::UnorderedElementsAre;
|
||||
namespace {
|
||||
|
||||
struct ExpressionPrettyPrinterTest : public ::testing::Test {
|
||||
ExpressionPrettyPrinterTest() : pdba{db.Access()}, dba{*pdba} {}
|
||||
ExpressionPrettyPrinterTest() : dba{db.Access()} {}
|
||||
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> pdba;
|
||||
database::GraphDbAccessor &dba;
|
||||
database::GraphDbAccessor dba;
|
||||
AstStorage storage;
|
||||
};
|
||||
|
||||
|
@ -16,8 +16,7 @@ using namespace query;
|
||||
class TestSymbolGenerator : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_ptr{db.Access()};
|
||||
database::GraphDbAccessor &dba{*dba_ptr};
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
AstStorage storage;
|
||||
};
|
||||
|
||||
|
@ -82,17 +82,17 @@ TEST(TestVariableStartPlanner, MatchReturn) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph (v1) -[:r]-> (v2)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
dba->InsertEdge(v1, v2, dba->EdgeType("r"));
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, dba.EdgeType("r"));
|
||||
dba.AdvanceCommand();
|
||||
// Test MATCH (n) -[r]-> (m) RETURN n
|
||||
AstStorage storage;
|
||||
auto *query = QUERY(SINGLE_QUERY(
|
||||
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m"))),
|
||||
RETURN("n")));
|
||||
// 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.
|
||||
AssertRows(results, {{v1}});
|
||||
});
|
||||
@ -102,12 +102,12 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
dba->InsertEdge(v1, v2, dba->EdgeType("r"));
|
||||
dba->InsertEdge(v2, v3, dba->EdgeType("r"));
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, dba.EdgeType("r"));
|
||||
dba.InsertEdge(v2, v3, dba.EdgeType("r"));
|
||||
dba.AdvanceCommand();
|
||||
{
|
||||
// Test `MATCH (n) -[r]-> (m) -[e]-> (l) RETURN n`
|
||||
AstStorage storage;
|
||||
@ -116,7 +116,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
|
||||
EDGE("e", Direction::OUT), NODE("l"))),
|
||||
RETURN("n")));
|
||||
// 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.
|
||||
AssertRows(results, {{v1}});
|
||||
});
|
||||
@ -128,7 +128,7 @@ TEST(TestVariableStartPlanner, MatchTripletPatternReturn) {
|
||||
MATCH(PATTERN(NODE("n"), EDGE("r", Direction::OUT), NODE("m")),
|
||||
PATTERN(NODE("m"), EDGE("e", Direction::OUT), NODE("l"))),
|
||||
RETURN("n")));
|
||||
CheckPlansProduce(3, query, storage, dba.get(), [&](const auto &results) {
|
||||
CheckPlansProduce(3, query, storage, &dba, [&](const auto &results) {
|
||||
AssertRows(results, {{v1}});
|
||||
});
|
||||
}
|
||||
@ -138,12 +138,12 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Make a graph (v1) -[:r]-> (v2) -[:r]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
dba->InsertEdge(v1, v2, dba->EdgeType("r"));
|
||||
dba->InsertEdge(v2, v3, dba->EdgeType("r"));
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, dba.EdgeType("r"));
|
||||
dba.InsertEdge(v2, v3, dba.EdgeType("r"));
|
||||
dba.AdvanceCommand();
|
||||
// Test MATCH (n) -[r]-> (m) OPTIONAL MATCH (m) -[e]-> (l) RETURN n, l
|
||||
AstStorage storage;
|
||||
auto *query = QUERY(SINGLE_QUERY(
|
||||
@ -152,7 +152,7 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchReturn) {
|
||||
RETURN("n", "l")));
|
||||
// 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.
|
||||
CheckPlansProduce(4, query, storage, dba.get(), [&](const auto &results) {
|
||||
CheckPlansProduce(4, query, storage, &dba, [&](const auto &results) {
|
||||
// We expect to produce 2 rows:
|
||||
// * (v1), (v3)
|
||||
// * (v2), null
|
||||
@ -164,12 +164,12 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Graph (v1) -[:r]-> (v2)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto r_type_name = "r";
|
||||
auto r_type = dba->EdgeType(r_type_name);
|
||||
dba->InsertEdge(v1, v2, r_type);
|
||||
dba->AdvanceCommand();
|
||||
auto r_type = dba.EdgeType(r_type_name);
|
||||
dba.InsertEdge(v1, v2, r_type);
|
||||
dba.AdvanceCommand();
|
||||
// Test MATCH (n) -[r]-> (m) OPTIONAL MATCH (m) -[e]-> (l)
|
||||
// MERGE (u) -[q:r]-> (v) RETURN n, m, l, u, v
|
||||
AstStorage storage;
|
||||
@ -181,7 +181,7 @@ TEST(TestVariableStartPlanner, MatchOptionalMatchMergeReturn) {
|
||||
RETURN("n", "m", "l", "u", "v")));
|
||||
// Since MATCH, OPTIONAL MATCH and MERGE each have 2 nodes from which we can
|
||||
// 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)
|
||||
AssertRows(results, {{v1, v2, TypedValue::Null, v1, v2}});
|
||||
});
|
||||
@ -191,10 +191,10 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Graph (v1) -[:r]-> (v2)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
dba->InsertEdge(v1, v2, dba->EdgeType("r"));
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, dba.EdgeType("r"));
|
||||
dba.AdvanceCommand();
|
||||
// Test MATCH (n) -[r]-> (m) WITH n MATCH (m) -[r]-> (l) RETURN n, m, l
|
||||
AstStorage storage;
|
||||
auto *query = QUERY(SINGLE_QUERY(
|
||||
@ -204,7 +204,7 @@ TEST(TestVariableStartPlanner, MatchWithMatchReturn) {
|
||||
RETURN("n", "m", "l")));
|
||||
// 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.
|
||||
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)
|
||||
AssertRows(results, {{v1, v1, v2}});
|
||||
});
|
||||
@ -214,12 +214,12 @@ TEST(TestVariableStartPlanner, MatchVariableExpand) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
// Graph (v1) -[:r1]-> (v2) -[:r2]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto r1 = dba->InsertEdge(v1, v2, dba->EdgeType("r1"));
|
||||
auto r2 = dba->InsertEdge(v2, v3, dba->EdgeType("r2"));
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto r1 = dba.InsertEdge(v1, v2, dba.EdgeType("r1"));
|
||||
auto r2 = dba.InsertEdge(v2, v3, dba.EdgeType("r2"));
|
||||
dba.AdvanceCommand();
|
||||
// Test MATCH (n) -[r*]-> (m) RETURN r
|
||||
AstStorage storage;
|
||||
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 r2_list(std::vector<TypedValue>{r2}); // [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}});
|
||||
});
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
auto id = dba.Property("id");
|
||||
// Graph (v1 {id:1}) -[:r1]-> (v2 {id: 2}) -[:r2]-> (v3 {id: 3})
|
||||
auto v1 = dba.InsertVertex();
|
||||
@ -266,15 +265,15 @@ TEST(TestVariableStartPlanner, MatchVariableExpandReferenceNode) {
|
||||
TEST(TestVariableStartPlanner, MatchVariableExpandBoth) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto id = dba->Property("id");
|
||||
auto id = dba.Property("id");
|
||||
// Graph (v1 {id:1}) -[:r1]-> (v2) -[:r2]-> (v3)
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.PropsSet(id, 1);
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto r1 = dba->InsertEdge(v1, v2, dba->EdgeType("r1"));
|
||||
auto r2 = dba->InsertEdge(v2, v3, dba->EdgeType("r2"));
|
||||
dba->AdvanceCommand();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto r1 = dba.InsertEdge(v1, v2, dba.EdgeType("r1"));
|
||||
auto r2 = dba.InsertEdge(v2, v3, dba.EdgeType("r2"));
|
||||
dba.AdvanceCommand();
|
||||
// Test MATCH (n {id:1}) -[r*]- (m) RETURN r
|
||||
AstStorage storage;
|
||||
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:
|
||||
TypedValue r1_list(std::vector<TypedValue>{r1}); // [r1]
|
||||
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}});
|
||||
});
|
||||
}
|
||||
|
||||
TEST(TestVariableStartPlanner, MatchBfs) {
|
||||
database::GraphDb db;
|
||||
auto dba_ptr = db.Access();
|
||||
auto &dba = *dba_ptr;
|
||||
auto dba = db.Access();
|
||||
auto id = dba.Property("id");
|
||||
// Graph (v1 {id:1}) -[:r1]-> (v2 {id: 2}) -[:r2]-> (v3 {id: 3})
|
||||
auto v1 = dba.InsertVertex();
|
||||
|
@ -15,11 +15,11 @@ TEST(RecordAccessor, Properties) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
auto &properties = vertex.Properties();
|
||||
|
||||
auto property = dba->Property("PropName");
|
||||
auto property_other = dba->Property("Other");
|
||||
auto property = dba.Property("PropName");
|
||||
auto property_other = dba.Property("Other");
|
||||
EXPECT_EQ(vertex.PropsAt(property).type(), PropertyValue::Type::Null);
|
||||
|
||||
vertex.PropsSet(property, 42);
|
||||
@ -37,24 +37,24 @@ TEST(RecordAccessor, DbAccessor) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba.InsertVertex();
|
||||
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();
|
||||
EXPECT_EQ(dba.get(), &vertex_dba);
|
||||
EXPECT_EQ(&dba, &vertex_dba);
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, RecordEquality) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
EXPECT_EQ(v1, v1);
|
||||
EXPECT_NE(v1, v2);
|
||||
|
||||
auto e1 = dba->InsertEdge(v1, v2, dba->EdgeType("type"));
|
||||
auto e2 = 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"));
|
||||
EXPECT_EQ(e1, e1);
|
||||
EXPECT_NE(e1, e2);
|
||||
}
|
||||
@ -65,16 +65,16 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
|
||||
// test both Switches work on new record
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.SwitchOld();
|
||||
v1.SwitchNew();
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
// test both Switches work on existing record
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto v1 = *dba->Vertices(false).begin();
|
||||
auto v1 = *dba.Vertices(false).begin();
|
||||
v1.SwitchOld();
|
||||
v1.SwitchNew();
|
||||
}
|
||||
@ -82,8 +82,8 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
|
||||
// ensure switch exposes the right data
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto label = dba->Label("label");
|
||||
auto v1 = *dba->Vertices(false).begin();
|
||||
auto label = dba.Label("label");
|
||||
auto v1 = *dba.Vertices(false).begin();
|
||||
|
||||
EXPECT_FALSE(v1.has_label(label)); // old record
|
||||
v1.add_label(label); // modifying data does not switch to new
|
||||
@ -97,26 +97,26 @@ TEST(RecordAccessor, SwitchOldAndSwitchNewMemberFunctionTest) {
|
||||
|
||||
TEST(RecordAccessor, Reconstruct) {
|
||||
database::GraphDb db;
|
||||
auto label = db.Access()->Label("label");
|
||||
auto label = db.Access().Label("label");
|
||||
|
||||
{
|
||||
// we must operate on an old vertex
|
||||
// because otherwise we only have new
|
||||
// so create a vertex and commit it
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex();
|
||||
dba->Commit();
|
||||
dba.InsertVertex();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
// ensure we don't have label set
|
||||
auto dba = db.Access();
|
||||
auto v1 = *dba->Vertices(false).begin();
|
||||
auto v1 = *dba.Vertices(false).begin();
|
||||
v1.SwitchNew();
|
||||
EXPECT_FALSE(v1.has_label(label));
|
||||
|
||||
{
|
||||
// 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);
|
||||
EXPECT_FALSE(v1.has_label(label));
|
||||
v1_other_accessor.SwitchNew();
|
||||
@ -132,13 +132,13 @@ TEST(RecordAccessor, Reconstruct) {
|
||||
TEST(RecordAccessor, VertexLabels) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto &labels = v1.labels();
|
||||
|
||||
EXPECT_EQ(v1.labels().size(), 0);
|
||||
|
||||
storage::Label l1 = dba->Label("label1");
|
||||
storage::Label l2 = dba->Label("label2");
|
||||
storage::Label l1 = dba.Label("label1");
|
||||
storage::Label l2 = dba.Label("label2");
|
||||
|
||||
// adding labels
|
||||
EXPECT_FALSE(v1.has_label(l1));
|
||||
@ -158,7 +158,7 @@ TEST(RecordAccessor, VertexLabels) {
|
||||
EXPECT_EQ(labels.size(), 2);
|
||||
|
||||
// removing labels
|
||||
storage::Label l3 = dba->Label("label3");
|
||||
storage::Label l3 = dba.Label("label3");
|
||||
v1.remove_label(l3);
|
||||
EXPECT_EQ(labels.size(), 2);
|
||||
|
||||
@ -173,13 +173,13 @@ TEST(RecordAccessor, VertexLabels) {
|
||||
TEST(RecordAccessor, EdgeType) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
|
||||
storage::EdgeType likes = dba->EdgeType("likes");
|
||||
storage::EdgeType hates = dba->EdgeType("hates");
|
||||
storage::EdgeType likes = dba.EdgeType("likes");
|
||||
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_NE(edge.EdgeType(), hates);
|
||||
}
|
||||
@ -187,23 +187,23 @@ TEST(RecordAccessor, EdgeType) {
|
||||
TEST(RecordAccessor, EdgeIsCycle) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto likes = dba->EdgeType("edge_type");
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto likes = dba.EdgeType("edge_type");
|
||||
|
||||
EXPECT_TRUE(dba->InsertEdge(v1, v1, 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(v2, v1, likes).is_cycle());
|
||||
EXPECT_TRUE(dba.InsertEdge(v1, v1, 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(v2, v1, likes).is_cycle());
|
||||
}
|
||||
|
||||
TEST(RecordAccessor, VertexEdgeConnections) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto edge = dba->InsertEdge(v1, v2, dba->EdgeType("likes"));
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge = dba.InsertEdge(v1, v2, dba.EdgeType("likes"));
|
||||
dba.AdvanceCommand();
|
||||
|
||||
EXPECT_EQ(edge.from(), v1);
|
||||
EXPECT_NE(edge.from(), v2);
|
||||
@ -232,16 +232,16 @@ TEST(RecordAccessor, VertexEdgeConnections) {
|
||||
TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto edge_type = dba->EdgeType("edge type");
|
||||
auto e12 = dba->InsertEdge(v1, v2, edge_type);
|
||||
auto e22 = dba->InsertEdge(v2, v2, edge_type);
|
||||
auto e23a = dba->InsertEdge(v2, v3, edge_type);
|
||||
auto e23b = dba->InsertEdge(v2, v3, edge_type);
|
||||
auto e32 = dba->InsertEdge(v3, v2, edge_type);
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto edge_type = dba.EdgeType("edge type");
|
||||
auto e12 = dba.InsertEdge(v1, v2, edge_type);
|
||||
auto e22 = dba.InsertEdge(v2, v2, edge_type);
|
||||
auto e23a = dba.InsertEdge(v2, v3, edge_type);
|
||||
auto e23b = dba.InsertEdge(v2, v3, edge_type);
|
||||
auto e32 = dba.InsertEdge(v3, v2, edge_type);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
TEST_EDGE_ITERABLE(v1.out(v1));
|
||||
TEST_EDGE_ITERABLE(v1.out(v2), {e12});
|
||||
@ -267,16 +267,16 @@ TEST(RecordAccessor, VertexEdgeConnectionsWithExistingVertex) {
|
||||
TEST(RecordAccessor, VertexEdgeConnectionsWithEdgeType) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto a = dba->EdgeType("a");
|
||||
auto b = dba->EdgeType("b");
|
||||
auto c = dba->EdgeType("c");
|
||||
auto ea = dba->InsertEdge(v1, v2, a);
|
||||
auto eb_1 = dba->InsertEdge(v2, v1, b);
|
||||
auto eb_2 = dba->InsertEdge(v2, v1, b);
|
||||
auto ec = dba->InsertEdge(v1, v2, c);
|
||||
dba->AdvanceCommand();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto a = dba.EdgeType("a");
|
||||
auto b = dba.EdgeType("b");
|
||||
auto c = dba.EdgeType("c");
|
||||
auto ea = dba.InsertEdge(v1, v2, a);
|
||||
auto eb_1 = dba.InsertEdge(v2, v1, b);
|
||||
auto eb_2 = dba.InsertEdge(v2, v1, b);
|
||||
auto ec = dba.InsertEdge(v1, v2, c);
|
||||
dba.AdvanceCommand();
|
||||
|
||||
TEST_EDGE_ITERABLE(v1.in(), {eb_1, eb_2});
|
||||
TEST_EDGE_ITERABLE(v2.in(), {ea, ec});
|
||||
|
@ -11,13 +11,13 @@ TEST(StateDelta, CreateVertex) {
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta =
|
||||
database::StateDelta::CreateVertex(dba->transaction_id(), gid0);
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
database::StateDelta::CreateVertex(dba.transaction_id(), gid0);
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->FindVertexOptional(gid0, false);
|
||||
auto vertex = dba.FindVertexOptional(gid0, false);
|
||||
EXPECT_TRUE(vertex);
|
||||
EXPECT_EQ(vertex->CypherId(), 0);
|
||||
}
|
||||
@ -29,19 +29,19 @@ TEST(StateDelta, RemoveVertex) {
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex(gid0);
|
||||
dba->Commit();
|
||||
dba.InsertVertex(gid0);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta =
|
||||
database::StateDelta::RemoveVertex(dba->transaction_id(), gid0, true);
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
database::StateDelta::RemoveVertex(dba.transaction_id(), gid0, true);
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->FindVertexOptional(gid0, false);
|
||||
auto vertex = dba.FindVertexOptional(gid0, false);
|
||||
EXPECT_FALSE(vertex);
|
||||
}
|
||||
}
|
||||
@ -54,21 +54,21 @@ TEST(StateDelta, CreateEdge) {
|
||||
auto gid2 = generator.Next();
|
||||
{
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex(gid0);
|
||||
dba->InsertVertex(gid1);
|
||||
dba->Commit();
|
||||
dba.InsertVertex(gid0);
|
||||
dba.InsertVertex(gid1);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta =
|
||||
database::StateDelta::CreateEdge(dba->transaction_id(), gid2, gid0,
|
||||
gid1, dba->EdgeType("edge"), "edge");
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
database::StateDelta::CreateEdge(dba.transaction_id(), gid2, gid0,
|
||||
gid1, dba.EdgeType("edge"), "edge");
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto edge = dba->FindEdgeOptional(gid2, false);
|
||||
auto edge = dba.FindEdgeOptional(gid2, false);
|
||||
EXPECT_TRUE(edge);
|
||||
}
|
||||
}
|
||||
@ -81,20 +81,20 @@ TEST(StateDelta, RemoveEdge) {
|
||||
auto gid2 = generator.Next();
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex(gid0);
|
||||
auto v1 = dba->InsertVertex(gid1);
|
||||
dba->InsertEdge(v0, v1, dba->EdgeType("edge"), gid2);
|
||||
dba->Commit();
|
||||
auto v0 = dba.InsertVertex(gid0);
|
||||
auto v1 = dba.InsertVertex(gid1);
|
||||
dba.InsertEdge(v0, v1, dba.EdgeType("edge"), gid2);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta = database::StateDelta::RemoveEdge(dba->transaction_id(), gid2);
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
auto delta = database::StateDelta::RemoveEdge(dba.transaction_id(), gid2);
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto edge = dba->FindEdgeOptional(gid2, false);
|
||||
auto edge = dba.FindEdgeOptional(gid2, false);
|
||||
EXPECT_FALSE(edge);
|
||||
}
|
||||
}
|
||||
@ -105,23 +105,23 @@ TEST(StateDelta, AddLabel) {
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex(gid0);
|
||||
dba->Commit();
|
||||
dba.InsertVertex(gid0);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta = database::StateDelta::AddLabel(dba->transaction_id(), gid0,
|
||||
dba->Label("label"), "label");
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
auto delta = database::StateDelta::AddLabel(dba.transaction_id(), gid0,
|
||||
dba.Label("label"), "label");
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->FindVertexOptional(gid0, false);
|
||||
auto vertex = dba.FindVertexOptional(gid0, false);
|
||||
EXPECT_TRUE(vertex);
|
||||
auto labels = vertex->labels();
|
||||
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 dba = db.Access();
|
||||
auto vertex = dba->InsertVertex(gid0);
|
||||
vertex.add_label(dba->Label("label"));
|
||||
dba->Commit();
|
||||
auto vertex = dba.InsertVertex(gid0);
|
||||
vertex.add_label(dba.Label("label"));
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta = database::StateDelta::RemoveLabel(
|
||||
dba->transaction_id(), gid0, dba->Label("label"), "label");
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
dba.transaction_id(), gid0, dba.Label("label"), "label");
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->FindVertexOptional(gid0, false);
|
||||
auto vertex = dba.FindVertexOptional(gid0, false);
|
||||
EXPECT_TRUE(vertex);
|
||||
auto labels = vertex->labels();
|
||||
EXPECT_EQ(labels.size(), 0);
|
||||
@ -157,22 +157,22 @@ TEST(StateDelta, SetPropertyVertex) {
|
||||
auto gid0 = generator.Next();
|
||||
{
|
||||
auto dba = db.Access();
|
||||
dba->InsertVertex(gid0);
|
||||
dba->Commit();
|
||||
dba.InsertVertex(gid0);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta = database::StateDelta::PropsSetVertex(
|
||||
dba->transaction_id(), gid0, dba->Property("property"), "property",
|
||||
dba.transaction_id(), gid0, dba.Property("property"), "property",
|
||||
PropertyValue(2212));
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto vertex = dba->FindVertexOptional(gid0, false);
|
||||
auto vertex = dba.FindVertexOptional(gid0, false);
|
||||
EXPECT_TRUE(vertex);
|
||||
auto prop = vertex->PropsAt(dba->Property("property"));
|
||||
auto prop = vertex->PropsAt(dba.Property("property"));
|
||||
EXPECT_EQ(prop.Value<int64_t>(), 2212);
|
||||
}
|
||||
}
|
||||
@ -185,24 +185,24 @@ TEST(StateDelta, SetPropertyEdge) {
|
||||
auto gid2 = generator.Next();
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto v0 = dba->InsertVertex(gid0);
|
||||
auto v1 = dba->InsertVertex(gid1);
|
||||
dba->InsertEdge(v0, v1, dba->EdgeType("edge"), gid2);
|
||||
dba->Commit();
|
||||
auto v0 = dba.InsertVertex(gid0);
|
||||
auto v1 = dba.InsertVertex(gid1);
|
||||
dba.InsertEdge(v0, v1, dba.EdgeType("edge"), gid2);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto delta = database::StateDelta::PropsSetEdge(
|
||||
dba->transaction_id(), gid2, dba->Property("property"), "property",
|
||||
dba.transaction_id(), gid2, dba.Property("property"), "property",
|
||||
PropertyValue(2212));
|
||||
delta.Apply(*dba);
|
||||
dba->Commit();
|
||||
delta.Apply(dba);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto edge = dba->FindEdgeOptional(gid2, false);
|
||||
auto edge = dba.FindEdgeOptional(gid2, false);
|
||||
EXPECT_TRUE(edge);
|
||||
auto prop = edge->PropsAt(dba->Property("property"));
|
||||
auto prop = edge->PropsAt(dba.Property("property"));
|
||||
EXPECT_EQ(prop.Value<int64_t>(), 2212);
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,9 @@ TEST_F(StatTest, CountTest1) {
|
||||
COMPARE(stat, 0, 0, 0);
|
||||
|
||||
auto dba = db_.Access();
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba->InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
dba.InsertVertex();
|
||||
|
||||
COMPARE(stat, 0, 0, 0);
|
||||
db_.RefreshStat();
|
||||
@ -34,31 +34,31 @@ TEST_F(StatTest, CountTest2) {
|
||||
COMPARE(stat, 0, 0, 0);
|
||||
|
||||
auto dba = db_.Access();
|
||||
auto type = dba->EdgeType("edge");
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v3 = dba->InsertVertex();
|
||||
auto v4 = dba->InsertVertex();
|
||||
dba->InsertEdge(v1, v2, type);
|
||||
dba->InsertEdge(v2, v2, type);
|
||||
dba->InsertEdge(v3, v2, type);
|
||||
dba->InsertEdge(v4, v2, type);
|
||||
dba->InsertEdge(v1, v3, type);
|
||||
auto type = dba.EdgeType("edge");
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto v3 = dba.InsertVertex();
|
||||
auto v4 = dba.InsertVertex();
|
||||
dba.InsertEdge(v1, v2, type);
|
||||
dba.InsertEdge(v2, v2, type);
|
||||
dba.InsertEdge(v3, v2, type);
|
||||
dba.InsertEdge(v4, v2, type);
|
||||
dba.InsertEdge(v1, v3, type);
|
||||
|
||||
COMPARE(stat, 0, 0, 0);
|
||||
db_.RefreshStat();
|
||||
COMPARE(stat, 4, 5, 2.5);
|
||||
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
|
||||
auto dba1 = db_.Access();
|
||||
auto v22 = dba1->FindVertex(v2.gid(), true);
|
||||
dba1->DetachRemoveVertex(v22);
|
||||
auto v22 = dba1.FindVertex(v2.gid(), true);
|
||||
dba1.DetachRemoveVertex(v22);
|
||||
|
||||
db_.RefreshStat();
|
||||
COMPARE(stat, 4, 5, 2.5);
|
||||
|
||||
dba1->Commit();
|
||||
dba1.Commit();
|
||||
db_.CollectGarbage();
|
||||
db_.RefreshStat();
|
||||
COMPARE(stat, 3, 1, 2.0 / 3);
|
||||
|
@ -19,7 +19,7 @@ class AllTypesFixture : public testing::Test {
|
||||
protected:
|
||||
std::vector<TypedValue> values_;
|
||||
database::GraphDb db_;
|
||||
std::unique_ptr<database::GraphDbAccessor> dba_{db_.Access()};
|
||||
database::GraphDbAccessor dba_{db_.Access()};
|
||||
|
||||
void SetUp() override {
|
||||
values_.emplace_back(TypedValue::Null);
|
||||
@ -35,11 +35,11 @@ class AllTypesFixture : public testing::Test {
|
||||
{"c", 42},
|
||||
{"d", 0.5},
|
||||
{"e", TypedValue::Null}});
|
||||
auto vertex = dba_->InsertVertex();
|
||||
auto vertex = dba_.InsertVertex();
|
||||
values_.emplace_back(vertex);
|
||||
values_.emplace_back(
|
||||
dba_->InsertEdge(vertex, vertex, dba_->EdgeType("et")));
|
||||
values_.emplace_back(query::Path(dba_->InsertVertex()));
|
||||
dba_.InsertEdge(vertex, vertex, dba_.EdgeType("et")));
|
||||
values_.emplace_back(query::Path(dba_.InsertVertex()));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -11,13 +11,13 @@ class UniqueLabelPropertiesTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto dba = db_.AccessBlocking();
|
||||
label_ = dba->Label("label");
|
||||
property1_ = dba->Property("property1");
|
||||
property2_ = dba->Property("property2");
|
||||
property3_ = dba->Property("property3");
|
||||
label_ = dba.Label("label");
|
||||
property1_ = dba.Property("property1");
|
||||
property2_ = dba.Property("property2");
|
||||
property3_ = dba.Property("property3");
|
||||
constraint_.AddConstraint(label_, {property1_, property2_, property3_},
|
||||
dba->transaction());
|
||||
dba->Commit();
|
||||
dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
database::GraphDb db_;
|
||||
@ -40,12 +40,12 @@ TEST_F(UniqueLabelPropertiesTest, BuildDrop) {
|
||||
constraint_.Exists(label_, {property1_, property2_, property3_}));
|
||||
EXPECT_FALSE(
|
||||
constraint_.Exists(label_, {property1_, property2_}));
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.AccessBlocking();
|
||||
constraint_.RemoveConstraint(label_, {property2_, property1_, property3_});
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
@ -53,129 +53,129 @@ TEST_F(UniqueLabelPropertiesTest, BuildDrop) {
|
||||
constraint_.Exists(label_, {property2_, property1_, property3_}));
|
||||
EXPECT_FALSE(
|
||||
constraint_.Exists(label_, {property1_, property2_, property3_}));
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertiesTest, BuildWithViolation) {
|
||||
auto dba1 = db_.Access();
|
||||
auto v1 = dba1->InsertVertex();
|
||||
auto v1 = dba1.InsertVertex();
|
||||
v1.add_label(label_);
|
||||
v1.PropsSet(property1_, value1_);
|
||||
v1.PropsSet(property2_, value2_);
|
||||
v1.PropsSet(property3_, value3_);
|
||||
|
||||
auto v2 = dba1->InsertVertex();
|
||||
auto v2 = dba1.InsertVertex();
|
||||
v2.add_label(label_);
|
||||
v2.PropsSet(property1_, value1_);
|
||||
v2.PropsSet(property3_, value3_);
|
||||
|
||||
auto v3 = dba1->InsertVertex();
|
||||
auto v3 = dba1.InsertVertex();
|
||||
v3.add_label(label_);
|
||||
v3.PropsSet(property3_, value3_);
|
||||
v3.PropsSet(property1_, value1_);
|
||||
v3.PropsSet(property2_, value2_);
|
||||
dba1->Commit();
|
||||
dba1.Commit();
|
||||
|
||||
auto dba2 = db_.Access();
|
||||
auto v4 = dba2->FindVertex(v1.gid(), false);
|
||||
auto v5 = dba2->FindVertex(v2.gid(), false);
|
||||
auto v6 = dba2->FindVertex(v3.gid(), false);
|
||||
constraint_.UpdateOnAddLabel(label_, v4, dba2->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v5, dba2->transaction());
|
||||
EXPECT_THROW(constraint_.UpdateOnAddLabel(label_, v6, dba2->transaction()),
|
||||
auto v4 = dba2.FindVertex(v1.gid(), false);
|
||||
auto v5 = dba2.FindVertex(v2.gid(), false);
|
||||
auto v6 = dba2.FindVertex(v3.gid(), false);
|
||||
constraint_.UpdateOnAddLabel(label_, v4, dba2.transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v5, dba2.transaction());
|
||||
EXPECT_THROW(constraint_.UpdateOnAddLabel(label_, v6, dba2.transaction()),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertInsert) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
EXPECT_THROW(constraint_.UpdateOnAddProperty(property1_, value1_, v,
|
||||
dba->transaction()),
|
||||
dba.transaction()),
|
||||
database::IndexConstraintViolationException);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertInsertDiffValues) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
PropertyValue other3("Some other value 3");
|
||||
v.PropsSet(property3_, other3);
|
||||
constraint_.UpdateOnAddProperty(property3_, other3, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, other3, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
PropertyValue other2("Some other value 2");
|
||||
v.PropsSet(property2_, other2);
|
||||
constraint_.UpdateOnAddProperty(property2_, other2, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, other2, v, dba.transaction());
|
||||
PropertyValue other1("Some other value 1");
|
||||
v.PropsSet(property1_, other1);
|
||||
constraint_.UpdateOnAddProperty(property1_, other1, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddProperty(property1_, other1, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertAbortInsert) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
dba->Abort();
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
dba.Abort();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,37 +183,37 @@ TEST_F(UniqueLabelPropertiesTest, InsertRemoveAbortInsert) {
|
||||
gid::Gid gid = 0;
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
v.PropsErase(property2_);
|
||||
constraint_.UpdateOnRemoveProperty(property2_, value2_, v,
|
||||
dba->transaction());
|
||||
dba->Abort();
|
||||
dba.transaction());
|
||||
dba.Abort();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v,
|
||||
dba->transaction()),
|
||||
dba.transaction()),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
}
|
||||
@ -221,31 +221,31 @@ TEST_F(UniqueLabelPropertiesTest, InsertRemoveAbortInsert) {
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertInsertSameTransaction) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v2, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v2, dba.transaction());
|
||||
v1.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v1, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v1, dba.transaction());
|
||||
v1.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v1,
|
||||
dba->transaction());
|
||||
dba.transaction());
|
||||
v1.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v1,
|
||||
dba->transaction());
|
||||
dba.transaction());
|
||||
v2.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v2,
|
||||
dba->transaction());
|
||||
dba.transaction());
|
||||
v2.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v2,
|
||||
dba->transaction());
|
||||
dba.transaction());
|
||||
v2.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v2,
|
||||
dba->transaction());
|
||||
dba.transaction());
|
||||
|
||||
v1.PropsSet(property3_, value3_);
|
||||
EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v1,
|
||||
dba->transaction()),
|
||||
dba.transaction()),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
}
|
||||
@ -253,31 +253,31 @@ TEST_F(UniqueLabelPropertiesTest, InsertInsertSameTransaction) {
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertInsertReversed) {
|
||||
auto dba1 = db_.Access();
|
||||
auto dba2 = db_.Access();
|
||||
auto v1 = dba1->InsertVertex();
|
||||
auto v2 = dba2->InsertVertex();
|
||||
auto v1 = dba1.InsertVertex();
|
||||
auto v2 = dba2.InsertVertex();
|
||||
v2.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v2, dba2->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v2, dba2.transaction());
|
||||
v1.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v1, dba1->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v1, dba1.transaction());
|
||||
v1.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v1,
|
||||
dba1->transaction());
|
||||
dba1.transaction());
|
||||
v1.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v1,
|
||||
dba1->transaction());
|
||||
dba1.transaction());
|
||||
v2.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v2,
|
||||
dba2->transaction());
|
||||
dba2.transaction());
|
||||
v2.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v2,
|
||||
dba2->transaction());
|
||||
dba2.transaction());
|
||||
v2.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v2,
|
||||
dba2->transaction());
|
||||
dba2.transaction());
|
||||
|
||||
v1.PropsSet(property3_, value3_);
|
||||
EXPECT_THROW(constraint_.UpdateOnAddProperty(property3_, value3_, v1,
|
||||
dba1->transaction()),
|
||||
dba1.transaction()),
|
||||
mvcc::SerializationError);
|
||||
}
|
||||
|
||||
@ -285,87 +285,87 @@ TEST_F(UniqueLabelPropertiesTest, InsertRemoveInsert) {
|
||||
gid::Gid gid = 0;
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
v.PropsErase(property2_);
|
||||
constraint_.UpdateOnRemoveProperty(property2_, value2_, v,
|
||||
dba->transaction());
|
||||
dba->Commit();
|
||||
dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertRemoveInsertSameTransaction) {
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsErase(property2_);
|
||||
constraint_.UpdateOnRemoveProperty(property2_, value2_, v,
|
||||
dba->transaction());
|
||||
dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertiesTest, InsertDropInsert) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
}
|
||||
{
|
||||
auto dba = db_.AccessBlocking();
|
||||
constraint_.RemoveConstraint(label_, {property2_, property3_, property1_});
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.PropsSet(property2_, value2_);
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property2_, value2_, v, dba.transaction());
|
||||
v.PropsSet(property1_, value1_);
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddProperty(property1_, value1_, v, dba.transaction());
|
||||
v.add_label(label_);
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
|
||||
constraint_.UpdateOnAddLabel(label_, v, dba.transaction());
|
||||
v.PropsSet(property3_, value3_);
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba->transaction());
|
||||
dba->Commit();
|
||||
constraint_.UpdateOnAddProperty(property3_, value3_, v, dba.transaction());
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,10 @@ class UniqueLabelPropertyTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
auto dba = db_.Access();
|
||||
label_ = dba->Label("label");
|
||||
property_ = dba->Property("property");
|
||||
dba->BuildUniqueConstraint(label_, property_);
|
||||
dba->Commit();
|
||||
label_ = dba.Label("label");
|
||||
property_ = dba.Property("property");
|
||||
dba.BuildUniqueConstraint(label_, property_);
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
database::GraphDb db_;
|
||||
@ -24,51 +24,51 @@ class UniqueLabelPropertyTest : public ::testing::Test {
|
||||
TEST_F(UniqueLabelPropertyTest, BuildDrop) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
EXPECT_TRUE(dba->UniqueConstraintExists(label_, property_));
|
||||
dba->Commit();
|
||||
EXPECT_TRUE(dba.UniqueConstraintExists(label_, property_));
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->DeleteUniqueConstraint(label_, property_);
|
||||
dba->Commit();
|
||||
dba.DeleteUniqueConstraint(label_, property_);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
EXPECT_FALSE(dba->UniqueConstraintExists(label_, property_));
|
||||
dba->Commit();
|
||||
EXPECT_FALSE(dba.UniqueConstraintExists(label_, property_));
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertyTest, BuildWithViolation) {
|
||||
auto dba1 = db_.Access();
|
||||
auto l1 = dba1->Label("l1");
|
||||
auto p1 = dba1->Property("p1");
|
||||
auto l1 = dba1.Label("l1");
|
||||
auto p1 = dba1.Property("p1");
|
||||
|
||||
auto v1 = dba1->InsertVertex();
|
||||
auto v1 = dba1.InsertVertex();
|
||||
v1.add_label(l1);
|
||||
v1.PropsSet(p1, value_);
|
||||
|
||||
auto v2 = dba1->InsertVertex();
|
||||
auto v2 = dba1.InsertVertex();
|
||||
v2.add_label(l1);
|
||||
v2.PropsSet(p1, value_);
|
||||
dba1->Commit();
|
||||
dba1.Commit();
|
||||
|
||||
auto dba2 = db_.Access();
|
||||
EXPECT_THROW(dba2->BuildUniqueConstraint(l1, p1),
|
||||
EXPECT_THROW(dba2.BuildUniqueConstraint(l1, p1),
|
||||
database::IndexConstraintViolationException);
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertyTest, InsertInsert) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
EXPECT_THROW(v.PropsSet(property_, value_),
|
||||
database::IndexConstraintViolationException);
|
||||
@ -78,35 +78,35 @@ TEST_F(UniqueLabelPropertyTest, InsertInsert) {
|
||||
TEST_F(UniqueLabelPropertyTest, InsertInsertDiffValues) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
PropertyValue other_value{"Some other value"};
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, other_value);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertyTest, InsertAbortInsert) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Abort();
|
||||
dba.Abort();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,21 +114,21 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveAbortInsert) {
|
||||
gid::Gid gid = 0;
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
gid = v.gid();
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
v.PropsErase(property_);
|
||||
dba->Abort();
|
||||
dba.Abort();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
EXPECT_THROW(v.PropsSet(property_, value_),
|
||||
database::IndexConstraintViolationException);
|
||||
@ -138,11 +138,11 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveAbortInsert) {
|
||||
TEST_F(UniqueLabelPropertyTest, InsertInsertSameTransaction) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v1 = dba->InsertVertex();
|
||||
auto v1 = dba.InsertVertex();
|
||||
v1.add_label(label_);
|
||||
v1.PropsSet(property_, value_);
|
||||
|
||||
auto v2 = dba->InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
v2.add_label(label_);
|
||||
EXPECT_THROW(v2.PropsSet(property_, value_),
|
||||
database::IndexConstraintViolationException);
|
||||
@ -153,12 +153,12 @@ TEST_F(UniqueLabelPropertyTest, InsertInsertReversed) {
|
||||
auto dba1 = db_.Access();
|
||||
auto dba2 = db_.Access();
|
||||
|
||||
auto v2 = dba2->InsertVertex();
|
||||
auto v2 = dba2.InsertVertex();
|
||||
v2.add_label(label_);
|
||||
v2.PropsSet(property_, value_);
|
||||
dba2->Commit();
|
||||
dba2.Commit();
|
||||
|
||||
auto v1 = dba1->InsertVertex();
|
||||
auto v1 = dba1.InsertVertex();
|
||||
v1.add_label(label_);
|
||||
EXPECT_THROW(v1.PropsSet(property_, value_),
|
||||
mvcc::SerializationError);
|
||||
@ -168,21 +168,21 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsert) {
|
||||
gid::Gid gid = 0;
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
gid = v.gid();
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->FindVertex(gid, false);
|
||||
auto v = dba.FindVertex(gid, false);
|
||||
v.PropsErase(property_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
}
|
||||
@ -190,33 +190,33 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsert) {
|
||||
|
||||
TEST_F(UniqueLabelPropertyTest, InsertRemoveInsertSameTransaction) {
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
v.PropsErase(property_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
|
||||
TEST_F(UniqueLabelPropertyTest, InsertDropInsert) {
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
dba->DeleteUniqueConstraint(label_, property_);
|
||||
dba->Commit();
|
||||
dba.DeleteUniqueConstraint(label_, property_);
|
||||
dba.Commit();
|
||||
}
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto v = dba->InsertVertex();
|
||||
auto v = dba.InsertVertex();
|
||||
v.add_label(label_);
|
||||
v.PropsSet(property_, value_);
|
||||
dba->Commit();
|
||||
dba.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,20 +35,20 @@ class RecoveryTest : public ::testing::Test {
|
||||
|
||||
TEST_F(RecoveryTest, TestVerticesRecovered) {
|
||||
auto dba = db_.Access();
|
||||
EXPECT_EQ(dba->VerticesCount(), 10);
|
||||
EXPECT_EQ(dba->VerticesCount(dba->Label("Comment")), 5);
|
||||
for (const auto &vertex : dba->Vertices(dba->Label("Comment"), false)) {
|
||||
EXPECT_TRUE(vertex.has_label(dba->Label("Message")));
|
||||
EXPECT_EQ(dba.VerticesCount(), 10);
|
||||
EXPECT_EQ(dba.VerticesCount(dba.Label("Comment")), 5);
|
||||
for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
|
||||
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) {
|
||||
auto dba = db_.Access();
|
||||
bool found = false;
|
||||
for (const auto &vertex : dba->Vertices(dba->Label("Comment"), false)) {
|
||||
auto id_prop = query::TypedValue(vertex.PropsAt(dba->Property("id")));
|
||||
auto browser = query::TypedValue(vertex.PropsAt(dba->Property("browser")));
|
||||
for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
|
||||
auto id_prop = query::TypedValue(vertex.PropsAt(dba.Property("id")));
|
||||
auto browser = query::TypedValue(vertex.PropsAt(dba.Property("browser")));
|
||||
if (id_prop.IsString() && id_prop.Value<std::string>() == "2") {
|
||||
EXPECT_FALSE(found);
|
||||
found = true;
|
||||
@ -62,17 +62,17 @@ TEST_F(RecoveryTest, TestPropertyNull) {
|
||||
|
||||
TEST_F(RecoveryTest, TestEdgesRecovered) {
|
||||
auto dba = db_.Access();
|
||||
EXPECT_EQ(dba->EdgesCount(), 5);
|
||||
for (const auto &edge : dba->Edges(false)) {
|
||||
EXPECT_TRUE(edge.EdgeType() == dba->EdgeType("POSTED_ON"));
|
||||
EXPECT_EQ(dba.EdgesCount(), 5);
|
||||
for (const auto &edge : dba.Edges(false)) {
|
||||
EXPECT_TRUE(edge.EdgeType() == dba.EdgeType("POSTED_ON"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(RecoveryTest, TestQuote) {
|
||||
auto dba = db_.Access();
|
||||
for (const auto &vertex : dba->Vertices(dba->Label("Comment"), false)) {
|
||||
auto id_prop = query::TypedValue(vertex.PropsAt(dba->Property("id")));
|
||||
auto country = query::TypedValue(vertex.PropsAt(dba->Property("country")));
|
||||
for (const auto &vertex : dba.Vertices(dba.Label("Comment"), false)) {
|
||||
auto id_prop = query::TypedValue(vertex.PropsAt(dba.Property("id")));
|
||||
auto country = query::TypedValue(vertex.PropsAt(dba.Property("country")));
|
||||
if (id_prop.IsString() && id_prop.Value<std::string>() == "1") {
|
||||
EXPECT_TRUE(country.IsString());
|
||||
EXPECT_EQ(country.Value<std::string>(), "United Kingdom");
|
||||
@ -82,17 +82,17 @@ TEST_F(RecoveryTest, TestQuote) {
|
||||
|
||||
TEST_F(RecoveryTest, TestNodeLabelFlag) {
|
||||
auto dba = db_.Access();
|
||||
for (const auto &vertex : dba->Vertices(false)) {
|
||||
EXPECT_TRUE(vertex.has_label(dba->Label("First")));
|
||||
EXPECT_TRUE(vertex.has_label(dba->Label("Second")));
|
||||
for (const auto &vertex : dba.Vertices(false)) {
|
||||
EXPECT_TRUE(vertex.has_label(dba.Label("First")));
|
||||
EXPECT_TRUE(vertex.has_label(dba.Label("Second")));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(RecoveryTest, TestRelationshipType) {
|
||||
auto dba = db_.Access();
|
||||
EXPECT_EQ(dba->EdgesCount(), 5);
|
||||
for (const auto &edge : dba->Edges(false)) {
|
||||
EXPECT_TRUE(edge.EdgeType() == dba->EdgeType("TYPE"));
|
||||
EXPECT_EQ(dba.EdgesCount(), 5);
|
||||
for (const auto &edge : dba.Edges(false)) {
|
||||
EXPECT_TRUE(edge.EdgeType() == dba.EdgeType("TYPE"));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user