/* * Copyright (C) 2021-present ScyllaDB */ /* * SPDX-License-Identifier: AGPL-3.0-or-later */ #include "data_dictionary.hh" #include "impl.hh" #include "user_types_metadata.hh" #include "keyspace_metadata.hh" #include "schema.hh" #include "utils/overloaded_functor.hh" #include #include #include #include #include #include namespace data_dictionary { schema_ptr table::schema() const { return _ops->get_table_schema(*this); } const std::vector& table::views() const { return _ops->get_table_views(*this); } const secondary_index::secondary_index_manager& table::get_index_manager() const { return _ops->get_index_manager(*this); } lw_shared_ptr keyspace::metadata() const { return _ops->get_keyspace_metadata(*this); } const user_types_metadata& keyspace::user_types() const { return metadata()->user_types(); } bool keyspace::is_internal() const { return _ops->is_internal(*this); } const locator::abstract_replication_strategy& keyspace::get_replication_strategy() const { return _ops->get_replication_strategy(*this); } std::optional database::try_find_keyspace(std::string_view name) const { return _ops->try_find_keyspace(*this, name); } bool database::has_keyspace(std::string_view name) const { return bool(try_find_keyspace(name)); } keyspace database::find_keyspace(std::string_view name) const { auto ks = try_find_keyspace(name); if (!ks) { throw no_such_keyspace(name); } return *ks; } std::vector database::get_keyspaces() const { return _ops->get_keyspaces(*this); } std::vector database::get_tables() const { return _ops->get_tables(*this); } std::optional
database::try_find_table(std::string_view ks, std::string_view table) const { return _ops->try_find_table(*this, ks, table); } table database::find_table(std::string_view ks, std::string_view table) const { auto t = try_find_table(ks, table); if (!t) { throw no_such_column_family(ks, table); } return *t; } std::optional
database::try_find_table(utils::UUID id) const { return _ops->try_find_table(*this, id); } table database::find_column_family(utils::UUID uuid) const { auto t = try_find_table(uuid); if (!t) { throw no_such_column_family(uuid); } return *t; } schema_ptr database::find_schema(std::string_view ks, std::string_view table) const { return find_table(ks, table).schema(); } schema_ptr database::find_schema(utils::UUID uuid) const { return find_column_family(uuid).schema(); } bool database::has_schema(std::string_view ks_name, std::string_view cf_name) const { return bool(try_find_table(ks_name, cf_name)); } table database::find_column_family(schema_ptr s) const { return find_column_family(s->id()); } schema_ptr database::find_indexed_table(std::string_view ks_name, std::string_view index_name) const { return _ops->find_indexed_table(*this, ks_name, index_name); } sstring database::get_available_index_name(std::string_view ks_name, std::string_view table_name, std::optional index_name_root) const { return _ops->get_available_index_name(*this, ks_name, table_name, index_name_root); } std::set database::existing_index_names(std::string_view ks_name, std::string_view cf_to_exclude) const { return _ops->existing_index_names(*this, ks_name, cf_to_exclude); } schema_ptr database::get_cdc_base_table(sstring_view ks_name, std::string_view table_name) const { return get_cdc_base_table(*find_table(ks_name, table_name).schema()); } schema_ptr database::get_cdc_base_table(const schema& s) const { return _ops->get_cdc_base_table(*this, s); } const db::extensions& database::extensions() const { return _ops->get_extensions(*this); } const gms::feature_service& database::features() const { return _ops->get_features(*this); } const db::config& database::get_config() const { return _ops->get_config(*this); } replica::database& database::real_database() const { return _ops->real_database(*this); } impl::~impl() = default; keyspace_metadata::keyspace_metadata(std::string_view name, std::string_view strategy_name, locator::replication_strategy_config_options strategy_options, bool durable_writes, std::vector cf_defs) : keyspace_metadata(name, strategy_name, std::move(strategy_options), durable_writes, std::move(cf_defs), user_types_metadata{}) { } keyspace_metadata::keyspace_metadata(std::string_view name, std::string_view strategy_name, locator::replication_strategy_config_options strategy_options, bool durable_writes, std::vector cf_defs, user_types_metadata user_types) : keyspace_metadata(name, strategy_name, std::move(strategy_options), durable_writes, std::move(cf_defs), user_types_metadata{}, storage_options{}) { } keyspace_metadata::keyspace_metadata(std::string_view name, std::string_view strategy_name, locator::replication_strategy_config_options strategy_options, bool durable_writes, std::vector cf_defs, user_types_metadata user_types, storage_options storage_opts) : _name{name} , _strategy_name{locator::abstract_replication_strategy::to_qualified_class_name(strategy_name.empty() ? "NetworkTopologyStrategy" : strategy_name)} , _strategy_options{std::move(strategy_options)} , _durable_writes{durable_writes} , _user_types{std::move(user_types)} , _storage_options{std::move(storage_opts)} { for (auto&& s : cf_defs) { _cf_meta_data.emplace(s->cf_name(), s); } } void keyspace_metadata::validate(const locator::topology& topology) const { using namespace locator; abstract_replication_strategy::validate_replication_strategy(name(), strategy_name(), strategy_options(), topology); } lw_shared_ptr keyspace_metadata::new_keyspace(std::string_view name, std::string_view strategy_name, locator::replication_strategy_config_options options, bool durables_writes, std::vector cf_defs, storage_options storage_opts) { return ::make_lw_shared(name, strategy_name, options, durables_writes, cf_defs, user_types_metadata{}, storage_opts); } void keyspace_metadata::add_user_type(const user_type ut) { _user_types.add_type(ut); } void keyspace_metadata::remove_user_type(const user_type ut) { _user_types.remove_type(ut); } std::vector keyspace_metadata::tables() const { return boost::copy_range>(_cf_meta_data | boost::adaptors::map_values | boost::adaptors::filtered([] (auto&& s) { return !s->is_view(); })); } std::vector keyspace_metadata::views() const { return boost::copy_range>(_cf_meta_data | boost::adaptors::map_values | boost::adaptors::filtered(std::mem_fn(&schema::is_view)) | boost::adaptors::transformed([] (auto&& s) { return view_ptr(s); })); } storage_options::value_type storage_options::from_map(std::string_view type, std::map values) { if (type == "LOCAL") { if (!values.empty()) { throw std::runtime_error("Local storage does not accept any custom options"); } return local{}; } if (type == "S3") { s3 options; const std::array, 2> allowed_options { std::make_pair("bucket", &options.bucket), std::make_pair("endpoint", &options.endpoint), }; for (auto& option : allowed_options) { if (auto it = values.find(option.first); it != values.end()) { *option.second = it->second; } else { throw std::runtime_error(format("Missing S3 option: {}", option.first)); } } if (values.size() > allowed_options.size()) { throw std::runtime_error(format("Extraneous options for S3: {}; allowed: {}", boost::algorithm::join(values | boost::adaptors::map_keys, ","), boost::algorithm::join(allowed_options | boost::adaptors::map_keys, ","))); } return options; } throw std::runtime_error(format("Unknown storage type: {}", type)); } std::string_view storage_options::type_string() const { return std::visit(overloaded_functor { [] (const storage_options::local&) { return "LOCAL"; }, [] (const storage_options::s3&) { return "S3"; } }, value); } std::map storage_options::to_map() const { std::map ret; std::visit(overloaded_functor { [] (const storage_options::local&) { }, [&ret] (const storage_options::s3& v) { ret.emplace("bucket", v.bucket); ret.emplace("endpoint", v.endpoint); } }, value); return ret; } bool storage_options::can_update_to(const storage_options& new_options) { return value == new_options.value; } no_such_keyspace::no_such_keyspace(std::string_view ks_name) : runtime_error{format("Can't find a keyspace {}", ks_name)} { } no_such_column_family::no_such_column_family(const utils::UUID& uuid) : runtime_error{format("Can't find a column family with UUID {}", uuid)} { } no_such_column_family::no_such_column_family(std::string_view ks_name, std::string_view cf_name) : runtime_error{format("Can't find a column family {} in keyspace {}", cf_name, ks_name)} { } no_such_column_family::no_such_column_family(std::string_view ks_name, const utils::UUID& uuid) : runtime_error{format("Can't find a column family with UUID {} in keyspace {}", uuid, ks_name)} { } std::ostream& operator<<(std::ostream& os, const keyspace_metadata& m) { os << "KSMetaData{"; os << "name=" << m._name; os << ", strategyClass=" << m._strategy_name; os << ", strategyOptions={"; int n = 0; for (auto& p : m._strategy_options) { if (n++ != 0) { os << ", "; } os << p.first << "=" << p.second; } os << "}"; os << ", cfMetaData={"; n = 0; for (auto& p : m._cf_meta_data) { if (n++ != 0) { os << ", "; } os << p.first << "=" << p.second; } os << "}"; os << ", durable_writes=" << m._durable_writes; os << ", userTypes=" << m._user_types; os << "}"; return os; } std::ostream& operator<<(std::ostream& os, const user_types_metadata& m) { os << "org.apache.cassandra.config.UTMetaData@" << &m; return os; } }