backend/schema/catalog/property_graph.h (166 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. // #ifndef THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_CATALOG_PROPERTY_GRAPH_H_ #define THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_CATALOG_PROPERTY_GRAPH_H_ #include <functional> #include <memory> #include <optional> #include <string> #include <string_view> #include <vector> #include "absl/container/flat_hash_set.h" #include "absl/memory/memory.h" #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_node.h" namespace google { namespace spanner { namespace emulator { namespace backend { class PropertyGraph : public SchemaNode { public: struct PropertyDeclaration { std::string name; std::string type; }; struct Label { std::string name; absl::flat_hash_set<std::string> property_names; }; enum GraphElementKind { UNDEFINED, NODE, EDGE }; class GraphElementTable { public: struct PropertyDefinition { std::string name; std::string value_expression_string; }; struct GraphNodeReference { // Referenced node table's name. std::string node_table_name; // Referenced node table's column names. std::vector<std::string> node_table_column_names; // Edge table's column names. std::vector<std::string> edge_table_column_names; std::string DebugString() const { return absl::StrCat("node_table_name: ", node_table_name, "\n", "node_table_column_names: ", absl::StrJoin(node_table_column_names, ", "), "\n", "edge_table_column_names: ", absl::StrJoin(edge_table_column_names, ", ")); } }; const std::string& name() const { return name_; } const std::string& alias() const { return alias_; } GraphElementKind element_kind() const { return element_kind_; } const std::vector<std::string>& key_clause_columns() const { return key_clause_columns_; } const std::vector<std::string>& label_names() const { return label_names_; } const std::vector<PropertyDefinition>& property_definitions() const { return property_definitions_; } const GraphNodeReference& source_node_reference() const { return source_node_reference_; } const GraphNodeReference& target_node_reference() const { return target_node_reference_; } void set_name(std::string_view name) { name_ = name; } void set_alias(std::string_view alias) { alias_ = alias; } void set_element_kind(GraphElementKind element_kind) { element_kind_ = element_kind; } void add_key_clause_column(std::string_view key_clause_column) { key_clause_columns_.push_back(std::string(key_clause_column)); } void add_label_name(std::string_view label_name) { label_names_.push_back(std::string(label_name)); } void add_property_definition(std::string_view name, std::string_view value_expression_string) { property_definitions_.push_back( {.name = std::string(name), .value_expression_string = std::string(value_expression_string)}); } void set_source_node_reference( std::string_view node_table_name, const std::vector<std::string> node_table_column_names, const std::vector<std::string> edge_table_column_names) { source_node_reference_.node_table_name = std::string(node_table_name); source_node_reference_.node_table_column_names = node_table_column_names; source_node_reference_.edge_table_column_names = edge_table_column_names; } void set_target_node_reference( std::string_view node_table_name, const std::vector<std::string> node_table_column_names, const std::vector<std::string> edge_table_column_names) { target_node_reference_.node_table_name = std::string(node_table_name); target_node_reference_.node_table_column_names = node_table_column_names; target_node_reference_.edge_table_column_names = edge_table_column_names; } std::string DebugString() const; private: // Name of the element table. std::string name_; // Alias of the element table. std::string alias_; // Kind of the element table: NODE or EDGE. GraphElementKind element_kind_; // Key clause columns of the element table. std::vector<std::string> key_clause_columns_; // Label names linked to this element table. std::vector<std::string> label_names_; // Property definitions in this element table. std::vector<PropertyDefinition> property_definitions_; // Source node reference for an edge table. GraphNodeReference source_node_reference_; // Target node reference for an edge table. GraphNodeReference target_node_reference_; }; const std::string& Name() const { return name_; } const std::string& DdlBody() const { return ddl_body_; } const std::vector<PropertyDeclaration>& PropertyDeclarations() const { return property_declarations_; } const std::vector<Label>& Labels() const { return labels_; } const std::vector<GraphElementTable>& NodeTables() const { return node_tables_; } const std::vector<GraphElementTable>& EdgeTables() const { return edge_tables_; } // const PropertyGraph::Label* FindLabelByName(absl::string_view name) const; // const PropertyGraph::PropertyDeclaration* FindPropertyDeclarationByName( // absl::string_view name) const; absl::Status FindLabelByName(absl::string_view name, const PropertyGraph::Label*& label) const; absl::Status FindPropertyDeclarationByName( absl::string_view name, const PropertyGraph::PropertyDeclaration*& property_declaration) const; // SchemaNode interface implementation. // ------------------------------------ std::optional<SchemaNameInfo> GetSchemaNameInfo() const override { return SchemaNameInfo{ .name = name_, .kind = "PropertyGraph", .global = true}; } absl::Status Validate(SchemaValidationContext* context) const override; absl::Status ValidateUpdate(const SchemaNode* orig, SchemaValidationContext* context) const override; std::string DebugString() const override; catalog::PropertyGraphProto ToProto() const; class Builder; class Editor; private: friend class PropertyGraphValidator; using ValidationFn = std::function<absl::Status(const PropertyGraph*, SchemaValidationContext*)>; using UpdateValidationFn = std::function<absl::Status( const PropertyGraph*, const PropertyGraph*, SchemaValidationContext*)>; // Constructors are private and only friend classes are able to build. PropertyGraph(const ValidationFn& validate, const UpdateValidationFn& validate_update) : validate_(validate), validate_update_(validate_update) {} PropertyGraph(const PropertyGraph&) = default; std::unique_ptr<SchemaNode> ShallowClone() const override { return absl::WrapUnique(new PropertyGraph(*this)); } absl::Status DeepClone(SchemaGraphEditor* editor, const SchemaNode* orig) override; // Validation delegates. const ValidationFn validate_; const UpdateValidationFn validate_update_; // The name of the property graph. std::string name_; // The input DDL string for this property graph. std::string ddl_body_; // The set of property declarations in this property graph. std::vector<PropertyDeclaration> property_declarations_; // The set of labels in this property graph. std::vector<Label> labels_; // The list of node tables in this property graph. std::vector<GraphElementTable> node_tables_; // The list of edge tables in this property graph. std::vector<GraphElementTable> edge_tables_; }; } // namespace backend } // namespace emulator } // namespace spanner } // namespace google #endif // THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_CATALOG_PROPERTY_GRAPH_H_