flydata 0.5.12 → 0.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +3 -0
- data/Rakefile +12 -0
- data/VERSION +1 -1
- data/ext/flydata/flydata.h +13 -0
- data/ext/flydata/json/extconf.rb +3 -0
- data/ext/flydata/json/json_ext.cpp +137 -0
- data/ext/flydata/parser/mysql/.gitignore +1 -0
- data/ext/flydata/parser/mysql/dump_parser_ext.cpp +106 -0
- data/ext/flydata/parser/mysql/extconf.rb +3 -0
- data/ext/flydata/parser/mysql/parser.txt +121 -0
- data/ext/flydata/parser/mysql/sql_parser.cpp +414 -0
- data/ext/flydata/parser/mysql/sql_parser.h +15 -0
- data/flydata-core/lib/flydata-core/mysql/command_generator.rb +20 -9
- data/flydata-core/spec/mysql/command_generator_spec.rb +17 -17
- data/flydata.gemspec +0 -0
- data/lib/flydata/command/sync.rb +78 -90
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +4 -1
- data/lib/flydata/json.rb +1 -0
- data/lib/flydata/json/.gitignore +1 -0
- data/lib/flydata/parser/mysql/.gitignore +1 -0
- data/lib/flydata/parser/mysql/dump_parser.rb +21 -5
- data/spec/flydata/command/sync_spec.rb +20 -13
- data/spec/flydata/parser/mysql/dump_parser_spec.rb +104 -0
- data/spec/flydata/sync_file_manager_spec.rb +3 -3
- data/test-suite.sh +1 -0
- metadata +38 -4
@@ -0,0 +1,414 @@
|
|
1
|
+
#include <iostream>
|
2
|
+
#include "sql_parser.h"
|
3
|
+
|
4
|
+
static int $DEBUG = 0;
|
5
|
+
|
6
|
+
enum status_t {
|
7
|
+
start,
|
8
|
+
value,
|
9
|
+
first_zero,
|
10
|
+
leading_zero,
|
11
|
+
number,
|
12
|
+
null_n,
|
13
|
+
null_u,
|
14
|
+
null_l1,
|
15
|
+
null_l2,
|
16
|
+
hex_blob,
|
17
|
+
hex_blob_number,
|
18
|
+
first_char,
|
19
|
+
following_char,
|
20
|
+
utf8_2_firstbyte,
|
21
|
+
utf8_3_firstbyte,
|
22
|
+
utf8_3_secondbyte,
|
23
|
+
utf8_3_err_secondbyte,
|
24
|
+
utf8_4_firstbyte,
|
25
|
+
utf8_4_secondbyte,
|
26
|
+
utf8_4_err_secondbyte,
|
27
|
+
utf8_4_thirdbyte,
|
28
|
+
utf8_4_err_thirdbyte,
|
29
|
+
escape,
|
30
|
+
error
|
31
|
+
};
|
32
|
+
|
33
|
+
long parse_insert_query(const char* sql, long len, ParserCallbackHandler& ch)
|
34
|
+
{
|
35
|
+
const char* current = sql;
|
36
|
+
long pos = 0;
|
37
|
+
status_t status = start;
|
38
|
+
const char* mark = 0;
|
39
|
+
const char* temp_mark = 0;
|
40
|
+
int value_len = 0;
|
41
|
+
long ret = -1; // success
|
42
|
+
|
43
|
+
for (int itor = 0; itor <= len; itor++) {
|
44
|
+
// the loop iterates through the terminate character
|
45
|
+
current = itor < len ? sql + itor : "\0";
|
46
|
+
pos++; value_len++;
|
47
|
+
switch (status) {
|
48
|
+
case start:
|
49
|
+
if (*current == '(') {
|
50
|
+
status = value;
|
51
|
+
} else {
|
52
|
+
status = start;
|
53
|
+
}
|
54
|
+
break;
|
55
|
+
|
56
|
+
case value:
|
57
|
+
if ($DEBUG) std::cout << "value[" << *current << "]: " << std::endl << std::flush;
|
58
|
+
if (*current == '\'') {
|
59
|
+
status = first_char;
|
60
|
+
} else if (*current == 'N') {
|
61
|
+
status = null_n;
|
62
|
+
} else if (*current == '0') {
|
63
|
+
mark = current; value_len = 1;//mark
|
64
|
+
status = first_zero;
|
65
|
+
} else if ( (*current >= '1' && *current <= '9') || *current == '-' ) {
|
66
|
+
mark = current; value_len = 1;//mark
|
67
|
+
status = number;
|
68
|
+
} else if (*current == ',') {
|
69
|
+
status = value;
|
70
|
+
} else if (*current == ')') {
|
71
|
+
ch.row_end_callback();//row end callback
|
72
|
+
status = start;
|
73
|
+
} else {
|
74
|
+
status = error;
|
75
|
+
}
|
76
|
+
break;
|
77
|
+
|
78
|
+
case first_zero:
|
79
|
+
if ($DEBUG) std::cout << "first_zero[" << *current << "]: " << std::endl << std::flush;
|
80
|
+
if (*current == ',') {
|
81
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback :end_value
|
82
|
+
mark = 0; value_len = 0; //mark_reset
|
83
|
+
status = value;
|
84
|
+
} else if (*current == ')') {
|
85
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback :end_value
|
86
|
+
mark = 0; value_len = 0; //mark_reset
|
87
|
+
ch.row_end_callback();//row end callback
|
88
|
+
status = start;
|
89
|
+
} else if (*current == '.') {
|
90
|
+
status = number;
|
91
|
+
} else if (*current == 'x' || *current == 'X') {
|
92
|
+
status = hex_blob;
|
93
|
+
} else if (*current == '0') {
|
94
|
+
mark = current; value_len = 1; //mark
|
95
|
+
status = leading_zero;
|
96
|
+
} else if (*current >= '1' && *current <= '9') {
|
97
|
+
mark = current; value_len = 1; //mark
|
98
|
+
status = number;
|
99
|
+
} else {
|
100
|
+
status = error;
|
101
|
+
}
|
102
|
+
break;
|
103
|
+
|
104
|
+
case leading_zero:
|
105
|
+
if ($DEBUG) std::cout << "leading_zero[" << *current << "]: " << std::endl << std::flush;
|
106
|
+
if (*current == ',') {
|
107
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback :end_value
|
108
|
+
mark = 0; value_len = 0; //mark_reset
|
109
|
+
status = value;
|
110
|
+
} else if (*current == ')') {
|
111
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback :end_value
|
112
|
+
mark = 0; value_len = 0; //mark_reset
|
113
|
+
ch.row_end_callback();//row end callback
|
114
|
+
status = start;
|
115
|
+
} else if (*current == '.') {
|
116
|
+
status = number;
|
117
|
+
} else if (*current == '0') {
|
118
|
+
mark = current; value_len = 1; //mark
|
119
|
+
status = leading_zero;
|
120
|
+
} else if (*current >= '1' && *current <= '9') {
|
121
|
+
mark = current; value_len = 1; //mark
|
122
|
+
status = number;
|
123
|
+
} else {
|
124
|
+
status = error;
|
125
|
+
}
|
126
|
+
break;
|
127
|
+
|
128
|
+
case number:
|
129
|
+
if ($DEBUG) std::cout << "number[" << *current << "]: " << std::endl << std::flush;
|
130
|
+
if ((*current >= '0' && *current <= '9') || *current == '.') {
|
131
|
+
status = number;
|
132
|
+
} else if (*current == ',') {
|
133
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback :end_value
|
134
|
+
mark = 0; value_len = 0; //mark_reset
|
135
|
+
status = value;
|
136
|
+
} else if (*current == ')') {
|
137
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback :end_value
|
138
|
+
mark = 0; value_len = 0; //mark_reset
|
139
|
+
ch.row_end_callback();//row end callback
|
140
|
+
status = start;
|
141
|
+
} else {
|
142
|
+
status = error;
|
143
|
+
}
|
144
|
+
break;
|
145
|
+
|
146
|
+
case null_n:
|
147
|
+
if ($DEBUG) std::cout << "null_n[" << *current << "]: " << std::endl << std::flush;
|
148
|
+
if (*current == 'U') {
|
149
|
+
status = null_u;
|
150
|
+
} else {
|
151
|
+
status = error;
|
152
|
+
}
|
153
|
+
break;
|
154
|
+
|
155
|
+
case null_u:
|
156
|
+
if ($DEBUG) std::cout << "null_u[" << *current << "]: " << std::endl << std::flush;
|
157
|
+
if (*current == 'L') {
|
158
|
+
status = null_l1;
|
159
|
+
} else {
|
160
|
+
status = error;
|
161
|
+
}
|
162
|
+
break;
|
163
|
+
|
164
|
+
case null_l1:
|
165
|
+
if ($DEBUG) std::cout << "null_l1[" << *current << "]: " << std::endl << std::flush;
|
166
|
+
if (*current == 'L') {
|
167
|
+
status = null_l2;
|
168
|
+
} else {
|
169
|
+
status = error;
|
170
|
+
}
|
171
|
+
break;
|
172
|
+
|
173
|
+
case null_l2:
|
174
|
+
if ($DEBUG) std::cout << "null_l2[" << *current << "]: " << std::endl << std::flush;
|
175
|
+
if (*current == ',') {
|
176
|
+
//# 0 is NULL pointer
|
177
|
+
ch.value_callback(0, 0, true);//value_callback 0 :end_value
|
178
|
+
mark = 0; value_len = 0;
|
179
|
+
status = value;
|
180
|
+
} else if (*current == ')') {
|
181
|
+
//# 0 is NULL pointer
|
182
|
+
ch.value_callback(0, 0, true);//value_callback 0, :end_value
|
183
|
+
mark = 0; value_len = 0;
|
184
|
+
ch.row_end_callback();//row end callback
|
185
|
+
status = start;
|
186
|
+
} else {
|
187
|
+
status = error;
|
188
|
+
}
|
189
|
+
break;
|
190
|
+
|
191
|
+
case hex_blob:
|
192
|
+
if ($DEBUG) std::cout << "hex_blob[" << *current << "]: " << std::endl << std::flush;
|
193
|
+
if ((*current >= '0' && *current <= '9') ||
|
194
|
+
(*current >= 'A' && *current <= 'F') ||
|
195
|
+
(*current >= 'a' && *current <= 'f')) {
|
196
|
+
status = hex_blob_number;
|
197
|
+
} else {
|
198
|
+
status = error;
|
199
|
+
}
|
200
|
+
break;
|
201
|
+
|
202
|
+
case hex_blob_number:
|
203
|
+
if ($DEBUG) std::cout << "hex_blob_number[" << *current << "]: " << std::endl << std::flush;
|
204
|
+
if ((*current >= '0' && *current <= '9') ||
|
205
|
+
(*current >= 'A' && *current <= 'F') ||
|
206
|
+
(*current >= 'a' && *current <= 'f')) {
|
207
|
+
status = hex_blob_number;
|
208
|
+
} else if (*current == ',') {
|
209
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback, :end_value
|
210
|
+
mark = 0; value_len = 0; //mark_reset
|
211
|
+
status = value;
|
212
|
+
} else if (*current == ')') {
|
213
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback, :end_value
|
214
|
+
mark = 0; value_len = 0; //mark_reset
|
215
|
+
ch.row_end_callback();//row_end_callback
|
216
|
+
status = start;
|
217
|
+
} else {
|
218
|
+
status = error;
|
219
|
+
}
|
220
|
+
break;
|
221
|
+
|
222
|
+
case first_char:
|
223
|
+
if ($DEBUG) std::cout << "first_char[" << *current << "]: " << std::endl << std::flush;
|
224
|
+
if (*current == '\'') {
|
225
|
+
mark = current; value_len = 1; //mark
|
226
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback, :end_value
|
227
|
+
mark = 0; value_len = 0; //mark_reset
|
228
|
+
status = value;
|
229
|
+
} else if (*current == '\\') {
|
230
|
+
mark = current; value_len = 1; //mark
|
231
|
+
status = escape;
|
232
|
+
} else if ((*current & 0xe0) == 0xc0) {
|
233
|
+
mark = current; value_len = 1; //mark
|
234
|
+
temp_mark = current; //temp_mark
|
235
|
+
status = utf8_2_firstbyte;
|
236
|
+
} else if ((*current & 0xf0) == 0xe0) {
|
237
|
+
mark = current; value_len = 1; //mark
|
238
|
+
temp_mark = current; //temp_mark
|
239
|
+
status = utf8_3_firstbyte;
|
240
|
+
} else if ((*current & 0xf8) == 0xf0) {
|
241
|
+
mark = current; value_len = 1; //mark
|
242
|
+
temp_mark = current; //temp_mark
|
243
|
+
status = utf8_4_firstbyte;
|
244
|
+
} else {
|
245
|
+
mark = current; value_len = 1; //mark
|
246
|
+
status = following_char;
|
247
|
+
}
|
248
|
+
break;
|
249
|
+
|
250
|
+
case utf8_2_firstbyte:
|
251
|
+
if ($DEBUG) std::cout << "utf8_2_firstbyte[" << *current << "]: " << std::endl << std::flush;
|
252
|
+
if ((*current & 0xe0) == 0x80) {
|
253
|
+
temp_mark = 0; //temp_mark reset)
|
254
|
+
status = following_char;
|
255
|
+
} else {
|
256
|
+
ch.value_callback(mark, temp_mark - mark, false);//value_callback mark...temp_mark
|
257
|
+
mark = 0; value_len = 0; //mark_reset
|
258
|
+
ch.value_callback("\xef\xbf\xbd\xef\xbf\xbd", 6, false); //value_callback "\xef\xbf\xbd\xef\xbf\xbd"
|
259
|
+
temp_mark = 0; //temp_mark reset
|
260
|
+
status = first_char;
|
261
|
+
}
|
262
|
+
break;
|
263
|
+
|
264
|
+
case utf8_3_firstbyte:
|
265
|
+
if ($DEBUG) std::cout << "utf8_3_firstbyte[" << *current << "]: " << std::endl << std::flush;
|
266
|
+
if ((*current & 0xe0) == 0x80) {
|
267
|
+
status = utf8_3_secondbyte;
|
268
|
+
} else {
|
269
|
+
status = utf8_3_err_secondbyte;
|
270
|
+
}
|
271
|
+
break;
|
272
|
+
|
273
|
+
case utf8_3_secondbyte:
|
274
|
+
if ($DEBUG) std::cout << "utf8_3_secondbyte[" << *current << "]: " << std::endl << std::flush;
|
275
|
+
if ((*current & 0xe0) == 0x80) {
|
276
|
+
temp_mark = 0; //temp_mark reset)
|
277
|
+
status = following_char;
|
278
|
+
} else {
|
279
|
+
ch.value_callback(mark, temp_mark - mark, false);//value_callback mark...temp_mark
|
280
|
+
mark = 0; value_len = 0; //mark_reset
|
281
|
+
ch.value_callback("\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd", 9, false); //value_callback "\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd"
|
282
|
+
temp_mark = 0; //temp_mark reset
|
283
|
+
status = first_char;
|
284
|
+
}
|
285
|
+
break;
|
286
|
+
|
287
|
+
case utf8_3_err_secondbyte:
|
288
|
+
if ($DEBUG) std::cout << "utf8_3_err_secondbyte[" << *current << "]: " << std::endl << std::flush;
|
289
|
+
ch.value_callback(mark, temp_mark - mark, false);//value_callback mark...temp_mark
|
290
|
+
mark = 0; value_len = 0; //mark_reset
|
291
|
+
ch.value_callback("\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd", 9, false); //value_callback "\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd"
|
292
|
+
temp_mark = 0; //temp_mark reset
|
293
|
+
status = first_char;
|
294
|
+
break;
|
295
|
+
|
296
|
+
case utf8_4_firstbyte:
|
297
|
+
if ($DEBUG) std::cout << "utf8_4_firstbyte[" << *current << "]: " << std::endl << std::flush;
|
298
|
+
if ((*current & 0xe0) == 0x80) {
|
299
|
+
status = utf8_4_secondbyte;
|
300
|
+
} else {
|
301
|
+
status = utf8_4_err_secondbyte;
|
302
|
+
}
|
303
|
+
break;
|
304
|
+
|
305
|
+
case utf8_4_secondbyte:
|
306
|
+
if ($DEBUG) std::cout << "utf8_4_secondbyte[" << *current << "]: " << std::endl << std::flush;
|
307
|
+
if ((*current & 0xe0) == 0x80) {
|
308
|
+
status = utf8_4_thirdbyte;
|
309
|
+
} else {
|
310
|
+
status = utf8_4_err_thirdbyte;
|
311
|
+
}
|
312
|
+
break;
|
313
|
+
|
314
|
+
case utf8_4_err_secondbyte:
|
315
|
+
if ($DEBUG) std::cout << "utf8_4_err_secondbyte[" << *current << "]: " << std::endl << std::flush;
|
316
|
+
status = utf8_4_err_thirdbyte;
|
317
|
+
break;
|
318
|
+
|
319
|
+
case utf8_4_thirdbyte:
|
320
|
+
if ($DEBUG) std::cout << "utf8_4_thirdbyte[" << *current << "]: " << std::endl << std::flush;
|
321
|
+
if ((*current & 0xe0) == 0x80) {
|
322
|
+
temp_mark = 0; //temp_mark reset)
|
323
|
+
status = following_char;
|
324
|
+
} else {
|
325
|
+
ch.value_callback(mark, temp_mark - mark, false);//value_callback mark...temp_mark
|
326
|
+
mark = 0; value_len = 0; //mark_reset
|
327
|
+
ch.value_callback("\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd", 12, false); //value_callback "\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd"
|
328
|
+
temp_mark = 0; //temp_mark reset
|
329
|
+
status = first_char;
|
330
|
+
}
|
331
|
+
break;
|
332
|
+
|
333
|
+
case utf8_4_err_thirdbyte:
|
334
|
+
if ($DEBUG) std::cout << "utf8_4_err_thirdbyte[" << *current << "]: " << std::endl << std::flush;
|
335
|
+
ch.value_callback(mark, temp_mark - mark, false);//value_callback mark...temp_mark
|
336
|
+
mark = 0; value_len = 0; //mark_reset
|
337
|
+
ch.value_callback("\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd", 12, false); //value_callback "\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd"
|
338
|
+
temp_mark = 0; //temp_mark reset
|
339
|
+
status = first_char;
|
340
|
+
break;
|
341
|
+
|
342
|
+
case following_char:
|
343
|
+
if ($DEBUG) std::cout << "following_char[" << *current << "]: " << std::endl << std::flush;
|
344
|
+
if (*current == '\'') {
|
345
|
+
ch.value_callback(mark, value_len - 1, true);//value_callback, :end_value
|
346
|
+
mark = 0; value_len = 0; //mark_reset
|
347
|
+
status = value;
|
348
|
+
} else if (*current == '\\') {
|
349
|
+
ch.value_callback(mark, value_len - 1, false);//value_callback
|
350
|
+
mark = current; value_len = 1;
|
351
|
+
status = escape;
|
352
|
+
} else if ((*current & 0xe0) == 0xc0) {
|
353
|
+
temp_mark = current; //temp_mark
|
354
|
+
status = utf8_2_firstbyte;
|
355
|
+
} else if ((*current & 0xf0) == 0xe0) {
|
356
|
+
temp_mark = current; //temp_mark
|
357
|
+
status = utf8_3_firstbyte;
|
358
|
+
} else if ((*current & 0xf8) == 0xf0) {
|
359
|
+
temp_mark = current; //temp_mark
|
360
|
+
status = utf8_4_firstbyte;
|
361
|
+
} else {
|
362
|
+
status = following_char;
|
363
|
+
}
|
364
|
+
break;
|
365
|
+
|
366
|
+
case escape:
|
367
|
+
if ($DEBUG) std::cout << "escape[" << *current << "]: " << std::endl << std::flush;
|
368
|
+
if (*current == '\"') {
|
369
|
+
ch.value_callback("\"", 1, false);//value_callback '\"'
|
370
|
+
mark = 0; value_len = 0;
|
371
|
+
status = first_char;
|
372
|
+
} else if (*current == '\'') {
|
373
|
+
ch.value_callback("\'", 1, false);//value_callback '\''
|
374
|
+
mark = 0; value_len = 0;
|
375
|
+
status = first_char;
|
376
|
+
} else if (*current == 'n') {
|
377
|
+
ch.value_callback("\n", 1, false);//value_callback '\n'
|
378
|
+
mark = 0; value_len = 0;
|
379
|
+
status = first_char;
|
380
|
+
} else if (*current == '\\') {
|
381
|
+
ch.value_callback("\\", 1, false);//value_callback '\\'
|
382
|
+
mark = 0; value_len = 0;
|
383
|
+
status = first_char;
|
384
|
+
} else if (*current == 'r') {
|
385
|
+
ch.value_callback("\r", 1, false);//value_callback '\r'
|
386
|
+
mark = 0; value_len = 0;
|
387
|
+
status = first_char;
|
388
|
+
} else if (*current == 'Z') {
|
389
|
+
ch.value_callback("\x1a", 1, false);//value_callback '\Z'
|
390
|
+
mark = 0; value_len = 0;
|
391
|
+
status = first_char;
|
392
|
+
} else if (*current == '0') {
|
393
|
+
ch.value_callback("\0", 1, false);//value_callback '\0'
|
394
|
+
mark = 0; value_len = 0;
|
395
|
+
status = first_char;
|
396
|
+
} else {
|
397
|
+
status = following_char;
|
398
|
+
}
|
399
|
+
break;
|
400
|
+
|
401
|
+
case error:
|
402
|
+
if ($DEBUG) std::cout << "error[" << *current << "]: " << std::endl << std::flush;
|
403
|
+
ret = pos - 1;
|
404
|
+
break;
|
405
|
+
|
406
|
+
default:
|
407
|
+
if ($DEBUG) std::cout << "default[" << *current << "]: " << std::endl << std::flush;
|
408
|
+
break;
|
409
|
+
}//switch
|
410
|
+
if (ret != -1)
|
411
|
+
break;
|
412
|
+
}//for
|
413
|
+
return ret;
|
414
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef __SQL_PARSER_H
|
2
|
+
#define __SQL_PARSER_H
|
3
|
+
|
4
|
+
class ParserCallbackHandler
|
5
|
+
{
|
6
|
+
public:
|
7
|
+
virtual void value_callback(const char* str, long len, bool end_value)=0;
|
8
|
+
virtual void row_end_callback()=0;
|
9
|
+
};
|
10
|
+
|
11
|
+
// Return: -1 if no error. Otherwise, the byte position in the string where
|
12
|
+
// a parse error occurred.
|
13
|
+
extern long parse_insert_query(const char* sql, long len, ParserCallbackHandler& ch);
|
14
|
+
|
15
|
+
#endif // __SQL_PARSER_H
|
@@ -1,10 +1,21 @@
|
|
1
1
|
require 'open3'
|
2
|
+
require 'shellwords'
|
2
3
|
require 'flydata-core/table_def/mysql_table_def'
|
3
4
|
|
4
5
|
module FlydataCore
|
5
6
|
module Mysql
|
6
7
|
class CommandGenerator
|
7
|
-
|
8
|
+
DEFAULT_OPTION = "--default-character-set=utf8 --protocol=tcp"
|
9
|
+
DEFAULT_MYSQL_OPTION = "#{DEFAULT_OPTION} --skip-auto-rehash"
|
10
|
+
|
11
|
+
def self.default_cmd_option(command)
|
12
|
+
case command
|
13
|
+
when 'mysql'
|
14
|
+
DEFAULT_MYSQL_OPTION
|
15
|
+
else #mysqldump
|
16
|
+
DEFAULT_OPTION
|
17
|
+
end
|
18
|
+
end
|
8
19
|
|
9
20
|
# Generate mysql/mysqldump command with options
|
10
21
|
# options must be hash
|
@@ -21,21 +32,21 @@ module FlydataCore
|
|
21
32
|
raise ArgumentError.new("option must be hash.") unless option.kind_of?(Hash)
|
22
33
|
option = convert_keys_to_sym(option)
|
23
34
|
command = option[:command] ? option[:command] : 'mysql'
|
24
|
-
host = option[:host] ? "-h #{option[:host]}" : nil
|
25
|
-
port = option[:port] ? "-P #{option[:port]}" : nil
|
26
|
-
username = option[:username] ? "-u#{option[:username]}" : nil
|
35
|
+
host = option[:host] ? "-h #{option[:host].shellescape}" : nil
|
36
|
+
port = option[:port] ? "-P #{option[:port].to_s.shellescape}" : nil
|
37
|
+
username = option[:username] ? "-u#{option[:username].shellescape}" : nil
|
27
38
|
password = if !(option[:password].to_s.empty?)
|
28
|
-
"-p
|
39
|
+
"-p#{option[:password].shellescape}"
|
29
40
|
else
|
30
41
|
nil
|
31
42
|
end
|
32
|
-
database = option[:database]
|
33
|
-
tables = option[:tables] ? option[:tables].join(' ') : nil
|
43
|
+
database = option[:database].shellescape if option[:database]
|
44
|
+
tables = option[:tables] ? option[:tables].collect{|t| t.shellescape}.join(' ') : nil
|
34
45
|
ssl_ca = option[:ssl_ca] ? option[:ssl_ca] : nil
|
35
46
|
ssl_cipher = option[:ssl_cipher] ? option[:ssl_cipher] : nil
|
36
47
|
|
37
|
-
default_option = option[:no_default_option] ? "" :
|
38
|
-
default_option += " --ssl-ca
|
48
|
+
default_option = option[:no_default_option] ? "" : default_cmd_option(command)
|
49
|
+
default_option += " --ssl-ca #{ssl_ca}" if ssl_ca
|
39
50
|
default_option += " --ssl-cipher=#{ssl_cipher}" unless ssl_cipher.to_s.empty?
|
40
51
|
default_option = nil if default_option == ''
|
41
52
|
|