Add most of CRUD
This commit is contained in:
parent
605a425bb3
commit
88f8a0ae68
@ -435,7 +435,7 @@ uint64_t InMemoryReplicationHandlers::ReadAndApplyDelta(storage::InMemoryStorage
|
||||
auto vertex = transaction->FindVertex(delta.vertex_add_remove_label.gid, View::NEW);
|
||||
if (!vertex)
|
||||
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
|
||||
auto ret = vertex->AddLabel(transaction->NameToLabel(delta.vertex_add_remove_label.label));
|
||||
auto ret = vertex->AddLabel(transaction->NameToLabel(delta.vertex_add_remove_label.label), true);
|
||||
if (ret.HasError() || !ret.GetValue())
|
||||
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
|
||||
break;
|
||||
@ -447,7 +447,7 @@ uint64_t InMemoryReplicationHandlers::ReadAndApplyDelta(storage::InMemoryStorage
|
||||
auto vertex = transaction->FindVertex(delta.vertex_add_remove_label.gid, View::NEW);
|
||||
if (!vertex)
|
||||
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
|
||||
auto ret = vertex->RemoveLabel(transaction->NameToLabel(delta.vertex_add_remove_label.label));
|
||||
auto ret = vertex->RemoveLabel(transaction->NameToLabel(delta.vertex_add_remove_label.label), true);
|
||||
if (ret.HasError() || !ret.GetValue())
|
||||
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
|
||||
break;
|
||||
@ -460,7 +460,7 @@ uint64_t InMemoryReplicationHandlers::ReadAndApplyDelta(storage::InMemoryStorage
|
||||
if (!vertex)
|
||||
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
|
||||
auto ret = vertex->SetProperty(transaction->NameToProperty(delta.vertex_edge_set_property.property),
|
||||
delta.vertex_edge_set_property.value);
|
||||
delta.vertex_edge_set_property.value, true);
|
||||
if (ret.HasError())
|
||||
throw utils::BasicException("Invalid transaction! Please raise an issue, {}:{}", __FILE__, __LINE__);
|
||||
break;
|
||||
|
@ -457,28 +457,30 @@ void ProcessNodeRow(memgraph::storage::Storage *store, const std::vector<std::st
|
||||
} else {
|
||||
pv_id = memgraph::storage::PropertyValue(node_id.id);
|
||||
}
|
||||
auto old_node_property = node.SetProperty(acc->NameToProperty(field.name), pv_id);
|
||||
auto old_node_property = node.SetProperty(acc->NameToProperty(field.name), pv_id, false);
|
||||
if (!old_node_property.HasValue()) throw LoadException("Couldn't add property '{}' to the node", field.name);
|
||||
if (!old_node_property->IsNull()) throw LoadException("The property '{}' already exists", field.name);
|
||||
}
|
||||
id = node_id;
|
||||
} else if (field.type == "LABEL") {
|
||||
for (const auto &label : memgraph::utils::Split(value, FLAGS_array_delimiter)) {
|
||||
auto node_label = node.AddLabel(acc->NameToLabel(label));
|
||||
auto node_label = node.AddLabel(acc->NameToLabel(label), false);
|
||||
if (!node_label.HasValue()) throw LoadException("Couldn't add label '{}' to the node", label);
|
||||
if (!*node_label) throw LoadException("The label '{}' already exists", label);
|
||||
}
|
||||
} else if (field.type != "IGNORE") {
|
||||
auto old_node_property = node.SetProperty(acc->NameToProperty(field.name), StringToValue(value, field.type));
|
||||
auto old_node_property =
|
||||
node.SetProperty(acc->NameToProperty(field.name), StringToValue(value, field.type), false);
|
||||
if (!old_node_property.HasValue()) throw LoadException("Couldn't add property '{}' to the node", field.name);
|
||||
if (!old_node_property->IsNull()) throw LoadException("The property '{}' already exists", field.name);
|
||||
}
|
||||
}
|
||||
for (const auto &label : additional_labels) {
|
||||
auto node_label = node.AddLabel(acc->NameToLabel(label));
|
||||
auto node_label = node.AddLabel(acc->NameToLabel(label), false);
|
||||
if (!node_label.HasValue()) throw LoadException("Couldn't add label '{}' to the node", label);
|
||||
if (!*node_label) throw LoadException("The label '{}' already exists", label);
|
||||
}
|
||||
// TODO: refresh text index
|
||||
if (acc->Commit().HasError()) throw LoadException("Couldn't store the node");
|
||||
}
|
||||
|
||||
|
@ -115,9 +115,13 @@ class VertexAccessor final {
|
||||
|
||||
auto Labels(storage::View view) const { return impl_.Labels(view); }
|
||||
|
||||
storage::Result<bool> AddLabel(storage::LabelId label) { return impl_.AddLabel(label); }
|
||||
storage::Result<bool> AddLabel(storage::LabelId label, bool update_text_index) {
|
||||
return impl_.AddLabel(label, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveLabel(storage::LabelId label) { return impl_.RemoveLabel(label); }
|
||||
storage::Result<bool> RemoveLabel(storage::LabelId label, bool update_text_index) {
|
||||
return impl_.RemoveLabel(label, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<bool> HasLabel(storage::View view, storage::LabelId label) const {
|
||||
return impl_.HasLabel(label, view);
|
||||
@ -129,25 +133,29 @@ class VertexAccessor final {
|
||||
return impl_.GetProperty(key, view);
|
||||
}
|
||||
|
||||
storage::Result<storage::PropertyValue> SetProperty(storage::PropertyId key, const storage::PropertyValue &value) {
|
||||
return impl_.SetProperty(key, value);
|
||||
storage::Result<storage::PropertyValue> SetProperty(storage::PropertyId key, const storage::PropertyValue &value,
|
||||
bool update_text_index = false) {
|
||||
return impl_.SetProperty(key, value, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||
return impl_.InitProperties(properties);
|
||||
storage::Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties,
|
||||
bool update_text_index = false) {
|
||||
return impl_.InitProperties(properties, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<std::vector<std::tuple<storage::PropertyId, storage::PropertyValue, storage::PropertyValue>>>
|
||||
UpdateProperties(std::map<storage::PropertyId, storage::PropertyValue> &properties) const {
|
||||
return impl_.UpdateProperties(properties);
|
||||
UpdateProperties(std::map<storage::PropertyId, storage::PropertyValue> &properties,
|
||||
bool update_text_index = false) const {
|
||||
return impl_.UpdateProperties(properties, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<storage::PropertyValue> RemoveProperty(storage::PropertyId key) {
|
||||
return SetProperty(key, storage::PropertyValue());
|
||||
storage::Result<storage::PropertyValue> RemoveProperty(storage::PropertyId key, bool update_text_index = true) {
|
||||
return SetProperty(key, storage::PropertyValue(), update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<std::map<storage::PropertyId, storage::PropertyValue>> ClearProperties() {
|
||||
return impl_.ClearProperties();
|
||||
storage::Result<std::map<storage::PropertyId, storage::PropertyValue>> ClearProperties(
|
||||
bool update_text_index = false) {
|
||||
return impl_.ClearProperties(update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<EdgeVertexAccessorResult> InEdges(storage::View view,
|
||||
@ -254,9 +262,13 @@ class SubgraphVertexAccessor final {
|
||||
|
||||
auto Labels(storage::View view) const { return impl_.Labels(view); }
|
||||
|
||||
storage::Result<bool> AddLabel(storage::LabelId label) { return impl_.AddLabel(label); }
|
||||
storage::Result<bool> AddLabel(storage::LabelId label, bool update_text_index) {
|
||||
return impl_.AddLabel(label, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveLabel(storage::LabelId label) { return impl_.RemoveLabel(label); }
|
||||
storage::Result<bool> RemoveLabel(storage::LabelId label, bool update_text_index) {
|
||||
return impl_.RemoveLabel(label, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<bool> HasLabel(storage::View view, storage::LabelId label) const {
|
||||
return impl_.HasLabel(view, label);
|
||||
@ -274,13 +286,15 @@ class SubgraphVertexAccessor final {
|
||||
|
||||
storage::Result<size_t> OutDegree(storage::View view) const { return impl_.OutDegree(view); }
|
||||
|
||||
storage::Result<storage::PropertyValue> SetProperty(storage::PropertyId key, const storage::PropertyValue &value) {
|
||||
return impl_.SetProperty(key, value);
|
||||
storage::Result<storage::PropertyValue> SetProperty(storage::PropertyId key, const storage::PropertyValue &value,
|
||||
bool update_text_index = false) {
|
||||
return impl_.SetProperty(key, value, update_text_index);
|
||||
}
|
||||
|
||||
storage::Result<std::vector<std::tuple<storage::PropertyId, storage::PropertyValue, storage::PropertyValue>>>
|
||||
UpdateProperties(std::map<storage::PropertyId, storage::PropertyValue> &properties) const {
|
||||
return impl_.UpdateProperties(properties);
|
||||
UpdateProperties(std::map<storage::PropertyId, storage::PropertyValue> &properties,
|
||||
bool update_text_index = false) const {
|
||||
return impl_.UpdateProperties(properties, update_text_index);
|
||||
}
|
||||
|
||||
VertexAccessor GetVertexAccessor() const;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Memgraph Ltd.
|
||||
// Copyright 2024 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@ -217,7 +217,7 @@ VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info, Frame *fram
|
||||
auto new_node = dba.InsertVertex();
|
||||
context.execution_stats[ExecutionStats::Key::CREATED_NODES] += 1;
|
||||
for (auto label : node_info.labels) {
|
||||
auto maybe_error = new_node.AddLabel(label);
|
||||
auto maybe_error = new_node.AddLabel(label, false);
|
||||
if (maybe_error.HasError()) {
|
||||
switch (maybe_error.GetError()) {
|
||||
case storage::Error::SERIALIZATION_ERROR:
|
||||
@ -251,6 +251,11 @@ VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info, Frame *fram
|
||||
}
|
||||
MultiPropsInitChecked(&new_node, properties);
|
||||
|
||||
// TODO antepusic check if text search is turned on
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
// new_node.AddToTextSearch()
|
||||
}
|
||||
|
||||
(*frame)[node_info.symbol] = new_node;
|
||||
return (*frame)[node_info.symbol].ValueVertex();
|
||||
}
|
||||
@ -2819,6 +2824,10 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
||||
context.trigger_context_collector->RegisterSetObjectProperty(lhs.ValueVertex(), self_.property_,
|
||||
TypedValue{std::move(old_value)}, TypedValue{rhs});
|
||||
}
|
||||
// TODO antepusic: update text index
|
||||
// new_node.UpdateInTextSearch()
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypedValue::Type::Edge: {
|
||||
@ -2975,6 +2984,10 @@ void SetPropertiesOnRecord(TRecordAccessor *record, const TypedValue &rhs, SetPr
|
||||
case TypedValue::Type::Vertex: {
|
||||
PropertiesMap new_properties = get_props(rhs.ValueVertex());
|
||||
update_props(new_properties);
|
||||
// TODO antepusic: update text index
|
||||
// new_node.UpdateInTextSearch()
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypedValue::Type::Map: {
|
||||
@ -3102,7 +3115,7 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
#endif
|
||||
|
||||
for (auto label : self_.labels_) {
|
||||
auto maybe_value = vertex.AddLabel(label);
|
||||
auto maybe_value = vertex.AddLabel(label, false);
|
||||
if (maybe_value.HasError()) {
|
||||
switch (maybe_value.GetError()) {
|
||||
case storage::Error::SERIALIZATION_ERROR:
|
||||
@ -3121,6 +3134,11 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO antepusic check if text search is turned on
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
// new_node.UpdateInTextSearch()
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3262,7 +3280,7 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont
|
||||
#endif
|
||||
|
||||
for (auto label : self_.labels_) {
|
||||
auto maybe_value = vertex.RemoveLabel(label);
|
||||
auto maybe_value = vertex.RemoveLabel(label, false);
|
||||
if (maybe_value.HasError()) {
|
||||
switch (maybe_value.GetError()) {
|
||||
case storage::Error::SERIALIZATION_ERROR:
|
||||
@ -3282,6 +3300,11 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont
|
||||
}
|
||||
}
|
||||
|
||||
// TODO antepusic check if text search is turned on
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
// new_node.UpdateInTextSearch()
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1838,9 +1838,10 @@ mgp_error mgp_vertex_set_property(struct mgp_vertex *v, const char *property_nam
|
||||
const auto prop_key =
|
||||
std::visit([property_name](auto *impl) { return impl->NameToProperty(property_name); }, v->graph->impl);
|
||||
|
||||
const auto result = std::visit(
|
||||
[prop_key, property_value](auto &impl) { return impl.SetProperty(prop_key, ToPropertyValue(*property_value)); },
|
||||
v->impl);
|
||||
const auto result =
|
||||
std::visit([prop_key, property_value](
|
||||
auto &impl) { return impl.SetProperty(prop_key, ToPropertyValue(*property_value), true); },
|
||||
v->impl);
|
||||
if (result.HasError()) {
|
||||
switch (result.GetError()) {
|
||||
case memgraph::storage::Error::DELETED_OBJECT:
|
||||
@ -1896,7 +1897,7 @@ mgp_error mgp_vertex_set_properties(struct mgp_vertex *v, struct mgp_map *proper
|
||||
v->graph->impl));
|
||||
}
|
||||
|
||||
const auto result = v->getImpl().UpdateProperties(props);
|
||||
const auto result = v->getImpl().UpdateProperties(props, true);
|
||||
if (result.HasError()) {
|
||||
switch (result.GetError()) {
|
||||
case memgraph::storage::Error::DELETED_OBJECT:
|
||||
@ -1953,7 +1954,7 @@ mgp_error mgp_vertex_add_label(struct mgp_vertex *v, mgp_label label) {
|
||||
throw ImmutableObjectException{"Cannot add a label to an immutable vertex!"};
|
||||
}
|
||||
|
||||
const auto result = std::visit([label_id](auto &impl) { return impl.AddLabel(label_id); }, v->impl);
|
||||
const auto result = std::visit([label_id](auto &impl) { return impl.AddLabel(label_id, true); }, v->impl);
|
||||
|
||||
if (result.HasError()) {
|
||||
switch (result.GetError()) {
|
||||
@ -1995,7 +1996,7 @@ mgp_error mgp_vertex_remove_label(struct mgp_vertex *v, mgp_label label) {
|
||||
if (!MgpVertexIsMutable(*v)) {
|
||||
throw ImmutableObjectException{"Cannot remove a label from an immutable vertex!"};
|
||||
}
|
||||
const auto result = std::visit([label_id](auto &impl) { return impl.RemoveLabel(label_id); }, v->impl);
|
||||
const auto result = std::visit([label_id](auto &impl) { return impl.RemoveLabel(label_id, true); }, v->impl);
|
||||
|
||||
if (result.HasError()) {
|
||||
switch (result.GetError()) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Memgraph Ltd.
|
||||
// Copyright 2024 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@ -799,6 +799,7 @@ RecoveredSnapshot LoadSnapshotVersion14(const std::filesystem::path &path, utils
|
||||
SPDLOG_TRACE("Recovered property \"{}\" with value \"{}\" for vertex {}.",
|
||||
name_id_mapper->IdToName(snapshot_id_map.at(*key)), *value, *gid);
|
||||
props.SetProperty(get_property_from_id(*key), *value);
|
||||
// TODO antepusic: update text index here or at the end of LoadSnapshot()?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Memgraph Ltd.
|
||||
// Copyright 2024 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@ -788,6 +788,7 @@ RecoveryInfo LoadWal(const std::filesystem::path &path, RecoveredIndicesAndConst
|
||||
auto &property_value = delta.vertex_edge_set_property.value;
|
||||
|
||||
vertex->properties.SetProperty(property_id, property_value);
|
||||
// TODO antepusic: update text index here or at the end of LoadWal()?
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -38,22 +38,44 @@ void Indices::RemoveObsoleteEntries(uint64_t oldest_active_start_timestamp) cons
|
||||
->RemoveObsoleteEntries(oldest_active_start_timestamp);
|
||||
}
|
||||
|
||||
void Indices::UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx) const {
|
||||
// void Indices::UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx) const {
|
||||
// label_index_->UpdateOnAddLabel(label, vertex, tx);
|
||||
// label_property_index_->UpdateOnAddLabel(label, vertex, tx);
|
||||
// }
|
||||
|
||||
// void Indices::UpdateOnRemoveLabel(LabelId label, Vertex *vertex, const Transaction &tx) const {
|
||||
// label_index_->UpdateOnRemoveLabel(label, vertex, tx);
|
||||
// label_property_index_->UpdateOnRemoveLabel(label, vertex, tx);
|
||||
// }
|
||||
|
||||
// void Indices::UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex,
|
||||
// const Transaction &tx) const {
|
||||
// label_property_index_->UpdateOnSetProperty(property, value, vertex, tx);
|
||||
// }
|
||||
|
||||
void Indices::UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx, Storage *storage,
|
||||
bool update_text_index) const {
|
||||
label_index_->UpdateOnAddLabel(label, vertex, tx);
|
||||
label_property_index_->UpdateOnAddLabel(label, vertex, tx);
|
||||
text_index_->UpdateOnAddLabel(label, vertex, tx);
|
||||
if (update_text_index) {
|
||||
text_index_->UpdateOnAddLabel(label, vertex, storage, tx);
|
||||
}
|
||||
}
|
||||
|
||||
void Indices::UpdateOnRemoveLabel(LabelId label, Vertex *vertex, const Transaction &tx) const {
|
||||
void Indices::UpdateOnRemoveLabel(LabelId label, Vertex *vertex, const Transaction &tx, bool update_text_index) const {
|
||||
label_index_->UpdateOnRemoveLabel(label, vertex, tx);
|
||||
label_property_index_->UpdateOnRemoveLabel(label, vertex, tx);
|
||||
text_index_->UpdateOnRemoveLabel(label, vertex, tx);
|
||||
if (update_text_index) {
|
||||
text_index_->UpdateOnRemoveLabel(label, vertex, tx);
|
||||
}
|
||||
}
|
||||
|
||||
void Indices::UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex,
|
||||
const Transaction &tx) const {
|
||||
const Transaction &tx, Storage *storage, bool update_text_index) const {
|
||||
label_property_index_->UpdateOnSetProperty(property, value, vertex, tx);
|
||||
text_index_->UpdateOnSetProperty(property, value, vertex, tx);
|
||||
if (update_text_index) {
|
||||
text_index_->UpdateOnSetProperty(vertex, storage, tx);
|
||||
}
|
||||
}
|
||||
|
||||
Indices::Indices(const Config &config, StorageMode storage_mode) {
|
||||
|
@ -56,14 +56,19 @@ struct Indices {
|
||||
|
||||
/// This function should be called whenever a label is added to a vertex.
|
||||
/// @throw std::bad_alloc
|
||||
void UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx) const;
|
||||
// void UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx) const;
|
||||
void UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx, Storage *storage,
|
||||
bool update_text_index) const;
|
||||
|
||||
void UpdateOnRemoveLabel(LabelId label, Vertex *vertex, const Transaction &tx) const;
|
||||
// void UpdateOnRemoveLabel(LabelId label, Vertex *vertex, const Transaction &tx) const;
|
||||
void UpdateOnRemoveLabel(LabelId label, Vertex *vertex, const Transaction &tx, bool update_text_index) const;
|
||||
|
||||
/// This function should be called whenever a property is modified on a vertex.
|
||||
/// @throw std::bad_alloc
|
||||
void UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex,
|
||||
const Transaction &tx) const;
|
||||
// void UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex,
|
||||
// const Transaction &tx) const;
|
||||
void UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex, const Transaction &tx,
|
||||
Storage *storage, bool update_text_index) const;
|
||||
|
||||
std::unique_ptr<LabelIndex> label_index_;
|
||||
std::unique_ptr<LabelPropertyIndex> label_property_index_;
|
||||
|
@ -17,17 +17,75 @@
|
||||
|
||||
namespace memgraph::storage {
|
||||
|
||||
void TextIndex::UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_update, const Transaction &tx) const {
|
||||
// Add node to this label's text index
|
||||
void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage,
|
||||
const std::vector<memcxx::text_search::Context *> &applicable_text_indices) {
|
||||
// NOTE: Text indexes are presently all-property indices. If we allow text indexes restricted to specific properties,
|
||||
// an indexable document should be created for each applicable index.
|
||||
nlohmann::json document = {};
|
||||
nlohmann::json properties = {};
|
||||
for (const auto &[prop_id, prop_value] : vertex_after_update->properties.Properties()) {
|
||||
if (!prop_value.IsString()) continue;
|
||||
properties[storage->PropertyToName(prop_id)] = prop_value.ValueString();
|
||||
}
|
||||
|
||||
document["data"] = properties;
|
||||
document["metadata"] = {};
|
||||
document["metadata"]["gid"] = vertex_after_update->gid.AsInt();
|
||||
// TODO add txid
|
||||
document["metadata"]["deleted"] = false;
|
||||
document["metadata"]["is_node"] = true;
|
||||
|
||||
for (auto *index_context : applicable_text_indices) {
|
||||
memcxx::text_search::add(*index_context, memcxx::text_search::DocumentInput{.data = document.dump()}, false);
|
||||
}
|
||||
}
|
||||
|
||||
void TextIndex::UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update, const Transaction &tx) const {
|
||||
// Remove node from this label's text index
|
||||
void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage) {
|
||||
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
||||
if (applicable_text_indices.empty()) return;
|
||||
AddNode(vertex_after_update, storage, applicable_text_indices);
|
||||
}
|
||||
|
||||
void TextIndex::UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex,
|
||||
const Transaction &tx) const {
|
||||
// Delete this node's document and re-add the it with the new value
|
||||
void TextIndex::UpdateNode(Vertex *vertex_after_update, Storage *storage) {
|
||||
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
||||
if (applicable_text_indices.empty()) return;
|
||||
RemoveNode(vertex_after_update, applicable_text_indices);
|
||||
AddNode(vertex_after_update, storage, applicable_text_indices);
|
||||
}
|
||||
|
||||
void TextIndex::RemoveNode(Vertex *vertex_after_update,
|
||||
const std::vector<memcxx::text_search::Context *> &applicable_text_indices) {
|
||||
auto search_node_to_be_deleted = memcxx::text_search::SearchInput{
|
||||
.search_query = fmt::format("metadata.gid:{}", vertex_after_update->gid.AsInt())};
|
||||
|
||||
for (auto *index_context : applicable_text_indices) {
|
||||
memcxx::text_search::delete_document(*index_context, search_node_to_be_deleted, false);
|
||||
}
|
||||
}
|
||||
|
||||
void TextIndex::RemoveNode(Vertex *vertex_after_update) {
|
||||
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
||||
if (applicable_text_indices.empty()) return;
|
||||
RemoveNode(vertex_after_update, applicable_text_indices);
|
||||
}
|
||||
|
||||
void TextIndex::UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_update, Storage *storage,
|
||||
const Transaction &tx) {
|
||||
if (!label_to_index_.contains(added_label)) {
|
||||
return;
|
||||
}
|
||||
AddNode(vertex_after_update, storage, {&index_.at(label_to_index_.at(added_label))});
|
||||
}
|
||||
|
||||
void TextIndex::UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update, const Transaction &tx) {
|
||||
if (!label_to_index_.contains(removed_label)) {
|
||||
return;
|
||||
}
|
||||
RemoveNode(vertex_after_update, {&index_.at(label_to_index_.at(removed_label))});
|
||||
}
|
||||
|
||||
void TextIndex::UpdateOnSetProperty(Vertex *vertex_after_update, Storage *storage, const Transaction &tx) {
|
||||
UpdateNode(vertex_after_update, storage);
|
||||
}
|
||||
|
||||
std::vector<memcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(Vertex *vertex) {
|
||||
|
@ -22,8 +22,15 @@ class DbAccessor;
|
||||
}
|
||||
|
||||
namespace memgraph::storage {
|
||||
class Storage;
|
||||
|
||||
class TextIndex {
|
||||
private:
|
||||
void AddNode(Vertex *vertex, Storage *storage,
|
||||
const std::vector<memcxx::text_search::Context *> &applicable_text_indices);
|
||||
|
||||
void RemoveNode(Vertex *vertex, const std::vector<memcxx::text_search::Context *> &applicable_text_indices);
|
||||
|
||||
public:
|
||||
TextIndex() = default;
|
||||
|
||||
@ -37,12 +44,17 @@ class TextIndex {
|
||||
std::map<std::string, memcxx::text_search::Context> index_;
|
||||
std::map<LabelId, std::string> label_to_index_;
|
||||
|
||||
void UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_update, const Transaction &tx) const;
|
||||
void AddNode(Vertex *vertex, Storage *storage);
|
||||
|
||||
void UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update, const Transaction &tx) const;
|
||||
void UpdateNode(Vertex *vertex, Storage *storage);
|
||||
|
||||
void UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex,
|
||||
const Transaction &tx) const;
|
||||
void RemoveNode(Vertex *vertex);
|
||||
|
||||
void UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_update, Storage *storage, const Transaction &tx);
|
||||
|
||||
void UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update, const Transaction &tx);
|
||||
|
||||
void UpdateOnSetProperty(Vertex *vertex_after_update, Storage *storage, const Transaction &tx);
|
||||
|
||||
std::vector<memcxx::text_search::Context *> GetApplicableTextIndices(Vertex *vertex);
|
||||
|
||||
|
@ -974,6 +974,7 @@ void InMemoryStorage::InMemoryAccessor::Abort() {
|
||||
}
|
||||
// Setting the correct value
|
||||
vertex->properties.SetProperty(current->property.key, current->property.value);
|
||||
// TODO antepusic: update text index here or at the end of Abort()?
|
||||
break;
|
||||
}
|
||||
case Delta::Action::ADD_IN_EDGE: {
|
||||
|
@ -152,6 +152,8 @@ Result<std::optional<VertexAccessor>> Storage::Accessor::DeleteVertex(VertexAcce
|
||||
return std::optional<VertexAccessor>{};
|
||||
}
|
||||
|
||||
// TODO antepusic remove from text index
|
||||
|
||||
const auto &[vertices, edges] = *value;
|
||||
|
||||
MG_ASSERT(vertices.size() <= 1, "The number of deleted vertices is not less or equal to 1!");
|
||||
@ -184,6 +186,8 @@ Result<std::optional<std::pair<VertexAccessor, std::vector<EdgeAccessor>>>> Stor
|
||||
return res.GetError();
|
||||
}
|
||||
|
||||
// TODO antepusic remove from text index
|
||||
|
||||
auto &value = res.GetValue();
|
||||
if (!value) {
|
||||
return std::optional<ReturnType>{};
|
||||
@ -274,6 +278,8 @@ Storage::Accessor::DetachDelete(std::vector<VertexAccessor *> nodes, std::vector
|
||||
|
||||
auto deleted_vertices = maybe_deleted_vertices.GetValue();
|
||||
|
||||
// delete from text inde here
|
||||
|
||||
return std::make_optional<ReturnType>(std::move(deleted_vertices), std::move(deleted_edges));
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ bool VertexAccessor::IsVisible(View view) const {
|
||||
return exists && (for_deleted_ || !deleted);
|
||||
}
|
||||
|
||||
Result<bool> VertexAccessor::AddLabel(LabelId label) {
|
||||
Result<bool> VertexAccessor::AddLabel(LabelId label, bool update_text_index) {
|
||||
if (transaction_->edge_import_mode_active) {
|
||||
throw query::WriteVertexOperationInEdgeImportModeException();
|
||||
}
|
||||
@ -126,14 +126,14 @@ Result<bool> VertexAccessor::AddLabel(LabelId label) {
|
||||
/// TODO: some by pointers, some by reference => not good, make it better
|
||||
storage_->constraints_.unique_constraints_->UpdateOnAddLabel(label, *vertex_, transaction_->start_timestamp);
|
||||
transaction_->constraint_verification_info.AddedLabel(vertex_);
|
||||
storage_->indices_.UpdateOnAddLabel(label, vertex_, *transaction_);
|
||||
storage_->indices_.UpdateOnAddLabel(label, vertex_, *transaction_, storage_, update_text_index);
|
||||
transaction_->manyDeltasCache.Invalidate(vertex_, label);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// TODO: move to after update and change naming to vertex after update
|
||||
Result<bool> VertexAccessor::RemoveLabel(LabelId label) {
|
||||
Result<bool> VertexAccessor::RemoveLabel(LabelId label, bool update_text_index) {
|
||||
if (transaction_->edge_import_mode_active) {
|
||||
throw query::WriteVertexOperationInEdgeImportModeException();
|
||||
}
|
||||
@ -154,7 +154,7 @@ Result<bool> VertexAccessor::RemoveLabel(LabelId label) {
|
||||
|
||||
/// TODO: some by pointers, some by reference => not good, make it better
|
||||
storage_->constraints_.unique_constraints_->UpdateOnRemoveLabel(label, *vertex_, transaction_->start_timestamp);
|
||||
storage_->indices_.UpdateOnRemoveLabel(label, vertex_, *transaction_);
|
||||
storage_->indices_.UpdateOnRemoveLabel(label, vertex_, *transaction_, update_text_index);
|
||||
transaction_->manyDeltasCache.Invalidate(vertex_, label);
|
||||
|
||||
return true;
|
||||
@ -254,7 +254,8 @@ Result<std::vector<LabelId>> VertexAccessor::Labels(View view) const {
|
||||
return std::move(labels);
|
||||
}
|
||||
|
||||
Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const PropertyValue &value) {
|
||||
Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const PropertyValue &value,
|
||||
bool update_text_index) {
|
||||
if (transaction_->edge_import_mode_active) {
|
||||
throw query::WriteVertexOperationInEdgeImportModeException();
|
||||
}
|
||||
@ -275,21 +276,8 @@ Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const Pro
|
||||
// transactions get a SERIALIZATION_ERROR.
|
||||
|
||||
utils::AtomicMemoryBlock atomic_memory_block{
|
||||
[transaction = transaction_, storage = storage_, vertex = vertex_, &value, &property, ¤t_value]() {
|
||||
[transaction = transaction_, vertex = vertex_, &value, &property, ¤t_value]() {
|
||||
CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, current_value);
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
for (auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex)) {
|
||||
auto search_input = memcxx::text_search::SearchInput{
|
||||
.search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt()), .return_fields = {"data"}};
|
||||
|
||||
auto search_result = memcxx::text_search::search(*index_context, search_input);
|
||||
memcxx::text_search::delete_document(*index_context, search_input, true);
|
||||
auto new_properties = search_result.docs[0].data; // TODO (pending real Tantivy results): parse result to
|
||||
// JSON, set property and convert back to string
|
||||
auto new_properties_document = memcxx::text_search::DocumentInput{.data = new_properties};
|
||||
memcxx::text_search::add(*index_context, new_properties_document, true);
|
||||
}
|
||||
}
|
||||
vertex->properties.SetProperty(property, value);
|
||||
}};
|
||||
std::invoke(atomic_memory_block);
|
||||
@ -299,13 +287,28 @@ Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const Pro
|
||||
} else {
|
||||
transaction_->constraint_verification_info.RemovedProperty(vertex_);
|
||||
}
|
||||
storage_->indices_.UpdateOnSetProperty(property, value, vertex_, *transaction_);
|
||||
storage_->indices_.UpdateOnSetProperty(property, value, vertex_, *transaction_, storage_, update_text_index);
|
||||
transaction_->manyDeltasCache.Invalidate(vertex_, property);
|
||||
|
||||
// if (flags::run_time::GetTextSearchEnabled() && update_text_index) {
|
||||
// for (auto *index_context : storage_->indices_.text_index_->GetApplicableTextIndices(vertex_)) {
|
||||
// auto search_input = memcxx::text_search::SearchInput{
|
||||
// .search_query = fmt::format("metadata.gid:{}", vertex_->gid.AsInt()), .return_fields = {"data"}};
|
||||
|
||||
// auto search_result = memcxx::text_search::search(*index_context, search_input);
|
||||
// memcxx::text_search::delete_document(*index_context, search_input, true);
|
||||
// auto new_properties = search_result.docs[0].data; // TODO (pending real Tantivy results): parse result to
|
||||
// // JSON, set property and convert back to string
|
||||
// auto new_properties_document = memcxx::text_search::DocumentInput{.data = new_properties};
|
||||
// memcxx::text_search::add(*index_context, new_properties_document, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
return std::move(current_value);
|
||||
}
|
||||
|
||||
Result<bool> VertexAccessor::InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||
Result<bool> VertexAccessor::InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties,
|
||||
bool update_text_index) {
|
||||
if (transaction_->edge_import_mode_active) {
|
||||
throw query::WriteVertexOperationInEdgeImportModeException();
|
||||
}
|
||||
@ -318,22 +321,14 @@ Result<bool> VertexAccessor::InitProperties(const std::map<storage::PropertyId,
|
||||
if (vertex_->deleted) return Error::DELETED_OBJECT;
|
||||
bool result{false};
|
||||
utils::AtomicMemoryBlock atomic_memory_block{
|
||||
[&result, &properties, storage = storage_, transaction = transaction_, vertex = vertex_]() {
|
||||
[&result, &properties, storage = storage_, transaction = transaction_, vertex = vertex_, update_text_index]() {
|
||||
if (!vertex->properties.InitProperties(properties)) {
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
for (auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex)) {
|
||||
auto new_properties_document =
|
||||
memcxx::text_search::DocumentInput{}; // TODO (pending real Tantivy operation): create a JSON, set
|
||||
// properties and convert to string
|
||||
memcxx::text_search::add(*index_context, new_properties_document, true);
|
||||
}
|
||||
}
|
||||
for (const auto &[property, value] : properties) {
|
||||
CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, PropertyValue());
|
||||
storage->indices_.UpdateOnSetProperty(property, value, vertex, *transaction);
|
||||
storage->indices_.UpdateOnSetProperty(property, value, vertex, *transaction, storage, update_text_index);
|
||||
transaction->manyDeltasCache.Invalidate(vertex, property);
|
||||
if (!value.IsNull()) {
|
||||
transaction->constraint_verification_info.AddedProperty(vertex);
|
||||
@ -345,11 +340,20 @@ Result<bool> VertexAccessor::InitProperties(const std::map<storage::PropertyId,
|
||||
}};
|
||||
std::invoke(atomic_memory_block);
|
||||
|
||||
// if (flags::run_time::GetTextSearchEnabled() && update_text_index) {
|
||||
// for (auto *index_context : storage_->indices_.text_index_->GetApplicableTextIndices(vertex_)) {
|
||||
// auto new_properties_document =
|
||||
// memcxx::text_search::DocumentInput{}; // TODO (pending real Tantivy operation): create a JSON, set
|
||||
// // properties and convert to string
|
||||
// memcxx::text_search::add(*index_context, new_properties_document, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<std::vector<std::tuple<PropertyId, PropertyValue, PropertyValue>>> VertexAccessor::UpdateProperties(
|
||||
std::map<storage::PropertyId, storage::PropertyValue> &properties) const {
|
||||
std::map<storage::PropertyId, storage::PropertyValue> &properties, bool update_text_index) const {
|
||||
if (transaction_->edge_import_mode_active) {
|
||||
throw query::WriteVertexOperationInEdgeImportModeException();
|
||||
}
|
||||
@ -363,43 +367,43 @@ Result<std::vector<std::tuple<PropertyId, PropertyValue, PropertyValue>>> Vertex
|
||||
|
||||
using ReturnType = decltype(vertex_->properties.UpdateProperties(properties));
|
||||
std::optional<ReturnType> id_old_new_change;
|
||||
utils::AtomicMemoryBlock atomic_memory_block{
|
||||
[storage = storage_, transaction = transaction_, vertex = vertex_, &properties, &id_old_new_change]() {
|
||||
id_old_new_change.emplace(vertex->properties.UpdateProperties(properties));
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
for (auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex)) {
|
||||
auto search_input = memcxx::text_search::SearchInput{
|
||||
.search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt()), .return_fields = {"data"}};
|
||||
utils::AtomicMemoryBlock atomic_memory_block{[storage = storage_, transaction = transaction_, vertex = vertex_,
|
||||
&properties, &id_old_new_change, update_text_index]() {
|
||||
id_old_new_change.emplace(vertex->properties.UpdateProperties(properties));
|
||||
// if (flags::run_time::GetTextSearchEnabled()) {
|
||||
// for (auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex)) {
|
||||
// auto search_input = memcxx::text_search::SearchInput{
|
||||
// .search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt()), .return_fields = {"data"}};
|
||||
|
||||
auto search_result = memcxx::text_search::search(*index_context, search_input);
|
||||
memcxx::text_search::delete_document(*index_context, search_input, true);
|
||||
auto new_properties = search_result.docs[0].data; // TODO (pending real Tantivy results): parse result to
|
||||
// JSON, set property and convert back to string
|
||||
auto new_properties_document = memcxx::text_search::DocumentInput{.data = new_properties};
|
||||
memcxx::text_search::add(*index_context, new_properties_document, true);
|
||||
}
|
||||
}
|
||||
// auto search_result = memcxx::text_search::search(*index_context, search_input);
|
||||
// memcxx::text_search::delete_document(*index_context, search_input, true);
|
||||
// auto new_properties = search_result.docs[0].data; // TODO (pending real Tantivy results): parse result to
|
||||
// // JSON, set property and convert back to string
|
||||
// auto new_properties_document = memcxx::text_search::DocumentInput{.data = new_properties};
|
||||
// memcxx::text_search::add(*index_context, new_properties_document, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!id_old_new_change.has_value()) {
|
||||
return;
|
||||
}
|
||||
for (auto &[id, old_value, new_value] : *id_old_new_change) {
|
||||
storage->indices_.UpdateOnSetProperty(id, new_value, vertex, *transaction);
|
||||
CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), id, std::move(old_value));
|
||||
transaction->manyDeltasCache.Invalidate(vertex, id);
|
||||
if (!new_value.IsNull()) {
|
||||
transaction->constraint_verification_info.AddedProperty(vertex);
|
||||
} else {
|
||||
transaction->constraint_verification_info.RemovedProperty(vertex);
|
||||
}
|
||||
}
|
||||
}};
|
||||
if (!id_old_new_change.has_value()) {
|
||||
return;
|
||||
}
|
||||
for (auto &[id, old_value, new_value] : *id_old_new_change) {
|
||||
storage->indices_.UpdateOnSetProperty(id, new_value, vertex, *transaction, storage, update_text_index);
|
||||
CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), id, std::move(old_value));
|
||||
transaction->manyDeltasCache.Invalidate(vertex, id);
|
||||
if (!new_value.IsNull()) {
|
||||
transaction->constraint_verification_info.AddedProperty(vertex);
|
||||
} else {
|
||||
transaction->constraint_verification_info.RemovedProperty(vertex);
|
||||
}
|
||||
}
|
||||
}};
|
||||
std::invoke(atomic_memory_block);
|
||||
|
||||
return id_old_new_change.has_value() ? std::move(id_old_new_change.value()) : ReturnType{};
|
||||
}
|
||||
|
||||
Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties() {
|
||||
Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties(bool update_text_index) {
|
||||
if (transaction_->edge_import_mode_active) {
|
||||
throw query::WriteVertexOperationInEdgeImportModeException();
|
||||
}
|
||||
@ -412,26 +416,28 @@ Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties() {
|
||||
using ReturnType = decltype(vertex_->properties.Properties());
|
||||
std::optional<ReturnType> properties;
|
||||
utils::AtomicMemoryBlock atomic_memory_block{
|
||||
[storage = storage_, transaction = transaction_, vertex = vertex_, &properties]() {
|
||||
[storage = storage_, transaction = transaction_, vertex = vertex_, &properties, update_text_index]() {
|
||||
properties.emplace(vertex->properties.Properties());
|
||||
if (!properties.has_value()) {
|
||||
return;
|
||||
}
|
||||
for (const auto &[property, value] : *properties) {
|
||||
CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, value);
|
||||
storage->indices_.UpdateOnSetProperty(property, PropertyValue(), vertex, *transaction);
|
||||
storage->indices_.UpdateOnSetProperty(property, PropertyValue(), vertex, *transaction, storage,
|
||||
update_text_index);
|
||||
transaction->constraint_verification_info.RemovedProperty(vertex);
|
||||
transaction->manyDeltasCache.Invalidate(vertex, property);
|
||||
}
|
||||
|
||||
vertex->properties.ClearProperties();
|
||||
if (flags::run_time::GetTextSearchEnabled()) {
|
||||
for (auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex)) {
|
||||
auto search_input =
|
||||
memcxx::text_search::SearchInput{.search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt())};
|
||||
memcxx::text_search::delete_document(*index_context, search_input, true);
|
||||
}
|
||||
}
|
||||
// if (flags::run_time::GetTextSearchEnabled()) {
|
||||
// for (auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex)) {
|
||||
// auto search_input =
|
||||
// memcxx::text_search::SearchInput{.search_query = fmt::format("metadata.gid:{}",
|
||||
// vertex->gid.AsInt())};
|
||||
// memcxx::text_search::delete_document(*index_context, search_input, true);
|
||||
// }
|
||||
// }
|
||||
}};
|
||||
std::invoke(atomic_memory_block);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Memgraph Ltd.
|
||||
// Copyright 2024 Memgraph Ltd.
|
||||
//
|
||||
// Use of this software is governed by the Business Source License
|
||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||
@ -47,12 +47,12 @@ class VertexAccessor final {
|
||||
/// Add a label and return `true` if insertion took place.
|
||||
/// `false` is returned if the label already existed.
|
||||
/// @throw std::bad_alloc
|
||||
Result<bool> AddLabel(LabelId label);
|
||||
Result<bool> AddLabel(LabelId label, bool update_text_index);
|
||||
|
||||
/// Remove a label and return `true` if deletion took place.
|
||||
/// `false` is returned if the vertex did not have a label already.
|
||||
/// @throw std::bad_alloc
|
||||
Result<bool> RemoveLabel(LabelId label);
|
||||
Result<bool> RemoveLabel(LabelId label, bool update_text_index);
|
||||
|
||||
Result<bool> HasLabel(LabelId label, View view) const;
|
||||
|
||||
@ -63,19 +63,20 @@ class VertexAccessor final {
|
||||
|
||||
/// Set a property value and return the old value.
|
||||
/// @throw std::bad_alloc
|
||||
Result<PropertyValue> SetProperty(PropertyId property, const PropertyValue &value);
|
||||
Result<PropertyValue> SetProperty(PropertyId property, const PropertyValue &value, bool update_text_index);
|
||||
|
||||
/// Set property values only if property store is empty. Returns `true` if successully set all values,
|
||||
/// `false` otherwise.
|
||||
/// @throw std::bad_alloc
|
||||
Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties);
|
||||
Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties,
|
||||
bool update_text_index);
|
||||
|
||||
Result<std::vector<std::tuple<PropertyId, PropertyValue, PropertyValue>>> UpdateProperties(
|
||||
std::map<storage::PropertyId, storage::PropertyValue> &properties) const;
|
||||
std::map<storage::PropertyId, storage::PropertyValue> &properties, bool update_text_index) const;
|
||||
|
||||
/// Remove all properties and return the values of the removed properties.
|
||||
/// @throw std::bad_alloc
|
||||
Result<std::map<PropertyId, PropertyValue>> ClearProperties();
|
||||
Result<std::map<PropertyId, PropertyValue>> ClearProperties(bool update_text_index);
|
||||
|
||||
/// @throw std::bad_alloc
|
||||
Result<PropertyValue> GetProperty(PropertyId property, View view) const;
|
||||
|
Loading…
Reference in New Issue
Block a user