From 6ef7885ae36798623bc391023b4a69b5e1935fde Mon Sep 17 00:00:00 2001 From: Calle Wilund Date: Tue, 10 May 2016 14:31:30 +0000 Subject: [PATCH] database: Implement update_keyspace Reloads keyspace metadata and replaces in existing keyspace. Note: since keyspace metadata, and consequently, replication strategy now becomes volatile, keyspace::metadata now returns shared pointer by value (i.e. keep-alive). Replication strategy should receive the same treatment, but since it is extensively used, but never kept across a continuation, I've just added a comment for now. --- database.cc | 18 ++++++++++++++++-- database.hh | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/database.cc b/database.cc index 7e35af1b35..c61280189a 100644 --- a/database.cc +++ b/database.cc @@ -1473,8 +1473,17 @@ void database::add_keyspace(sstring name, keyspace k) { _keyspaces.emplace(std::move(name), std::move(k)); } -void database::update_keyspace(const sstring& name) { - throw std::runtime_error("update keyspace not implemented"); +future<> database::update_keyspace(const sstring& name) { + auto& proxy = service::get_storage_proxy(); + return db::schema_tables::read_schema_partition_for_keyspace(proxy, db::schema_tables::KEYSPACES, name).then([this, name](db::schema_tables::schema_result_value_type&& v) { + auto& ks = find_keyspace(name); + + auto tmp_ksm = db::schema_tables::create_keyspace_from_schema_partition(v); + auto new_ksm = ::make_lw_shared(tmp_ksm->name(), tmp_ksm->strategy_name(), tmp_ksm->strategy_options(), tmp_ksm->durable_writes(), + boost::copy_range>(ks.metadata()->cf_meta_data() | boost::adaptors::map_values), ks.metadata()->user_types()); + ks.update_from(std::move(new_ksm)); + return service::get_local_migration_manager().notify_update_keyspace(ks.metadata()); + }); } void database::drop_keyspace(const sstring& name) { @@ -1628,6 +1637,11 @@ keyspace::set_replication_strategy(std::unique_ptr ksm) { + _metadata = std::move(ksm); + create_replication_strategy(_metadata->strategy_options()); +} + column_family::config keyspace::make_column_family_config(const schema& s) const { column_family::config cfg; diff --git a/database.hh b/database.hh index bb31cb56a8..48832667fd 100644 --- a/database.hh +++ b/database.hh @@ -734,10 +734,24 @@ public: : _metadata(std::move(metadata)) , _config(std::move(cfg)) {} - const lw_shared_ptr& metadata() const { + + void update_from(lw_shared_ptr); + + /** Note: return by shared pointer value, since the meta data is + * semi-volatile. I.e. we could do alter keyspace at any time, and + * boom, it is replaced. + */ + lw_shared_ptr metadata() const { return _metadata; } void create_replication_strategy(const std::map& options); + /** + * This should not really be return by reference, since replication + * strategy is also volatile in that it could be replaced at "any" time. + * However, all current uses at least are "instantateous", i.e. does not + * carry it across a continuation. So it is sort of same for now, but + * should eventually be refactored. + */ locator::abstract_replication_strategy& get_replication_strategy(); const locator::abstract_replication_strategy& get_replication_strategy() const; column_family::config make_column_family_config(const schema& s) const; @@ -872,7 +886,7 @@ public: keyspace& find_keyspace(const sstring& name); const keyspace& find_keyspace(const sstring& name) const; bool has_keyspace(const sstring& name) const; - void update_keyspace(const sstring& name); + future<> update_keyspace(const sstring& name); void drop_keyspace(const sstring& name); const auto& keyspaces() const { return _keyspaces; } std::vector get_non_system_keyspaces() const;