1 | |
2 | // vim:sw=2:ai |
3 | |
4 | /* |
5 | * Copyright (C) 2010-2011 DeNA Co.,Ltd.. All rights reserved. |
6 | * Copyright (C) 2011-2017 Kentoku SHIBA |
7 | * See COPYRIGHT.txt for details. |
8 | */ |
9 | |
10 | #include <my_global.h> |
11 | #include "mysql_version.h" |
12 | #if MYSQL_VERSION_ID < 50500 |
13 | #include "mysql_priv.h" |
14 | #include <mysql/plugin.h> |
15 | #else |
16 | #include "sql_priv.h" |
17 | #include "probes_mysql.h" |
18 | #endif |
19 | |
20 | #include "config.hpp" |
21 | |
22 | namespace dena { |
23 | |
24 | unsigned int verbose_level = 0; |
25 | |
26 | uchar * |
27 | conf_get_key( |
28 | conf_param *param, |
29 | size_t *length, |
30 | my_bool not_used __attribute__ ((unused)) |
31 | ) { |
32 | *length = param->key.length(); |
33 | return (uchar*) param->key.ptr(); |
34 | } |
35 | |
36 | config::config() |
37 | { |
38 | if (my_hash_init(&conf_hash, &my_charset_bin, 32, 0, 0, |
39 | (my_hash_get_key) conf_get_key, 0, 0)) |
40 | init = FALSE; |
41 | else |
42 | init = TRUE; |
43 | return; |
44 | } |
45 | |
46 | config::~config() |
47 | { |
48 | if (init) |
49 | { |
50 | conf_param *param; |
51 | while ((param = (conf_param *) my_hash_element(&conf_hash, 0))) |
52 | { |
53 | my_hash_delete(&conf_hash, (uchar*) param); |
54 | delete param; |
55 | } |
56 | my_hash_free(&conf_hash); |
57 | } |
58 | } |
59 | |
60 | conf_param * |
61 | config::find(const String& key) const |
62 | { |
63 | if (init) |
64 | return (conf_param *) my_hash_search(&conf_hash, (const uchar*) key.ptr(), |
65 | key.length()); |
66 | else |
67 | return NULL; |
68 | } |
69 | |
70 | conf_param * |
71 | config::find(const char *key) const |
72 | { |
73 | if (init) |
74 | return (conf_param *) my_hash_search(&conf_hash, (const uchar*) key, |
75 | strlen(key)); |
76 | else |
77 | return NULL; |
78 | } |
79 | |
80 | String |
81 | config::get_str(const String& key, const String& def) const |
82 | { |
83 | DENA_VERBOSE(30, list_all_params()); |
84 | conf_param *param = find(key); |
85 | if (!param) { |
86 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(default)\n" , key.ptr(), |
87 | def.ptr())); |
88 | return def; |
89 | } |
90 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n" , key.ptr(), |
91 | param->val.ptr())); |
92 | return param->val; |
93 | } |
94 | |
95 | String |
96 | config::get_str(const char *key, const char *def) const |
97 | { |
98 | DENA_VERBOSE(30, list_all_params()); |
99 | conf_param *param = find(key); |
100 | if (!param) { |
101 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(default)\n" , key, def)); |
102 | return String(def, strlen(def), &my_charset_bin); |
103 | } |
104 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n" , |
105 | key, param->val.ptr())); |
106 | return param->val; |
107 | } |
108 | |
109 | long long |
110 | config::get_int(const String& key, long long def) const |
111 | { |
112 | int err; |
113 | DENA_VERBOSE(30, list_all_params()); |
114 | conf_param *param = find(key); |
115 | if (!param) { |
116 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(default)\n" , key.ptr(), |
117 | def)); |
118 | return def; |
119 | } |
120 | const long long r = my_strtoll10(param->val.ptr(), (char**) NULL, &err); |
121 | if (err) { |
122 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(err)\n" , key.ptr(), |
123 | def)); |
124 | return def; |
125 | } |
126 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld\n" , key.ptr(), r)); |
127 | return r; |
128 | } |
129 | |
130 | long long |
131 | config::get_int(const char *key, long long def) const |
132 | { |
133 | int err; |
134 | DENA_VERBOSE(30, list_all_params()); |
135 | conf_param *param = find(key); |
136 | if (!param) { |
137 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(default)\n" , key, def)); |
138 | return def; |
139 | } |
140 | const long long r = my_strtoll10(param->val.ptr(), (char**) NULL, &err); |
141 | if (err) { |
142 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld(err)\n" , key, def)); |
143 | return def; |
144 | } |
145 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%lld\n" , key, r)); |
146 | return r; |
147 | } |
148 | |
149 | bool |
150 | config::replace(const char *key, const char *val) |
151 | { |
152 | uint32 val_len = strlen(val); |
153 | conf_param *param = find(key); |
154 | if (!param) { |
155 | /* create */ |
156 | if (!(param = new conf_param())) |
157 | return TRUE; |
158 | uint32 key_len = strlen(key); |
159 | if ( |
160 | param->key.reserve(key_len + 1) || |
161 | param->val.reserve(val_len + 1) |
162 | ) { |
163 | delete param; |
164 | return TRUE; |
165 | } |
166 | param->key.q_append(key, key_len); |
167 | param->val.q_append(val, val_len); |
168 | param->key.c_ptr_safe(); |
169 | param->val.c_ptr_safe(); |
170 | if (my_hash_insert(&conf_hash, (uchar*) param)) |
171 | { |
172 | delete param; |
173 | return TRUE; |
174 | } |
175 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(create)\n" , |
176 | param->key.ptr(), param->val.ptr())); |
177 | return FALSE; |
178 | } |
179 | /* replace */ |
180 | param->val.length(0); |
181 | if (param->val.reserve(val_len + 1)) |
182 | return TRUE; |
183 | param->val.q_append(val, val_len); |
184 | param->val.c_ptr_safe(); |
185 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s(replace)\n" , |
186 | param->key.ptr(), param->val.ptr())); |
187 | return FALSE; |
188 | } |
189 | |
190 | bool |
191 | config::replace(const char *key, long long val) |
192 | { |
193 | char val_str[22]; |
194 | sprintf(val_str, "%lld" , val); |
195 | return replace(key, val_str); |
196 | } |
197 | |
198 | bool |
199 | config::compare(const char *key, const char *val) |
200 | { |
201 | conf_param *param = find(key); |
202 | if (!param) |
203 | return FALSE; |
204 | return !strcmp(param->val.ptr(), val); |
205 | } |
206 | |
207 | void |
208 | config::list_all_params() const |
209 | { |
210 | conf_param *param; |
211 | DENA_VERBOSE(10, fprintf(stderr, "list_all_params start\n" )); |
212 | for(ulong i = 0; i < conf_hash.records; i++) |
213 | { |
214 | if ((param = (conf_param *) my_hash_element((HASH *) &conf_hash, i))) |
215 | { |
216 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n" , |
217 | param->key.ptr(), param->val.ptr())); |
218 | } |
219 | } |
220 | DENA_VERBOSE(10, fprintf(stderr, "list_all_params end\n" )); |
221 | } |
222 | |
223 | config& |
224 | config::operator =(const config& x) |
225 | { |
226 | DENA_VERBOSE(10, fprintf(stderr, "config operator = start" )); |
227 | if (this != &x && init && x.init) { |
228 | conf_param *param, *new_param; |
229 | for(ulong i = 0; i < x.conf_hash.records; i++) |
230 | { |
231 | if ( |
232 | (param = (conf_param *) my_hash_element((HASH *) &x.conf_hash, i)) && |
233 | (new_param = new conf_param()) |
234 | ) { |
235 | if ( |
236 | !new_param->key.copy(param->key) && |
237 | !new_param->val.copy(param->val) |
238 | ) { |
239 | new_param->key.c_ptr_safe(); |
240 | new_param->val.c_ptr_safe(); |
241 | DENA_VERBOSE(10, fprintf(stderr, "CONFIG: %s=%s\n" , |
242 | new_param->key.ptr(), new_param->val.ptr())); |
243 | if (my_hash_insert(&conf_hash, (uchar*) new_param)) |
244 | delete new_param; |
245 | } else |
246 | delete new_param; |
247 | } |
248 | } |
249 | } |
250 | DENA_VERBOSE(10, fprintf(stderr, "config operator = end %p" , this)); |
251 | return *this; |
252 | } |
253 | |
254 | void |
255 | parse_args(int argc, char **argv, config& conf) |
256 | { |
257 | conf_param *param; |
258 | for (int i = 1; i < argc; ++i) { |
259 | const char *const arg = argv[i]; |
260 | const char *const eq = strchr(arg, '='); |
261 | if (eq == 0) { |
262 | continue; |
263 | } |
264 | if (!(param = new conf_param())) |
265 | continue; |
266 | uint32 key_len = (uint32)(eq - arg); |
267 | uint32 val_len = strlen(eq + 1); |
268 | if ( |
269 | param->key.reserve(key_len + 1) || |
270 | param->val.reserve(val_len + 1) |
271 | ) { |
272 | delete param; |
273 | continue; |
274 | } |
275 | param->key.q_append(arg, key_len); |
276 | param->val.q_append(eq + 1, val_len); |
277 | param->key.c_ptr_safe(); |
278 | param->val.c_ptr_safe(); |
279 | if (my_hash_insert(&conf.conf_hash, (uchar*) param)) |
280 | { |
281 | delete param; |
282 | continue; |
283 | } |
284 | } |
285 | param = conf.find("verbose" ); |
286 | if (param) { |
287 | verbose_level = atoi(param->val.c_ptr()); |
288 | } |
289 | } |
290 | |
291 | }; |
292 | |
293 | |