/* * Copyright (C) 2021 Codership Oy * * This file is part of wsrep-lib. * * Wsrep-lib is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * Wsrep-lib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with wsrep-lib. If not, see . */ /** @file provider_options.hpp * * A proxy interface to control provider configuration options. */ #ifndef WSREP_PROVIDER_OPTIONS_HPP #define WSREP_PROVIDER_OPTIONS_HPP #include "provider.hpp" #include #include #include #include namespace wsrep { /** * Proxy class for managing provider options. * Options are strings by default, or flagged with corresponding * provider_options::flag as either bool, integer or double. */ class provider_options { public: struct flag { static const int deprecated = (1 << 0); static const int readonly = (1 << 1); static const int type_bool = (1 << 2); static const int type_integer = (1 << 3); static const int type_double = (1 << 4); }; static const int flag_type_mask = flag::type_bool | flag::type_integer | flag::type_double; class option_value { public: virtual ~option_value() {} virtual const char* as_string() const = 0; virtual const void* get_ptr() const = 0; }; class option_value_string : public option_value { public: option_value_string(const std::string& value) : value_(value) { } ~option_value_string() WSREP_OVERRIDE {} const char* as_string() const WSREP_OVERRIDE { return value_.c_str(); } const void* get_ptr() const WSREP_OVERRIDE { return value_.c_str(); } private: std::string value_; }; class option_value_bool : public option_value { public: option_value_bool(bool value) : value_(value) { } ~option_value_bool() WSREP_OVERRIDE {} const char* as_string() const WSREP_OVERRIDE { if (value_) { return "yes"; } else { return "no"; } } const void* get_ptr() const WSREP_OVERRIDE { return &value_; } private: bool value_; }; class option_value_int : public option_value { public: option_value_int(int64_t value) : value_(value) , value_str_(std::to_string(value)) { } ~option_value_int() WSREP_OVERRIDE {} const char* as_string() const WSREP_OVERRIDE { return value_str_.c_str(); } const void* get_ptr() const WSREP_OVERRIDE { return &value_; } private: int64_t value_; std::string value_str_; }; class option_value_double : public option_value { public: option_value_double(double value) : value_(value) , value_str_(std::to_string(value)) { } ~option_value_double() WSREP_OVERRIDE {} const char* as_string() const WSREP_OVERRIDE { return value_str_.c_str(); } const void* get_ptr() const WSREP_OVERRIDE { return &value_; } private: double value_; std::string value_str_; }; class option { public: option(); /** Construct option with given values. Allocates * memory. */ option(const std::string& name, std::unique_ptr value, std::unique_ptr default_value, int flags); /** Non copy-constructible. */ option(const option&) = delete; /** Non copy-assignable. */ option& operator=(const option&) = delete; option(option&&) = delete; option& operator=(option&&) = delete; ~option(); /** * Get name of the option. * * @return Name of the option. */ const char* name() const { return name_.c_str(); } /** * Get the real name of the option. This displays the * option name as it is visible in provider options. */ const char* real_name() const { return real_name_.c_str(); } /** * Get value of the option. * * @return Value of the option. */ option_value* value() const { return value_.get(); } /** * Get default value of the option. * * @return Default value of the option. */ option_value* default_value() const { return default_value_.get(); } /** * Get flags of the option * * @return Flag of the option */ int flags() const { return flags_; } /** * Update the value of the option with new_value. The old * value is freed. */ void update_value(std::unique_ptr new_value); private: /** Sanitized name with dots replaced with underscores */ std::string name_; /** Real name in provider */ std::string real_name_; std::unique_ptr value_; std::unique_ptr default_value_; int flags_; }; provider_options(wsrep::provider&); provider_options(const provider_options&) = delete; provider_options& operator=(const provider_options&) = delete; /** * Set initial options. This should be used to initialize * provider options after the provider has been loaded. * Individual options should be accessed through set()/get(). * * @return Provider status code. */ enum wsrep::provider::status initial_options(); /** * Get the option with the given name * * @param name Name of the option to retrieve */ const option* get_option(const std::string& name) const; /** * Set a value for the option. * * @return Wsrep provider status code. * @return wsrep::provider::error_size_exceeded if memory could * not be allocated for the new value. */ enum wsrep::provider::status set(const std::string& name, std::unique_ptr value); /** * Create a new option with default value. */ enum wsrep::provider::status set_default(const std::string& name, std::unique_ptr value, std::unique_ptr default_value, int flags); void for_each(const std::function& fn); private: provider& provider_; using options_map = std::map>; options_map options_; }; /** * Equality operator for provider option. Returns true if * the name part is equal. */ bool operator==(const wsrep::provider_options::option&, const wsrep::provider_options::option&); } // namespace wsrep #endif // WSREP_PROVIDER_OPTIONS_HPP