backend/schema/catalog/property_graph.cc (190 lines of code) (raw):

// // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #include "backend/schema/catalog/property_graph.h" #include <string> #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_join.h" #include "absl/strings/string_view.h" #include "backend/schema/catalog/property_graph.pb.h" #include "backend/schema/graph/schema_graph_editor.h" #include "backend/schema/graph/schema_node.h" #include "backend/schema/updater/schema_validation_context.h" namespace google { namespace spanner { namespace emulator { namespace backend { absl::Status PropertyGraph::Validate(SchemaValidationContext* context) const { return validate_(this, context); } absl::Status PropertyGraph::ValidateUpdate( const SchemaNode* orig, SchemaValidationContext* context) const { return validate_update_(this, orig->As<const PropertyGraph>(), context); } absl::Status PropertyGraph::DeepClone(SchemaGraphEditor* editor, const SchemaNode* orig) { return absl::OkStatus(); } std::string PropertyGraph::DebugString() const { std::string debug_string; absl::StrAppend(&debug_string, "PropertyGraph(\"", name_, "\") {\n"); absl::StrAppend(&debug_string, " ddl_body: \"", ddl_body_, "\"\n"); absl::StrAppend(&debug_string, " property_declarations: [\n"); for (const auto& property_declaration : property_declarations_) { absl::StrAppend(&debug_string, " { name: \"", property_declaration.name, "\", type: \"", property_declaration.type, "\" },\n"); } absl::StrAppend(&debug_string, " ]\n"); absl::StrAppend(&debug_string, " labels: [\n"); for (const auto& label : labels_) { absl::StrAppend(&debug_string, " { name: \"", label.name, "\", properties: ["); for (const auto& property_name : label.property_names) { absl::StrAppend(&debug_string, "\"", property_name, "\", "); } absl::StrAppend(&debug_string, "] },\n"); } absl::StrAppend(&debug_string, " ]\n"); absl::StrAppend(&debug_string, " node_tables: [\n"); for (const auto& node_table_element : node_tables_) { absl::StrAppend(&debug_string, " ", node_table_element.DebugString(), ",\n"); } absl::StrAppend(&debug_string, " ]\n"); absl::StrAppend(&debug_string, " edge_tables: [\n"); for (const auto& edge_table_element : edge_tables_) { absl::StrAppend(&debug_string, " ", edge_table_element.DebugString(), ",\n"); } absl::StrAppend(&debug_string, " ]\n"); absl::StrAppend(&debug_string, "}"); return debug_string; } inline void SetNodeTableReferenceProto( const PropertyGraph::GraphElementTable::GraphNodeReference& data, catalog::GraphNodeTableReferenceProto& proto) { proto.set_node_table_name(data.node_table_name); for (const auto& node_table_column_name : data.node_table_column_names) { proto.add_node_table_columns(node_table_column_name); } for (const auto& edge_table_column_name : data.edge_table_column_names) { proto.add_edge_table_columns(edge_table_column_name); } } catalog::PropertyGraphProto PropertyGraph::ToProto() const { catalog::PropertyGraphProto proto; proto.set_catalog(""); proto.set_schema(""); proto.set_name(name_); for (const auto& node : node_tables_) { auto& node_proto = *proto.add_node_tables(); node_proto.set_name(node.name()); node_proto.set_kind(catalog::GraphElementTableProto::NODE); node_proto.set_base_table_name(node.name()); node_proto.set_base_catalog_name(""); node_proto.set_base_schema_name(""); for (const auto& key_clause_column : node.key_clause_columns()) { node_proto.add_key_columns(key_clause_column); } for (const auto& label_name : node.label_names()) { node_proto.add_label_names(label_name); } for (const auto& property_definition : node.property_definitions()) { auto& property_definition_proto = *node_proto.add_property_definitions(); property_definition_proto.set_property_declaration_name( property_definition.name); property_definition_proto.set_value_expression_sql( property_definition.value_expression_string); } } for (const auto& edge : edge_tables_) { auto& edge_proto = *proto.add_edge_tables(); edge_proto.set_name(edge.name()); edge_proto.set_kind(catalog::GraphElementTableProto::EDGE); edge_proto.set_base_table_name(edge.name()); edge_proto.set_base_catalog_name(""); edge_proto.set_base_schema_name(""); for (const auto& key_clause_column : edge.key_clause_columns()) { edge_proto.add_key_columns(key_clause_column); } for (const auto& label_name : edge.label_names()) { edge_proto.add_label_names(label_name); } for (const auto& property_definition : edge.property_definitions()) { auto& property_definition_proto = *edge_proto.add_property_definitions(); property_definition_proto.set_property_declaration_name( property_definition.name); property_definition_proto.set_value_expression_sql( property_definition.value_expression_string); } SetNodeTableReferenceProto(edge.source_node_reference(), *edge_proto.mutable_source_node_table()); SetNodeTableReferenceProto(edge.target_node_reference(), *edge_proto.mutable_destination_node_table()); } for (const auto& label : labels_) { auto& label_proto = *proto.add_labels(); label_proto.set_name(label.name); for (const auto& property_name : label.property_names) { label_proto.add_property_declaration_names(property_name); } } for (const auto& property_declaration : property_declarations_) { auto& property_declaration_proto = *proto.add_property_declarations(); property_declaration_proto.set_name(property_declaration.name); property_declaration_proto.set_type(property_declaration.type); } return proto; } std::string PropertyGraph::GraphElementTable::DebugString() const { std::string debug_string; absl::StrAppend(&debug_string, "GraphElementTable {\n"); absl::StrAppend(&debug_string, " name: ", name_, "\n"); absl::StrAppend(&debug_string, " alias: ", alias_, "\n"); absl::StrAppend(&debug_string, " element_kind: ", element_kind_, "\n"); absl::StrAppend(&debug_string, " key_clause_columns: ", absl::StrJoin(key_clause_columns_, ", "), "\n"); absl::StrAppend(&debug_string, " label_names: ", absl::StrJoin(label_names_, ", "), "\n"); if (element_kind_ == GraphElementKind::EDGE) { absl::StrAppend(&debug_string, " source_node_reference: ", source_node_reference_.DebugString(), "\n"); absl::StrAppend(&debug_string, " target_node_reference: ", target_node_reference_.DebugString(), "\n"); } absl::StrAppend( &debug_string, " property_definitions: ", absl::StrJoin(property_definitions_, ", ", [](std::string* out, const PropertyDefinition& pd) { absl::StrAppend(out, "{name: ", pd.name, ", value_expression_string: ", pd.value_expression_string, "}"); }), "\n"); absl::StrAppend(&debug_string, "}"); return debug_string; } absl::Status PropertyGraph::FindLabelByName( absl::string_view name, const PropertyGraph::Label*& label) const { for (const auto& l : labels_) { if (l.name == name) { label = &l; return absl::OkStatus(); } } return absl::NotFoundError(absl::StrCat("Label not found: ", name)); } absl::Status PropertyGraph::FindPropertyDeclarationByName( absl::string_view name, const PropertyGraph::PropertyDeclaration*& property_declaration) const { for (const auto& pd : property_declarations_) { if (pd.name == name) { property_declaration = &pd; return absl::OkStatus(); } } return absl::NotFoundError( absl::StrCat("Property declaration not found: ", name)); } } // namespace backend } // namespace emulator } // namespace spanner } // namespace google