mysql5/mysql-5.7.27/client/base/abstract_option.h

198 lines
5.6 KiB
C++

/*
Copyright (c) 2014, 2015 Oracle and/or its affiliates. All rights reserved.
This program 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; version 2 of the License.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ABSTRACT_OPTION_INCLUDED
#define ABSTRACT_OPTION_INCLUDED
#include <string>
#include <vector>
#include "my_getopt.h"
#include "i_option_changed_listener.h"
#include "i_callable.h"
namespace Mysql{
namespace Tools{
namespace Base{
namespace Options{
class Abstract_options_provider;
/**
Abstract base with common option functionalities.
*/
template<typename T_type> class Abstract_option : public I_option
{
public:
virtual ~Abstract_option();
/**
Adds new callback for this option for option_parsed() event to callback
chain.
I_Callable can be replaced with std::Function<void(char*)> once we get
one.
*/
T_type* add_callback(Mysql::I_callable<void, char*>* callback);
/**
Sets optid to given character to make possible usage of short option
alternative.
*/
T_type* set_short_character(char code);
protected:
/**
Constructs new option.
@param value Pointer to object to receive option value.
@param var_type my_getopt internal option type.
@param name Name of option. It is used in command line option name as
--name.
@param desription Description of option to be printed in --help.
@param default_value default value to be supplied to internal option
data structure.
*/
Abstract_option(void* value, ulong var_type, std::string name,
std::string description, uint64 default_value);
/**
Returns my_getopt internal option data structure representing this option.
To be used by Abstract_options_provider when preparing options array to
return.
*/
my_option get_my_option();
/**
Method to set listener on option changed events.
For use from Abstract_options_provider class only.
*/
void set_option_changed_listener(I_option_changed_listener* listener);
my_option m_option_structure;
private:
void call_callbacks(char* argument);
std::vector<Mysql::I_callable<void, char*>*> m_callbacks;
I_option_changed_listener* m_option_changed_listener;
friend class Abstract_options_provider;
};
template<typename T_type> Abstract_option<T_type>::~Abstract_option()
{
my_free((void*)this->m_option_structure.name);
my_free((void*)this->m_option_structure.comment);
for (std::vector<Mysql::I_callable<void, char*>*>::iterator
it= this->m_callbacks.begin();
it != this->m_callbacks.end();
it++)
{
delete *it;
}
}
template<typename T_type> T_type* Abstract_option<T_type>::add_callback(
Mysql::I_callable<void, char*>* callback)
{
this->m_callbacks.push_back(callback);
return (T_type*)this;
}
template<typename T_type> T_type* Abstract_option<T_type>::set_short_character(
char code)
{
// Change optid to new one
uint32 old_optid= this->m_option_structure.id;
this->m_option_structure.id= (int)code;
// Inform that it has changed
if (this->m_option_changed_listener != NULL)
{
this->m_option_changed_listener->notify_option_optid_changed(
this, old_optid);
}
return (T_type*)this;
}
template<typename T_type> Abstract_option<T_type>::Abstract_option(void* value,
ulong var_type, std::string name, std::string description,
uint64 default_value)
: m_option_changed_listener(NULL)
{
this->m_option_structure.block_size= 0;
this->m_option_structure.max_value= 0;
this->m_option_structure.min_value= 0;
this->m_option_structure.sub_size= 0;
this->m_option_structure.typelib= NULL;
this->m_option_structure.u_max_value= NULL;
this->m_option_structure.app_type= this;
this->m_option_structure.arg_type= REQUIRED_ARG;
this->m_option_structure.comment= my_strdup(
PSI_NOT_INSTRUMENTED, description.c_str(), MYF(MY_FAE));
// This in future can be changed to atomic operation (compare_and_exchange)
this->m_option_structure.id= Abstract_option::last_optid;
Abstract_option::last_optid++;
;
this->m_option_structure.def_value= default_value;
this->m_option_structure.name= my_strdup(
PSI_NOT_INSTRUMENTED, name.c_str(), MYF(MY_FAE));
/*
TODO mbabij 15-04-2014: this is based on previous usages of my_option.
Everyone sets this the same as my_option::value, explain why.
*/
this->m_option_structure.u_max_value= value;
this->m_option_structure.value= value;
this->m_option_structure.var_type= var_type;
}
template<typename T_type> my_option Abstract_option<T_type>::get_my_option()
{
return this->m_option_structure;
}
template<typename T_type> void
Abstract_option<T_type>::set_option_changed_listener(
I_option_changed_listener* listener)
{
DBUG_ASSERT(this->m_option_changed_listener == NULL);
this->m_option_changed_listener= listener;
}
template<typename T_type> void Abstract_option<T_type>::call_callbacks(
char* argument)
{
std::vector<Mysql::I_callable<void, char*>*>::iterator callback_it;
for (callback_it= this->m_callbacks.begin();
callback_it != this->m_callbacks.end(); callback_it++)
{
(**callback_it)(argument);
}
}
}
}
}
}
#endif