1 /*
2    Copyright (c) 2014, 2021, Oracle and/or its affiliates.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef ABSTRACT_OPTIONS_PROVIDER_INCLUDED
26 #define ABSTRACT_OPTIONS_PROVIDER_INCLUDED
27 
28 #include <map>
29 #include <string>
30 #include "i_option.h"
31 #include "i_options_provider.h"
32 #include "i_option_changed_listener.h"
33 #include "simple_option.h"
34 #include "disabled_option.h"
35 #include "char_array_option.h"
36 #include "password_option.h"
37 #include "string_option.h"
38 #include "number_option.h"
39 #include "bool_option.h"
40 #include "enum_option.h"
41 
42 namespace Mysql{
43 namespace Tools{
44 namespace Base{
45 namespace Options{
46 
47 /**
48   Common abstract class for options providers.
49   Provides common functionalities.
50  */
51 class Abstract_options_provider : public I_options_provider
52 {
53 public:
54   /**
55     Creates and attach new simple option.
56     @param name Name of option. It is used in command-line option name as
57       --name.
58     @param desription Description of option to be printed in --help.
59    */
60   Simple_option* create_new_option(std::string name, std::string description);
61   /**
62     Creates and attach new disabled option. This option is to mark existance
63     of options inavailable due to distribution configuration.
64     @param name Name of option. It is used in command-line option name as
65       --name.
66     @param desription Description of option to be printed in --help.
67    */
68   Disabled_option* create_new_disabled_option(
69     std::string name, std::string description);
70   /**
71     Creates and attach new string option stored in char* type object.
72     @param value Pointer to char* object to receive option value.
73     @param allocated Specifies if value set should be some static string or
74       dynamically allocated string with my_strdup.
75     @param name Name of option. It is used in command line option name as
76       --name.
77     @param desription Description of option to be printed in --help.
78    */
79   Char_array_option* create_new_option(
80     char** value, std::string name, std::string description);
81   /**
82     Creates and attach new password option. It removes password from
83     command-line on UNIX systems to prevent password to be seen when listing
84     processes.
85     @param value Pointer to Nullable<string> object to receive option value.
86     @param name Name of option. It is used in command line option name as
87       --name.
88     @param desription Description of option to be printed in --help.
89    */
90   Password_option* create_new_password_option(
91     Nullable<std::string>* value, std::string name, std::string description);
92   /**
93     Creates and attach new string option.
94     @param value Pointer to Nullable<string> object to receive option value.
95     @param name Name of option. It is used in command line option name as
96       --name.
97     @param desription Description of option to be printed in --help.
98    */
99   String_option* create_new_option(
100     Nullable<std::string>* value, std::string name, std::string description);
101   /**
102     Creates and attach new 32-bit signed number option.
103     @param value Pointer to int32 object to receive option value.
104     @param name Name of option. It is used in command line option name as
105       --name.
106     @param desription Description of option to be printed in --help.
107    */
108   Number_option<int32>* create_new_option(
109     int32* value, std::string name, std::string description);
110   /**
111     Creates and attach new 32-bit unsigned number option.
112     @param value Pointer to uint32 object to receive option value.
113     @param name Name of option. It is used in command line option name as
114       --name.
115     @param desription Description of option to be printed in --help.
116    */
117   Number_option<uint32>* create_new_option(
118     uint32* value, std::string name, std::string description);
119   /**
120     Creates and attach new 64-bit signed number option.
121     @param value Pointer to int64 object to receive option value.
122     @param name Name of option. It is used in command line option name as
123       --name.
124     @param desription Description of option to be printed in --help.
125    */
126   Number_option<int64>* create_new_option(
127     int64* value, std::string name, std::string description);
128   /**
129     Creates and attach new 64-bit unsigned number option.
130     @param value Pointer to uint64 object to receive option value.
131     @param name Name of option. It is used in command line option name as
132       --name.
133     @param desription Description of option to be printed in --help.
134    */
135   Number_option<uint64>* create_new_option(
136     uint64* value, std::string name, std::string description);
137   /**
138     Creates and attach new floating-point number option.
139     @param value Pointer to double object to receive option value.
140     @param name Name of option. It is used in command line option name as
141       --name.
142     @param desription Description of option to be printed in --help.
143    */
144   Number_option<double>* create_new_option(
145     double* value, std::string name, std::string description);
146   /**
147     Creates and attach new boolean option with value received from argument.
148     @param value Pointer to double object to receive option value.
149     @param name Name of option. It is used in command line option name as
150       --name.
151     @param desription Description of option to be printed in --help.
152    */
153   Bool_option* create_new_option(
154     bool* value, std::string name, std::string description);
155 
156   template<typename T_type, typename T_typelib>
create_new_enum_option(T_type * value,const T_typelib * type,std::string name,std::string description)157     Enum_option<T_type, T_typelib>* create_new_enum_option(
158       T_type* value, const T_typelib* type, std::string name,
159       std::string description)
160   {
161     return this->attach_new_option<Enum_option<T_type, T_typelib> >(
162       new Enum_option<T_type, T_typelib>(value, type, name, description));
163   }
164 
165 
166   /**
167     Creates all options that will be provided.
168    */
169   virtual void create_options()= 0;
170 
171   /**
172     Creates list of options provided by this provider.
173     Part of I_options_provider interface implementation.
174     @returns list of my_getopt internal option data structures.
175    */
176   virtual std::vector<my_option> generate_options();
177   /**
178     Callback to be called when command-line options parsing have finished.
179     Part of I_options_provider interface implementation.
180    */
181   virtual void options_parsed();
182 
183 protected:
184   Abstract_options_provider();
185   virtual ~Abstract_options_provider();
186 
187   /**
188     Sets optional option changes listener to which all changes in all options
189     contained in this provider should be reported. This is used when this
190     provider is attached to another.
191     Part of I_options_provider interface implementation.
192    */
193   virtual void set_option_changed_listener(I_option_changed_listener* listener);
194 
195 private:
196   /**
197     Makes sure this provider will be able to watch name and optid usage.
198    */
attach_new_option(T_type * option)199   template<typename T_type> T_type* attach_new_option(T_type* option)
200   {
201     // Make this option reporting all name and optid changes to us.
202     option->set_option_changed_listener(this);
203 
204     // Add to list of our own options.
205     this->m_options_created.push_back(option);
206 
207     // Check for name and optid collision.
208     this->notify_option_name_changed(option, "");
209     this->notify_option_optid_changed(option, 0);
210 
211     return option;
212   }
213 
214   /**
215     Called after specified option has name changed.
216     It is also called when new option is added, old_name is empty string in
217     that case.
218     Part of I_option_changed_listener interface implementation.
219    */
220   virtual void notify_option_name_changed(I_option* source, std::string old_name);
221   /**
222     Called after specified option has option ID changed.
223     It is also called when new option is added, old_optid is 0 in that case.
224     Part of I_option_changed_listener interface implementation.
225    */
226   virtual void notify_option_optid_changed(I_option* source, uint32 old_optid);
227 
228   bool m_are_options_created;
229   std::map<std::string, I_option*> m_name_usage;
230   std::map<uint32, I_option*> m_optid_usage;
231   I_option_changed_listener* m_option_changed_listener;
232   std::vector<I_option*> m_options_created;
233 };
234 
235 }
236 }
237 }
238 }
239 
240 #endif
241