Constraint code cleanup

Summary: Refactor tests, remove some test cases, refactor some methods in `GraphDbAccessor`.

Reviewers: msantl

Reviewed By: msantl

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1933
This commit is contained in:
Vinko Kasljevic 2019-04-02 16:30:25 +02:00
parent dc231fe4e7
commit 2a63e2f12d
12 changed files with 191 additions and 224 deletions

View File

@ -0,0 +1,18 @@
/// @file
#pragma once
#include "utils/exceptions.hpp"
namespace database {
/// Thrown when creating an index which already exists.
class IndexExistsException : public utils::BasicException {
using utils::BasicException::BasicException;
};
/// Thrown on concurrent index creation when the transaction engine fails to
/// start a new transaction.
class IndexTransactionException : public utils::BasicException {
using utils::BasicException::BasicException;
};
} // namespace database

View File

@ -255,9 +255,9 @@ GraphDbAccessor::ListUniqueLabelPropertyConstraints() const {
return db_.storage().unique_label_property_constraints_.ListConstraints();
}
void GraphDbAccessor::UpdateLabelIndices(storage::Label label,
const VertexAccessor &vertex_accessor,
const Vertex *vertex) {
void GraphDbAccessor::UpdateOnAddLabel(storage::Label label,
const VertexAccessor &vertex_accessor,
const Vertex *vertex) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
auto *vlist_ptr = vertex_accessor.address();
@ -284,7 +284,7 @@ void GraphDbAccessor::UpdateOnRemoveLabel(
label, accessor, transaction());
}
void GraphDbAccessor::UpdatePropertyIndex(
void GraphDbAccessor::UpdateOnAddProperty(
storage::Property property, const PropertyValue &value,
const RecordAccessor<Vertex> &vertex_accessor, const Vertex *vertex) {
DCHECK(!commited_ && !aborted_) << "Accessor committed or aborted";
@ -299,9 +299,9 @@ void GraphDbAccessor::UpdatePropertyIndex(
}
}
void GraphDbAccessor::UpdateOnPropertyRemove(
storage::Property property, const Vertex *vertex,
const RecordAccessor<Vertex> &accessor) {
void GraphDbAccessor::UpdateOnRemoveProperty(
storage::Property property, const RecordAccessor<Vertex> &accessor,
const Vertex *vertex) {
db_.storage().unique_label_property_constraints_.UpdateOnRemoveProperty(
property, accessor, transaction());
@ -316,7 +316,7 @@ void GraphDbAccessor::BuildExistenceConstraint(
storage::Label label, const std::vector<storage::Property> &properties) {
auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction().id_));
ExistenceRule rule{label, properties};
storage::constraints::ExistenceRule rule{label, properties};
for (auto v : dba->Vertices(false)) {
if (!CheckIfSatisfiesExistenceRule(v.GetOld(), rule)) {
@ -326,7 +326,10 @@ void GraphDbAccessor::BuildExistenceConstraint(
}
}
if (!db_.storage().existence_constraints_.AddConstraint(rule)) return;
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(),
@ -342,8 +345,11 @@ void GraphDbAccessor::DeleteExistenceConstraint(
storage::Label label, const std::vector<storage::Property> &properties) {
auto dba =
db_.AccessBlocking(std::experimental::make_optional(transaction().id_));
ExistenceRule rule{label, properties};
if (!db_.storage().existence_constraints_.RemoveConstraint(rule)) return;
storage::constraints::ExistenceRule rule{label, properties};
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(),
@ -358,12 +364,12 @@ void GraphDbAccessor::DeleteExistenceConstraint(
bool GraphDbAccessor::ExistenceConstraintExists(
storage::Label label,
const std::vector<storage::Property> &properties) const {
ExistenceRule rule{label, properties};
storage::constraints::ExistenceRule rule{label, properties};
return db_.storage().existence_constraints_.Exists(rule);
}
std::vector<ExistenceRule> GraphDbAccessor::ExistenceConstraintsList()
const {
std::vector<storage::constraints::ExistenceRule>
GraphDbAccessor::ListExistenceConstraints() const {
return db_.storage().existence_constraints_.ListConstraints();
}

View File

@ -11,6 +11,7 @@
#include <cppitertools/filter.hpp>
#include <cppitertools/imap.hpp>
#include "database/single_node/exceptions.hpp"
#include "database/single_node/graph_db.hpp"
#include "storage/common/types/types.hpp"
#include "storage/single_node/constraints/exceptions.hpp"
@ -19,26 +20,8 @@
#include "transactions/transaction.hpp"
#include "transactions/type.hpp"
#include "utils/bound.hpp"
#include "utils/exceptions.hpp"
namespace database {
/** Thrown when creating an index which already exists. */
class IndexExistsException : public utils::BasicException {
using utils::BasicException::BasicException;
};
/** Thrown when creating an index which already exists. */
class IndexCreationOnWorkerException : public utils::BasicException {
using utils::BasicException::BasicException;
};
/// Thrown on concurrent index creation when the transaction engine fails to
/// start a new transaction.
class IndexTransactionException : public utils::BasicException {
using utils::BasicException::BasicException;
};
/**
* Base accessor for the database object: exposes functions for operating on the
* database. All the functions in this class should be self-sufficient: for
@ -514,7 +497,8 @@ class GraphDbAccessor {
/**
* Returns the list of existence constraints currently active.
*/
std::vector<ExistenceRule> ExistenceConstraintsList() const;
std::vector<storage::constraints::ExistenceRule> ListExistenceConstraints()
const;
/**
* Return approximate number of all vertices in the database.
@ -664,18 +648,6 @@ class GraphDbAccessor {
**/
std::vector<std::pair<std::string, std::string>> StorageInfo() const;
/**
* Insert this vertex into corresponding label and label+property (if it
* exists) index.
*
* @param label - label with which to insert vertex label record
* @param vertex_accessor - vertex_accessor to insert
* @param vertex - vertex record to insert
*/
void UpdateLabelIndices(storage::Label label,
const VertexAccessor &vertex_accessor,
const Vertex *const vertex);
private:
GraphDb &db_;
tx::Transaction &transaction_;
@ -687,29 +659,46 @@ class GraphDbAccessor {
bool aborted_{false};
/**
* Notifies storage about change.
* Notifies storage about a change.
*
* @param label - label that was added
* @param vertex_accessor - vertex_accessor that was updated
* @param vertex - vertex that was updated
*/
void UpdateOnRemoveLabel(storage::Label label,
void UpdateOnAddLabel(storage::Label label,
const VertexAccessor &vertex_accessor,
const Vertex *vertex);
/**
* Notifies storage about a change.
*
* @param label - label that was removed
* @param vertex_accessor - vertex_accessor that was updated
*/
void UpdateOnRemoveLabel(storage::Label label,
const RecordAccessor<Vertex> &accessor);
/**
* Notifies storage about change.
* Notifies storage about a change.
* @param vertex_accessor - vertex_accessor that was updated
* @param vertex - vertex that was updated
*/
void UpdateOnPropertyRemove(storage::Property property,
const Vertex *vertex,
const RecordAccessor<Vertex> &accessor);
void UpdateOnRemoveProperty(storage::Property property,
const RecordAccessor<Vertex> &accessor,
const Vertex* vertex);
/**
* Insert this vertex into corresponding any label + 'property' index.
* @param property - vertex will be inserted into indexes which contain this
* property
* @param vertex_accessor - vertex accessor to insert
* @param vertex - vertex to insert
* Notifies storage about a change.
*
* @param property - property that was added
* @param value - corresponding value that was added
* @param vertex_accessor - vertex accessor that was updated
* @param vertex - vertex that was updated
*/
void UpdatePropertyIndex(storage::Property property,
void UpdateOnAddProperty(storage::Property property,
const PropertyValue &value,
const RecordAccessor<Vertex> &vertex_accessor,
const Vertex *const vertex);
const Vertex *vertex);
};
} // namespace database

View File

@ -58,7 +58,7 @@ bool Encode(const fs::path &snapshot_file, database::GraphDb &db,
// Write existence constraints to snapshoot
{
std::vector<communication::bolt::Value> existence_constraints;
for (const auto &rule : dba.ExistenceConstraintsList()) {
for (const auto &rule : dba.ListExistenceConstraints()) {
existence_constraints.emplace_back(dba.LabelName(rule.label));
existence_constraints.emplace_back(
static_cast<int64_t>(rule.properties.size()));

View File

@ -1,6 +1,6 @@
#include "storage/single_node/constraints/existence_constraints.hpp"
namespace database {
namespace storage::constraints {
bool Contains(const PropertyValueStore &store,
const std::vector<storage::Property> &properties) {
for (auto &property : properties) {
@ -13,7 +13,7 @@ bool Contains(const PropertyValueStore &store,
}
bool CheckIfSatisfiesExistenceRule(const Vertex *vertex,
const database::ExistenceRule &rule) {
const ExistenceRule &rule) {
if (!utils::Contains(vertex->labels_, rule.label)) return true;
if (!Contains(vertex->properties_, rule.properties)) return false;
@ -69,4 +69,4 @@ bool ExistenceConstraints::CheckOnRemoveProperty(
const std::vector<ExistenceRule> &ExistenceConstraints::ListConstraints() const {
return constraints_;
}
} // namespace database
} // namespace storage::constraints

View File

@ -10,7 +10,7 @@
#include "storage/single_node/vertex.hpp"
#include "transactions/type.hpp"
namespace database {
namespace storage::constraints {
/// Existence rule defines label -> set of properties rule. This means that
/// every vertex with that label has to have every property in the set of
@ -30,7 +30,7 @@ struct ExistenceRule {
};
bool CheckIfSatisfiesExistenceRule(const Vertex *vertex,
const database::ExistenceRule &rule);
const ExistenceRule &rule);
/// ExistenceConstraints contains all active constrains. Existence constraints
/// are restriction on the vertices and are defined by ExistenceRule.
@ -84,4 +84,4 @@ class ExistenceConstraints {
private:
std::vector<ExistenceRule> constraints_;
};
}; // namespace database
}; // namespace storage::constraints

View File

@ -26,7 +26,7 @@ void RecordAccessor<Vertex>::PropsSet(storage::Property key,
auto delta = StateDelta::PropsSetVertex(dba.transaction_id(), gid(), key,
dba.PropertyName(key), value);
update().properties_.set(key, value);
dba.UpdatePropertyIndex(key, value, *this, &update());
dba.UpdateOnAddProperty(key, value, *this, &update());
db_accessor().wal().Emplace(delta);
}
@ -48,7 +48,7 @@ void RecordAccessor<Vertex>::PropsErase(storage::Property key) {
StateDelta::PropsSetVertex(dba.transaction_id(), gid(), key,
dba.PropertyName(key), PropertyValue::Null);
update().properties_.set(key, PropertyValue::Null);
dba.UpdateOnPropertyRemove(key, GetNew(), *this);
dba.UpdateOnRemoveProperty(key, *this, GetNew());
dba.wal().Emplace(delta);
}

View File

@ -78,7 +78,7 @@ class Storage {
LabelPropertyIndex label_property_index_;
// existence constraints
ExistenceConstraints existence_constraints_;
storage::constraints::ExistenceConstraints existence_constraints_;
// unique constraints
storage::constraints::UniqueLabelPropertyConstraint

View File

@ -25,7 +25,7 @@ void VertexAccessor::add_label(storage::Label label) {
if (!utils::Contains(vertex.labels_, label)) {
vertex.labels_.emplace_back(label);
dba.wal().Emplace(delta);
dba.UpdateLabelIndices(label, *this, &vertex);
dba.UpdateOnAddLabel(label, *this, &vertex);
}
}
@ -40,6 +40,7 @@ void VertexAccessor::remove_label(storage::Label label) {
std::swap(*found, labels.back());
labels.pop_back();
dba.wal().Emplace(delta);
dba.UpdateOnRemoveLabel(label, *this);
}
}

View File

@ -168,8 +168,8 @@ class DbGenerator {
bool CompareExistenceConstraints(const database::GraphDbAccessor &dba1,
const database::GraphDbAccessor &dba2) {
auto c1 = dba1.ExistenceConstraintsList();
auto c2 = dba2.ExistenceConstraintsList();
auto c1 = dba1.ListExistenceConstraints();
auto c2 = dba2.ListExistenceConstraints();
auto compare_prop = [](auto &dba1, auto &p1, auto &dba2, auto &p2) {
std::vector<std::string> p1_names;

View File

@ -4,131 +4,132 @@
#include "database/single_node/graph_db.hpp"
#include "database/single_node/graph_db_accessor.hpp"
#include "storage/single_node/constraints/existence_constraints.hpp"
class ExistenceConstraintsTest : public ::testing::Test {
public:
void SetUp() override {}
database::ExistenceConstraints constraints_;
void SetUp() override {
auto dba = db_.Access();
label_ = dba->Label("label");
property_ = dba->Property("property");
properties_ = {property_};
rule_ = {label_, properties_};
dba->Commit();
}
storage::constraints::ExistenceConstraints constraints_;
database::GraphDb db_;
storage::Label label_;
storage::Property property_;
std::vector<storage::Property> properties_;
storage::constraints::ExistenceRule rule_;
};
TEST_F(ExistenceConstraintsTest, MultiBuildDrop) {
auto d = db_.Access();
auto label = d->Label("label");
auto prop = d->Property("property");
database::ExistenceRule rule{label, std::vector<storage::Property>{prop}};
d->Commit();
TEST_F(ExistenceConstraintsTest, BuildDrop) {
{
auto dba = db_.AccessBlocking();
constraints_.AddConstraint(rule);
EXPECT_TRUE(constraints_.Exists(rule));
auto dba = db_.Access();
EXPECT_FALSE(dba->ExistenceConstraintExists(label_, properties_));
dba->Commit();
}
{
auto dba = db_.AccessBlocking();
constraints_.RemoveConstraint(rule);
EXPECT_FALSE(constraints_.Exists(rule));
auto dba = db_.Access();
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();
}
}
TEST_F(ExistenceConstraintsTest, InsertTest) {
auto d = db_.Access();
auto label = d->Label("label");
auto prop = d->Property("property");
database::ExistenceRule rule{label, std::vector<storage::Property>{prop}};
d->Commit();
TEST_F(ExistenceConstraintsTest, BuildWithViolation) {
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label);
EXPECT_TRUE(constraints_.CheckOnAddLabel(v.GetNew(), label));
v.add_label(label_);
dba->Commit();
}
{
auto dba = db_.Access();
bool can_add_constraint = true;
for (auto v : dba->Vertices(false)) {
if (!database::CheckIfSatisfiesExistenceRule(v.GetOld(), rule)) {
can_add_constraint = false;
}
}
EXPECT_THROW(dba->BuildExistenceConstraint(label_, properties_),
database::IndexConstraintViolationException);
}
}
EXPECT_FALSE(can_add_constraint);
dba->Commit();
}
{
auto dba = db_.AccessBlocking();
constraints_.AddConstraint(rule);
dba->Commit();
}
TEST_F(ExistenceConstraintsTest, InsertFail) {
{
auto dba = db_.Access();
auto v1 = dba->InsertVertex();
v1.add_label(label);
EXPECT_FALSE(
constraints_.CheckOnAddLabel(v1.GetNew(), label));
auto v2 = dba->InsertVertex();
v2.PropsSet(prop, PropertyValue(false));
v2.add_label(label);
EXPECT_TRUE(constraints_.CheckOnAddLabel(v2.GetNew(), label));
dba->Commit();
}
{
auto dba = db_.AccessBlocking();
constraints_.RemoveConstraint(rule);
dba->BuildExistenceConstraint(label_, properties_);
dba->Commit();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label);
EXPECT_TRUE(constraints_.CheckOnAddLabel(v.GetNew(), label));
EXPECT_THROW(v.add_label(label_),
database::IndexConstraintViolationException);
}
}
TEST_F(ExistenceConstraintsTest, InsertPass) {
{
auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_);
dba->Commit();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.PropsSet(property_, PropertyValue("Something"));
v.add_label(label_);
dba->Commit();
}
}
TEST_F(ExistenceConstraintsTest, GraphDbAccessor) {
auto d = db_.Access();
auto label = d->Label("label");
auto prop = d->Property("property");
auto properties = std::vector<storage::Property>{prop};
d->Commit();
TEST_F(ExistenceConstraintsTest, RemoveFail) {
{
auto dba = db_.Access();
dba->BuildExistenceConstraint(label_, properties_);
dba->Commit();
}
gid::Gid gid;
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.PropsSet(property_, PropertyValue("Something"));
v.add_label(label_);
gid = v.gid();
dba->Commit();
}
{
auto dba = db_.Access();
auto v = dba->FindVertex(gid, false);
EXPECT_THROW(v.PropsErase(property_),
database::IndexConstraintViolationException);
}
}
TEST_F(ExistenceConstraintsTest, RemovePass) {
{
auto dba = db_.Access();
dba->BuildExistenceConstraint(label, properties);
// Constraint is not visible because transaction creates blocking
// transaction with different id;
dba->BuildExistenceConstraint(label_, properties_);
dba->Commit();
}
gid::Gid gid;
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.PropsSet(property_, PropertyValue("Something"));
v.add_label(label_);
gid = v.gid();
dba->Commit();
}
{
auto dba = db_.Access();
EXPECT_TRUE(dba->ExistenceConstraintExists(label, properties));
auto v1 = dba->InsertVertex();
EXPECT_THROW(v1.add_label(label),
database::IndexConstraintViolationException);
auto v2 = dba->InsertVertex();
v2.PropsSet(prop, PropertyValue(false));
v2.add_label(label);
EXPECT_THROW(v2.PropsErase(prop),
database::IndexConstraintViolationException);
v2.remove_label(label);
dba->Commit();
}
{
auto dba = db_.Access();
dba->DeleteExistenceConstraint(label, properties);
dba->Commit();
}
{
auto dba = db_.Access();
EXPECT_FALSE(dba->ExistenceConstraintExists(label, properties));
auto v1 = dba->InsertVertex();
v1.add_label(label);
auto v = dba->FindVertex(gid, false);
v.remove_label(label_);
v.PropsErase(property_);
dba->Commit();
}
}

View File

@ -4,15 +4,14 @@
#include "database/single_node/graph_db.hpp"
#include "database/single_node/graph_db_accessor.hpp"
#include "storage/single_node/constraints/unique_label_property_constraint.hpp"
class UniqueLabelPropertyTest : public ::testing::Test {
public:
void SetUp() override {
auto dba = db_.AccessBlocking();
auto dba = db_.Access();
label_ = dba->Label("label");
property_ = dba->Property("property");
constraint_.AddConstraint(label_, property_, dba->transaction());
dba->BuildUniqueConstraint(label_, property_);
dba->Commit();
}
@ -20,43 +19,42 @@ class UniqueLabelPropertyTest : public ::testing::Test {
storage::Label label_;
storage::Property property_;
PropertyValue value_{"value"};
storage::constraints::UniqueLabelPropertyConstraint constraint_;
};
TEST_F(UniqueLabelPropertyTest, BuildDrop) {
{
auto dba = db_.Access();
EXPECT_TRUE(constraint_.Exists(label_, property_));
EXPECT_TRUE(dba->UniqueConstraintExists(label_, property_));
dba->Commit();
}
{
auto dba = db_.Access();
constraint_.RemoveConstraint(label_, property_);
dba->DeleteUniqueConstraint(label_, property_);
dba->Commit();
}
{
auto dba = db_.Access();
EXPECT_FALSE(constraint_.Exists(label_, property_));
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 v1 = dba1->InsertVertex();
v1.add_label(label_);
v1.PropsSet(property_, value_);
v1.add_label(l1);
v1.PropsSet(p1, value_);
auto v2 = dba1->InsertVertex();
v2.add_label(label_);
v2.PropsSet(property_, value_);
v2.add_label(l1);
v2.PropsSet(p1, value_);
dba1->Commit();
auto dba2 = db_.Access();
auto v3 = dba2->FindVertex(v1.gid(), false);
auto v4 = dba2->FindVertex(v2.gid(), false);
constraint_.Update(v3, dba2->transaction());
EXPECT_THROW(constraint_.Update(v4, dba2->transaction()),
EXPECT_THROW(dba2->BuildUniqueConstraint(l1, p1),
database::IndexConstraintViolationException);
}
@ -65,23 +63,15 @@ TEST_F(UniqueLabelPropertyTest, InsertInsert) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Commit();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property_, value_, v,
dba->transaction()),
database::IndexConstraintViolationException);
EXPECT_THROW(constraint_.UpdateOnAddLabel(label_, v, dba->transaction()),
database::IndexConstraintViolationException);
dba->Commit();
EXPECT_THROW(v.PropsSet(property_, value_),
database::IndexConstraintViolationException);
}
}
@ -90,9 +80,7 @@ TEST_F(UniqueLabelPropertyTest, InsertInsertDiffValues) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Commit();
}
{
@ -100,10 +88,7 @@ TEST_F(UniqueLabelPropertyTest, InsertInsertDiffValues) {
auto v = dba->InsertVertex();
PropertyValue other_value{"Some other value"};
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, other_value);
constraint_.UpdateOnAddProperty(property_, other_value, v,
dba->transaction());
dba->Commit();
}
}
@ -113,18 +98,14 @@ TEST_F(UniqueLabelPropertyTest, InsertAbortInsert) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Abort();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Commit();
}
}
@ -135,9 +116,7 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveAbortInsert) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
gid = v.gid();
dba->Commit();
}
@ -145,17 +124,13 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveAbortInsert) {
auto dba = db_.Access();
auto v = dba->FindVertex(gid, false);
v.PropsErase(property_);
constraint_.UpdateOnRemoveProperty(property_, v, dba->transaction());
dba->Abort();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property_, value_, v,
dba->transaction()),
EXPECT_THROW(v.PropsSet(property_, value_),
database::IndexConstraintViolationException);
}
}
@ -165,16 +140,11 @@ TEST_F(UniqueLabelPropertyTest, InsertInsertSameTransaction) {
auto dba = db_.Access();
auto v1 = dba->InsertVertex();
v1.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v1, dba->transaction());
v1.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v1, dba->transaction());
auto v2 = dba->InsertVertex();
v2.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v2, dba->transaction());
v2.PropsSet(property_, value_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property_, value_, v2,
dba->transaction()),
EXPECT_THROW(v2.PropsSet(property_, value_),
database::IndexConstraintViolationException);
}
}
@ -185,17 +155,12 @@ TEST_F(UniqueLabelPropertyTest, InsertInsertReversed) {
auto v2 = dba2->InsertVertex();
v2.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v2, dba2->transaction());
v2.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v2, dba2->transaction());
dba2->Commit();
auto v1 = dba1->InsertVertex();
v1.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v1, dba1->transaction());
v1.PropsSet(property_, value_);
EXPECT_THROW(constraint_.UpdateOnAddProperty(property_, value_, v1,
dba1->transaction()),
EXPECT_THROW(v1.PropsSet(property_, value_),
mvcc::SerializationError);
}
@ -205,9 +170,7 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsert) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
gid = v.gid();
dba->Commit();
}
@ -215,16 +178,13 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsert) {
auto dba = db_.Access();
auto v = dba->FindVertex(gid, false);
v.PropsErase(property_);
constraint_.UpdateOnRemoveProperty(property_, v, dba->transaction());
dba->Commit();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
}
}
@ -232,13 +192,9 @@ TEST_F(UniqueLabelPropertyTest, InsertRemoveInsertSameTransaction) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
v.PropsErase(property_);
constraint_.UpdateOnRemoveProperty(property_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Commit();
}
@ -247,23 +203,19 @@ TEST_F(UniqueLabelPropertyTest, InsertDropInsert) {
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Commit();
}
{
auto dba = db_.AccessBlocking();
constraint_.RemoveConstraint(label_, property_);
auto dba = db_.Access();
dba->DeleteUniqueConstraint(label_, property_);
dba->Commit();
}
{
auto dba = db_.Access();
auto v = dba->InsertVertex();
v.add_label(label_);
constraint_.UpdateOnAddLabel(label_, v, dba->transaction());
v.PropsSet(property_, value_);
constraint_.UpdateOnAddProperty(property_, value_, v, dba->transaction());
dba->Commit();
}
}