diff --git a/src/database/single_node/graph_db_accessor.cpp b/src/database/single_node/graph_db_accessor.cpp index 722ab6a85..52a603d11 100644 --- a/src/database/single_node/graph_db_accessor.cpp +++ b/src/database/single_node/graph_db_accessor.cpp @@ -194,7 +194,7 @@ void GraphDbAccessor::UpdateLabelIndices(storage::Label label, "Node couldn't be updated due to index constraint violation!"); } - if (!db_.storage().existence_constraints_.CheckIfSatisfies(vertex)) { + if (!db_.storage().existence_constraints_.CheckOnAddLabel(vertex, label)) { throw IndexConstraintViolationException( "Node couldn't be updated due to existence constraint violation!"); } @@ -216,7 +216,8 @@ void GraphDbAccessor::UpdatePropertyIndex( void GraphDbAccessor::UpdateOnPropertyRemove(storage::Property property, const Vertex *vertex, const RecordAccessor &accessor) { - if (!db_.storage().existence_constraints_.CheckIfSatisfies(vertex)) { + if (!db_.storage().existence_constraints_.CheckOnRemoveProperty(vertex, + property)) { throw IndexConstraintViolationException( "Node couldn't be updated due to existence constraint violation!"); } @@ -270,7 +271,7 @@ bool GraphDbAccessor::ExistenceConstraintExists( return db_.storage().existence_constraints_.Exists(rule); } -std::list GraphDbAccessor::ExistenceConstraintsList() +std::vector GraphDbAccessor::ExistenceConstraintsList() const { return db_.storage().existence_constraints_.ListConstraints(); } diff --git a/src/database/single_node/graph_db_accessor.hpp b/src/database/single_node/graph_db_accessor.hpp index 614c78580..62f443de3 100644 --- a/src/database/single_node/graph_db_accessor.hpp +++ b/src/database/single_node/graph_db_accessor.hpp @@ -487,7 +487,7 @@ class GraphDbAccessor { /** * Returns the list of existence constraints currently active. */ - std::list ExistenceConstraintsList() const; + std::vector ExistenceConstraintsList() const; /** * Return approximate number of all vertices in the database. diff --git a/src/storage/single_node/constraints/existence_constraints.cpp b/src/storage/single_node/constraints/existence_constraints.cpp index 88d423ff9..8de073663 100644 --- a/src/storage/single_node/constraints/existence_constraints.cpp +++ b/src/storage/single_node/constraints/existence_constraints.cpp @@ -30,7 +30,8 @@ void ExistenceConstraints::AddConstraint(const ExistenceRule &rule) { void ExistenceConstraints::RemoveConstraint(const ExistenceRule &rule) { auto found = std::find(constraints_.begin(), constraints_.end(), rule); if (found != constraints_.end()) { - constraints_.erase(found); + std::swap(*found, constraints_.back()); + constraints_.pop_back(); } } @@ -39,15 +40,29 @@ bool ExistenceConstraints::Exists(const ExistenceRule &rule) const { return found != constraints_.end(); } -bool ExistenceConstraints::CheckIfSatisfies(const Vertex *vertex) const { +bool ExistenceConstraints::CheckOnAddLabel(const Vertex *vertex, + storage::Label label) const { for (auto &constraint : constraints_) { - if (!CheckIfSatisfiesExistenceRule(vertex, constraint)) return false; + if (constraint.label == label && + !CheckIfSatisfiesExistenceRule(vertex, constraint)) { + return false; + } } - return true; } -const std::list &ExistenceConstraints::ListConstraints() const { +bool ExistenceConstraints::CheckOnRemoveProperty( + const Vertex *vertex, storage::Property property) const { + for (auto &constraint : constraints_) { + if (utils::Contains(constraint.properties, property) && + !CheckIfSatisfiesExistenceRule(vertex, constraint)) { + return false; + } + } + return true; +} + +const std::vector &ExistenceConstraints::ListConstraints() const { return constraints_; } } // namespace database diff --git a/src/storage/single_node/constraints/existence_constraints.hpp b/src/storage/single_node/constraints/existence_constraints.hpp index 74f3374d4..87919f02a 100644 --- a/src/storage/single_node/constraints/existence_constraints.hpp +++ b/src/storage/single_node/constraints/existence_constraints.hpp @@ -65,14 +65,19 @@ class ExistenceConstraints { /// Checks whether given constraint is visible. bool Exists(const ExistenceRule &rule) const; - /// Check if given vertex satisfies all visible constraints. - // TODO I could check this faster if I knew exactly what changed - bool CheckIfSatisfies(const Vertex *vertex) const; + /// Check if add label update satisfies all visible constraints. + /// @return true if all constraints are satisfied, false otherwise + bool CheckOnAddLabel(const Vertex *vertex, storage::Label label) const; + + /// Check if remove property update satisfies all visible constraints. + /// @return true if all constraints are satisfied, false otherwise + bool CheckOnRemoveProperty(const Vertex *vertex, + storage::Property property) const; /// Returns list of all constraints. - const std::list &ListConstraints() const; + const std::vector &ListConstraints() const; private: - std::list constraints_; + std::vector constraints_; }; }; // namespace database diff --git a/tests/unit/existence_constraints.cpp b/tests/unit/existence_constraints.cpp index 68d84cb2b..385023815 100644 --- a/tests/unit/existence_constraints.cpp +++ b/tests/unit/existence_constraints.cpp @@ -45,7 +45,7 @@ TEST_F(ExistenceConstraintsTest, InsertTest) { auto dba = db_.Access(); auto v = dba->InsertVertex(); v.add_label(label); - EXPECT_TRUE(constraints_.CheckIfSatisfies(v.GetNew())); + EXPECT_TRUE(constraints_.CheckOnAddLabel(v.GetNew(), label)); dba->Commit(); } { @@ -70,11 +70,11 @@ TEST_F(ExistenceConstraintsTest, InsertTest) { auto v1 = dba->InsertVertex(); v1.add_label(label); EXPECT_FALSE( - constraints_.CheckIfSatisfies(v1.GetNew())); + constraints_.CheckOnAddLabel(v1.GetNew(), label)); auto v2 = dba->InsertVertex(); v2.PropsSet(prop, PropertyValue(false)); v2.add_label(label); - EXPECT_TRUE(constraints_.CheckIfSatisfies(v2.GetNew())); + EXPECT_TRUE(constraints_.CheckOnAddLabel(v2.GetNew(), label)); dba->Commit(); } { @@ -86,7 +86,7 @@ TEST_F(ExistenceConstraintsTest, InsertTest) { auto dba = db_.Access(); auto v = dba->InsertVertex(); v.add_label(label); - EXPECT_TRUE(constraints_.CheckIfSatisfies(v.GetNew())); + EXPECT_TRUE(constraints_.CheckOnAddLabel(v.GetNew(), label)); dba->Commit(); } }