1 /*
2 Copyright (c) 2001, 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 #include <vector>
26 #include <iostream>
27 #include "my_getopt.h"
28 #include "abstract_options_provider.h"
29 #include "i_options_provider.h"
30
31 using std::vector;
32 using std::string;
33 using std::map;
34 using namespace Mysql::Tools::Base::Options;
35 using Mysql::Nullable;
36
37
create_new_option(string name,string description)38 Simple_option* Abstract_options_provider::create_new_option(
39 string name, string description)
40 {
41 return this->attach_new_option<Simple_option>(
42 new Simple_option(name, description));
43 }
44
create_new_disabled_option(string name,string description)45 Disabled_option* Abstract_options_provider::create_new_disabled_option(
46 string name, string description)
47 {
48 return this->attach_new_option<Disabled_option>(
49 new Disabled_option(name, description));
50 }
51
create_new_option(char ** value,string name,string description)52 Char_array_option* Abstract_options_provider::create_new_option(
53 char** value, string name, string description)
54 {
55 return this->attach_new_option<Char_array_option>(
56 new Char_array_option(value, false, name, description));
57 }
58
create_new_password_option(Nullable<string> * value,string name,string description)59 Password_option* Abstract_options_provider::create_new_password_option(
60 Nullable<string>* value, string name, string description)
61 {
62 return this->attach_new_option<Password_option>(
63 new Password_option(value, name, description));
64 }
65
create_new_option(Nullable<string> * value,string name,string description)66 String_option* Abstract_options_provider::create_new_option(
67 Nullable<string>* value, string name, string description)
68 {
69 return this->attach_new_option<String_option>(
70 new String_option(value, name, description));
71 }
72
create_new_option(int32 * value,string name,string description)73 Number_option<int32>* Abstract_options_provider::create_new_option(
74 int32* value, string name, string description)
75 {
76 return this->attach_new_option<Number_option<int32> >(
77 new Number_option<int32>(value, name, description));
78 }
79
create_new_option(uint32 * value,string name,string description)80 Number_option<uint32>* Abstract_options_provider::create_new_option(
81 uint32* value, string name, string description)
82 {
83 return this->attach_new_option<Number_option<uint32> >(
84 new Number_option<uint32>(value, name, description));
85 }
86
create_new_option(int64 * value,string name,string description)87 Number_option<int64>* Abstract_options_provider::create_new_option(
88 int64* value, string name, string description)
89 {
90 return this->attach_new_option<Number_option<int64> >(
91 new Number_option<int64>(value, name, description));
92 }
93
create_new_option(uint64 * value,string name,string description)94 Number_option<uint64>* Abstract_options_provider::create_new_option(
95 uint64* value, string name, string description)
96 {
97 return this->attach_new_option<Number_option<uint64> >(
98 new Number_option<uint64>(value, name, description));
99 }
100
create_new_option(double * value,string name,string description)101 Number_option<double>* Abstract_options_provider::create_new_option(
102 double* value, string name, string description)
103 {
104 return this->attach_new_option<Number_option<double> >(
105 new Number_option<double>(value, name, description));
106 }
107
create_new_option(bool * value,string name,string description)108 Bool_option* Abstract_options_provider::create_new_option(
109 bool* value, string name, string description)
110 {
111 return this->attach_new_option<Bool_option>(
112 new Bool_option(value, name, description));
113 }
114
115
generate_options()116 vector<my_option> Abstract_options_provider::generate_options()
117 {
118 if (this->m_are_options_created == false)
119 {
120 this->m_are_options_created= true;
121 this->create_options();
122 }
123
124 vector<my_option> res;
125 for (vector<I_option*>::iterator it= this->m_options_created.begin();
126 it != this->m_options_created.end();
127 it++)
128 {
129 res.push_back((*it)->get_my_option());
130 }
131
132 return res;
133 }
134
135
options_parsed()136 void Abstract_options_provider::options_parsed()
137 {}
138
139
Abstract_options_provider()140 Abstract_options_provider::Abstract_options_provider()
141 : m_are_options_created(false),
142 m_option_changed_listener(NULL)
143 {}
144
~Abstract_options_provider()145 Abstract_options_provider::~Abstract_options_provider()
146 {
147 for (vector<I_option*>::iterator it= this->m_options_created.begin();
148 it != this->m_options_created.end();
149 it++)
150 {
151 delete *it;
152 }
153 }
154
set_option_changed_listener(I_option_changed_listener * listener)155 void Abstract_options_provider::set_option_changed_listener(I_option_changed_listener* listener)
156 {
157 assert(this->m_option_changed_listener == NULL);
158 this->m_option_changed_listener= listener;
159 }
160
161
notify_option_name_changed(I_option * source,string old_name)162 void Abstract_options_provider::notify_option_name_changed(I_option* source,
163 string old_name)
164 {
165 // Check if it is modification or new assignment
166 if (old_name != "")
167 {
168 this->m_name_usage.erase(this->m_name_usage.find(old_name));
169 }
170
171 string new_name= source->get_my_option().name;
172
173 // Try to find existing option with that name.
174 map<string, I_option*>::iterator name_item =
175 this->m_name_usage.find(new_name);
176
177 // Report error if already used.
178 if (name_item != this->m_name_usage.end())
179 {
180 std::cerr << "Cannot register new option \"" << new_name
181 << "\" as it collides with existing one with following name \""
182 << name_item->second->get_my_option().name << "\" and description: "
183 << name_item->second->get_my_option().comment << std::endl;
184 exit(1);
185 }
186 // Add name usage.
187 this->m_name_usage.insert(std::make_pair(new_name, source));
188
189 // If we have listener we should inform it too.
190 if (this->m_option_changed_listener != NULL)
191 {
192 this->m_option_changed_listener->notify_option_name_changed(source, old_name);
193 }
194 }
195
notify_option_optid_changed(I_option * source,uint32 old_optid)196 void Abstract_options_provider::notify_option_optid_changed(I_option* source,
197 uint32 old_optid)
198 {
199 // Check if it is modification or new assignment
200 if (old_optid != 0)
201 {
202 this->m_optid_usage.erase(this->m_optid_usage.find(old_optid));
203 }
204
205 uint32 new_optid= source->get_my_option().id;
206
207 // Try to find existing option with that optid.
208 map<uint32, I_option*>::iterator optid_item =
209 this->m_optid_usage.find(new_optid);
210
211 // Report error if already used.
212 if (optid_item != this->m_optid_usage.end())
213 {
214 string name= source->get_my_option().name;
215
216 std::cerr << "Cannot register new option \"" << name
217 << "\" as it collides with existing one with following name \""
218 << optid_item->second->get_my_option().name << "\" and description: "
219 << optid_item->second->get_my_option().comment << std::endl;
220 exit(1);
221 }
222 // Add optid usage.
223 this->m_optid_usage.insert(std::make_pair(new_optid, source));
224
225 // If we have listener we should inform it too.
226 if (this->m_option_changed_listener != NULL)
227 {
228 this->m_option_changed_listener->notify_option_optid_changed(source, old_optid);
229 }
230 }
231
232