backend/schema/builders/table_builder.h (210 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_BUILDERS_TABLE_BUILDER_H_
#define THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_BUILDERS_TABLE_BUILDER_H_
#include <algorithm>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "absl/log/check.h"
#include "absl/memory/memory.h"
#include "backend/common/ids.h"
#include "backend/schema/catalog/change_stream.h"
#include "backend/schema/catalog/check_constraint.h"
#include "backend/schema/catalog/column.h"
#include "backend/schema/catalog/foreign_key.h"
#include "backend/schema/catalog/index.h"
#include "backend/schema/catalog/locality_group.h"
#include "backend/schema/catalog/table.h"
#include "backend/schema/ddl/operations.pb.h"
#include "backend/schema/updater/schema_validation_context.h"
#include "backend/schema/validators/table_validator.h"
namespace google {
namespace spanner {
namespace emulator {
namespace backend {
class Table::Builder {
public:
Builder()
: instance_(absl::WrapUnique(new Table(
TableValidator::Validate, TableValidator::ValidateUpdate))) {}
std::unique_ptr<const Table> build() { return std::move(instance_); }
const Table* get() const { return instance_.get(); }
Builder& set_id(const std::string& id) {
instance_->id_ = id;
return *this;
}
Builder& set_name(const std::string& name) {
instance_->name_ = name;
return *this;
}
Builder& set_owner_index(const Index* index) {
instance_->owner_index_ = index;
return *this;
}
Builder& set_owner_change_stream(const ChangeStream* change_stream) {
instance_->owner_change_stream_ = change_stream;
return *this;
}
Builder& add_change_stream(const ChangeStream* change_stream) {
instance_->change_streams_.push_back(change_stream);
return *this;
}
Builder& add_column(const Column* column) {
instance_->columns_.push_back(column);
instance_->columns_map_[column->Name()] = column;
return *this;
}
Builder& add_key_column(const KeyColumn* key_col) {
instance_->primary_key_.push_back(key_col);
return *this;
}
Builder& set_parent_table(const Table* table) {
instance_->parent_table_ = table;
return *this;
}
Builder& set_on_delete(OnDeleteAction action) {
instance_->on_delete_action_ = action;
return *this;
}
Builder& add_foreign_key(const ForeignKey* foreign_key) {
instance_->foreign_keys_.push_back(foreign_key);
return *this;
}
Builder& add_referencing_foreign_key(const ForeignKey* foreign_key) {
instance_->referencing_foreign_keys_.push_back(foreign_key);
return *this;
}
Builder& set_row_deletion_policy(
std::optional<ddl::RowDeletionPolicy> policy) {
instance_->row_deletion_policy_ = policy;
return *this;
}
Builder& set_synonym(const std::string& synonym) {
instance_->synonym_ = synonym;
return *this;
}
Builder& set_postgresql_oid(std::optional<uint32_t> postgresql_oid) {
if (postgresql_oid.has_value()) {
instance_->set_postgresql_oid(postgresql_oid.value());
}
return *this;
}
Builder& set_interleave_in_parent_postgresql_oid(
std::optional<uint32_t> postgresql_oid) {
if (postgresql_oid.has_value()) {
instance_->set_interleave_in_parent_postgresql_oid(
postgresql_oid.value());
}
return *this;
}
Builder& set_primary_key_index_postgresql_oid(
std::optional<uint32_t> postgresql_oid) {
if (postgresql_oid.has_value()) {
instance_->set_primary_key_index_postgresql_oid(postgresql_oid.value());
}
return *this;
}
private:
std::unique_ptr<Table> instance_;
};
class Table::Editor {
public:
explicit Editor(Table* instance) : instance_(instance) {}
const Table* get() const { return instance_; }
Editor& set_name(const std::string& name) {
instance_->name_ = name;
return *this;
}
Editor& add_column(const Column* column) {
instance_->columns_.push_back(column);
instance_->columns_map_[column->Name()] = column;
return *this;
}
Editor& add_index(const Index* index) {
instance_->indexes_.push_back(index);
return *this;
}
Editor& add_child_table(const Table* table) {
instance_->child_tables_.push_back(table);
return *this;
}
Editor& set_on_delete(OnDeleteAction action) {
instance_->on_delete_action_ = action;
return *this;
}
Editor& add_check_constraint(const CheckConstraint* check_constraint) {
instance_->check_constraints_.push_back(check_constraint);
return *this;
}
Editor& add_foreign_key(const ForeignKey* foreign_key) {
instance_->foreign_keys_.push_back(foreign_key);
return *this;
}
Editor& add_referencing_foreign_key(const ForeignKey* foreign_key) {
instance_->referencing_foreign_keys_.push_back(foreign_key);
return *this;
}
Editor& set_row_deletion_policy(
std::optional<ddl::RowDeletionPolicy> policy) {
instance_->row_deletion_policy_ = policy;
return *this;
}
Editor& add_change_stream(const ChangeStream* change_stream) {
instance_->change_streams_.push_back(change_stream);
return *this;
}
Editor& add_change_stream_explicitly_tracking_table(
const ChangeStream* change_stream) {
instance_->change_streams_explicitly_tracking_table_.push_back(
change_stream);
return *this;
}
Editor& remove_change_stream(const ChangeStream* change_stream) {
auto itr = std::find_if(
instance_->change_streams_.begin(), instance_->change_streams_.end(),
[change_stream](const auto& change_stream_element) {
return absl::EqualsIgnoreCase(change_stream->Name(),
change_stream_element->Name());
});
if (itr != instance_->change_streams_.end()) {
instance_->change_streams_.erase(itr);
}
auto itr_2 = std::find_if(
instance_->change_streams_explicitly_tracking_table_.begin(),
instance_->change_streams_explicitly_tracking_table_.end(),
[change_stream](const auto& change_stream_element) {
return absl::EqualsIgnoreCase(change_stream->Name(),
change_stream_element->Name());
});
if (itr_2 != instance_->change_streams_explicitly_tracking_table_.end()) {
instance_->change_streams_explicitly_tracking_table_.erase(itr_2);
}
return *this;
}
Editor& set_synonym(const std::string& synonym) {
instance_->synonym_ = synonym;
return *this;
}
Editor& drop_synonym(const std::string& synonym) {
if (instance_->synonym_ == synonym) {
instance_->synonym_ = "";
}
return *this;
}
Editor& set_locality_group(const LocalityGroup* locality_group) {
instance_->locality_group_ = locality_group;
return *this;
}
Editor& clear_locality_group() {
instance_->locality_group_ = nullptr;
return *this;
}
private:
// Not owned.
Table* instance_;
};
} // namespace backend
} // namespace emulator
} // namespace spanner
} // namespace google
#endif // THIRD_PARTY_CLOUD_SPANNER_EMULATOR_BACKEND_SCHEMA_BUILDERS_TABLE_BUILDER_H_