78
67
#define IGNORE_DATA 0x01 /* don't dump data for this table */
79
68
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
81
bool opt_alltspcs= false;
82
bool opt_complete_insert= false;
84
static bool use_drizzle_protocol= false;
85
bool ignore_errors= false;
86
static bool flush_logs= false;
87
static bool create_options= true;
88
static bool opt_quoted= false;
89
bool opt_databases= false;
90
bool opt_alldbs= false;
91
static bool opt_lock_all_tables= false;
92
static bool opt_dump_date= true;
93
bool opt_autocommit= false;
94
static bool opt_single_transaction= false;
95
static bool opt_comments;
96
static bool opt_compact;
97
bool opt_ignore= false;
98
bool opt_drop_database;
99
bool opt_no_create_info;
100
bool opt_no_data= false;
101
bool opt_create_db= false;
102
bool opt_disable_keys= true;
103
bool extended_insert= true;
104
bool opt_replace_into= false;
106
uint32_t show_progress_size= 0;
70
static void add_load_option(string &str, const char *option,
71
const char *option_value);
72
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
73
char **err_pos, uint32_t *err_len);
75
static void field_escape(string &in, const char *from);
76
static bool verbose= false, opt_no_create_info= false, opt_no_data= false,
77
quick= true, extended_insert= true,
78
lock_tables= true, ignore_errors= false, flush_logs= false,
79
opt_drop= true, opt_keywords= false,
80
opt_lock= true, opt_compress= false,
81
opt_delayed= false, create_options= true, opt_quoted= false,
82
opt_databases= false, opt_alldbs= false, opt_create_db= false,
83
opt_lock_all_tables= false,
84
opt_set_charset= false, opt_dump_date= true,
85
opt_autocommit= false, opt_disable_keys= true, opt_xml= false,
86
opt_delete_master_logs= false, tty_password= false,
87
opt_single_transaction= false, opt_comments= false,
88
opt_compact= false, opt_hex_blob= false,
89
opt_order_by_primary=false, opt_ignore= false,
90
opt_complete_insert= false, opt_drop_database= false,
91
opt_replace_into= false,
93
opt_slave_apply= false,
94
opt_include_master_host_port= false,
96
static bool debug_info_flag= false, debug_check_flag= false;
97
static uint32_t opt_max_allowed_packet, opt_net_buffer_length, show_progress_size= 0;
98
static uint64_t total_rows= 0;
99
static DRIZZLE drizzleclient_connection, *drizzle= 0;
107
100
static string insert_pat;
101
static char *opt_password= NULL, *current_user= NULL,
102
*current_host= NULL, *path= NULL, *fields_terminated= NULL,
103
*lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
105
*where= NULL, *order_by= NULL,
106
*opt_compatible_mode_str= NULL,
108
static char **defaults_argv= NULL;
109
static char compatible_mode_normal_str[255];
110
static uint32_t opt_compatible_mode= 0;
111
#define DRIZZLE_OPT_MASTER_DATA_EFFECTIVE_SQL 1
112
#define DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL 2
113
#define DRIZZLE_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
114
#define DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL 2
108
115
static uint32_t opt_drizzle_port= 0;
116
static uint32_t opt_master_data;
117
static uint32_t opt_slave_data;
118
static uint32_t my_end_arg;
109
119
static int first_error= 0;
110
120
static string extended_row;
111
121
FILE *md_result_file= 0;
112
122
FILE *stderror_file= 0;
113
std::vector<DrizzleDumpDatabase*> database_store;
114
DrizzleDumpConnection* db_connection;
115
DrizzleDumpConnection* destination_connection;
123
int opt_destination= DESTINATION_STDOUT;
124
std::string opt_destination_host;
125
uint16_t opt_destination_port;
126
std::string opt_destination_user;
127
std::string opt_destination_password;
128
std::string opt_destination_database;
130
const string progname= "drizzledump";
142
//static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
144
boost::unordered_set<string> ignore_table;
146
void maybe_exit(int error);
125
Constant for detection of default value of default_charset.
126
If default_charset is equal to drizzle_universal_client_charset, then
127
it is the default value which assigned at the very beginning of main().
129
static const char *drizzle_universal_client_charset=
130
DRIZZLE_UNIVERSAL_CLIENT_CHARSET;
131
static char *default_charset;
132
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
133
const char *default_dbug_option="d:t:o,/tmp/drizzledump.trace";
134
const char *compatible_mode_names[]=
136
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
137
"MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
141
#define MASK_ANSI_QUOTES \
143
(1<<2) | /* POSTGRESQL */\
144
(1<<3) | /* ORACLE */\
145
(1<<4) | /* MSSQL */\
147
(1<<6) | /* MAXDB */\
150
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
151
"", compatible_mode_names, NULL};
155
static struct my_option my_long_options[] =
157
{"all", 'a', "Deprecated. Use --create-options instead.",
158
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
160
{"all-databases", 'A',
161
"Dump all the databases. This will be same as --databases with all databases selected.",
162
(char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
164
{"all-tablespaces", 'Y',
165
"Dump all the tablespaces.",
166
(char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
168
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
169
(char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
171
{"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
172
(char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
174
{"add-locks", OPT_LOCKS, "Add locks around insert statements.",
175
(char**) &opt_lock, (char**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
177
{"allow-keywords", OPT_KEYWORDS,
178
"Allow creation of column names that are keywords.", (char**) &opt_keywords,
179
(char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
180
{"apply-slave-statements", OPT_DRIZZLEDUMP_SLAVE_APPLY,
181
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
182
(char**) &opt_slave_apply, (char**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
184
{"comments", 'i', "Write additional information.",
185
(char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
187
{"compatible", OPT_COMPATIBLE,
188
"Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MySQL. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires DRIZZLE server version 4.1.0 or higher. This option is ignored with earlier server versions.",
189
(char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
190
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
191
{"compact", OPT_COMPACT,
192
"Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-add-locks",
193
(char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
195
{"complete-insert", 'c', "Use complete insert statements.",
196
(char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
197
NO_ARG, 0, 0, 0, 0, 0, 0},
198
{"compress", 'C', "Use compression in server/client protocol.",
199
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
201
{"create-options", OPT_CREATE_OPTIONS,
202
"Include all DRIZZLE specific create options.",
203
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
206
"To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.",
207
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
209
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
210
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
211
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
212
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
213
(char**) &debug_info_flag, (char**) &debug_info_flag,
214
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
215
{"default-character-set", OPT_DEFAULT_CHARSET,
216
"Set the default character set.", (char**) &default_charset,
217
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
218
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
219
(char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
221
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
222
"Delete logs on master after backup. This automatically enables --master-data.",
223
(char**) &opt_delete_master_logs, (char**) &opt_delete_master_logs, 0,
224
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
225
{"disable-keys", 'K',
226
"'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.", (char**) &opt_disable_keys,
227
(char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
228
{"dump-slave", OPT_DRIZZLEDUMP_SLAVE_DATA,
229
"This causes the binary log position and filename of the master to be "
230
"appended to the dumped data output. Setting the value to 1, will print"
231
"it as a CHANGE MASTER command in the dumped data output; if equal"
232
" to 2, that command will be prefixed with a comment symbol. "
233
"This option will turn --lock-all-tables on, unless "
234
"--single-transaction is specified too (in which case a "
235
"global read lock is only taken a short time at the beginning of the dump "
236
"- don't forget to read about --single-transaction below). In all cases "
237
"any action on logs will happen at the exact moment of the dump."
238
"Option automatically turns --lock-tables off.",
239
(char**) &opt_slave_data, (char**) &opt_slave_data, 0,
240
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
241
{"extended-insert", 'e',
242
"Allows utilization of the new, much faster INSERT syntax.",
243
(char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
245
{"fields-terminated-by", OPT_FTB,
246
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
247
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
248
{"fields-enclosed-by", OPT_ENC,
249
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
250
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
251
{"fields-optionally-enclosed-by", OPT_O_ENC,
252
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
253
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
254
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
255
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
256
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
257
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
259
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
260
"Note that if you dump many databases at once (using the option "
261
"--databases= or --all-databases), the logs will be flushed for "
262
"each database dumped. The exception is when using --lock-all-tables "
264
"in this case the logs will be flushed only once, corresponding "
265
"to the moment all tables are locked. So if you want your dump and "
266
"the log flush to happen at the same exact moment you should use "
267
"--lock-all-tables or --master-data with --flush-logs",
268
(char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
270
{"force", 'f', "Continue even if we get an sql-error.",
271
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
273
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
274
NO_ARG, 0, 0, 0, 0, 0, 0},
275
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
276
"VARBINARY, BLOB) in hexadecimal format.",
277
(char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
278
{"host", 'h', "Connect to host.", (char**) ¤t_host,
279
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
280
{"ignore-table", OPT_IGNORE_TABLE,
281
"Do not dump the specified table. To specify more than one table to ignore, "
282
"use the directive multiple times, once for each table. Each table must "
283
"be specified with both database and table names, e.g. --ignore-table=database.table",
284
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
285
{"include-master-host-port", OPT_DRIZZLEDUMP_INCLUDE_MASTER_HOST_PORT,
286
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
287
(char**) &opt_include_master_host_port,
288
(char**) &opt_include_master_host_port,
291
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
292
(char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
294
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
295
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
296
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
297
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
298
"is achieved by taking a global read lock for the duration of the whole "
299
"dump. Automatically turns --single-transaction and --lock-tables off.",
300
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
302
{"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
303
(char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
304
{"master-data", OPT_MASTER_DATA,
305
"This causes the binary log position and filename to be appended to the "
306
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
307
" to 2, that command will be prefixed with a comment symbol. "
308
"This option will turn --lock-all-tables on, unless "
309
"--single-transaction is specified too (in which case a "
310
"global read lock is only taken a short time at the beginning of the dump "
311
"- don't forget to read about --single-transaction below). In all cases "
312
"any action on logs will happen at the exact moment of the dump."
313
"Option automatically turns --lock-tables off.",
314
(char**) &opt_master_data, (char**) &opt_master_data, 0,
315
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
316
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
317
(char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
318
GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
319
(int64_t) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
320
{"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
321
(char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0,
322
GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
323
MALLOC_OVERHEAD-1024, 1024, 0},
324
{"no-autocommit", OPT_AUTOCOMMIT,
325
"Wrap tables with autocommit/commit statements.",
326
(char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
328
{"no-create-db", 'n',
329
"'CREATE DATABASE IF NOT EXISTS db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}.",
330
(char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
332
{"no-create-info", 't', "Don't write table creation info.",
333
(char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
334
NO_ARG, 0, 0, 0, 0, 0, 0},
335
{"no-data", 'd', "No row information.", (char**) &opt_no_data,
336
(char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
337
{"no-set-names", 'N',
338
"Deprecated. Use --skip-set-charset instead.",
339
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
340
{"opt", OPT_OPTIMIZE,
341
"Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.",
342
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
343
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
344
"Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.",
345
(char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
347
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
348
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
349
{"port", 'p', "Port number to use for connection.",
350
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
351
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
352
(char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
353
{"quote-names",'Q', "Quote table and column names with backticks (`).",
354
(char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
356
{"replace", OPT_DRIZZLE_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
357
(char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
360
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
361
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
362
{"routines", 'R', "Dump stored routines (functions and procedures).",
363
(char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
364
NO_ARG, 0, 0, 0, 0, 0, 0},
366
Note that the combination --single-transaction --master-data
367
will give bullet-proof binlog position only if server >=4.1.3. That's the
368
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
370
{"single-transaction", OPT_TRANSACTION,
371
"Creates a consistent snapshot by dumping all tables in a single "
372
"transaction. Works ONLY for tables stored in storage engines which "
373
"support multiversioning (currently only InnoDB does); the dump is NOT "
374
"guaranteed to be consistent for other storage engines. "
375
"While a --single-transaction dump is in process, to ensure a valid "
376
"dump file (correct table contents and binary log position), no other "
377
"connection should use the following statements: ALTER TABLE, DROP "
378
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
379
"isolated from them. Option automatically turns off --lock-tables.",
380
(char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
381
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
382
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
383
(char**) &opt_dump_date, (char**) &opt_dump_date, 0,
384
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
385
{"skip-opt", OPT_SKIP_OPTIMIZATION,
386
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
387
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
389
"Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
390
(char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
391
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
392
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
393
{"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of rows before each output progress report (requires --verbose)."),
394
(char**) &show_progress_size, (char**) &show_progress_size, 0, GET_ULONG, REQUIRED_ARG,
395
10000, 0, 0, 0, 0, 0},
396
#ifndef DONT_ALLOW_USER_CHANGE
397
{"user", 'u', "User for login if not current user.",
398
(char**) ¤t_user, (char**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
401
{"verbose", 'v', "Print info about the various stages.",
402
(char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
403
{"version",'V', "Output version information and exit.", 0, 0, 0,
404
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
405
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
406
(char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
407
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
408
NO_ARG, 0, 0, 0, 0, 0, 0},
409
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
412
static const char *load_default_groups[]= { "drizzledump","client",0 };
414
static void maybe_exit(int error);
147
415
static void die(int error, const char* reason, ...);
148
static void write_header(char *db_name);
149
static int dump_selected_tables(const string &db, const vector<string> &table_names);
150
static int dump_databases(const vector<string> &db_names);
416
static void maybe_die(int error, const char* reason, ...);
417
static void write_header(FILE *sql_file, char *db_name);
418
static void print_value(FILE *file, DRIZZLE_RES *result, DRIZZLE_ROW row,
419
const char *prefix,const char *name,
421
static const char* fetch_named_row(DRIZZLE_RES *result, DRIZZLE_ROW row, const char* name);
422
static int dump_selected_tables(char *db, char **table_names, int tables);
423
static int dump_all_tables_in_db(char *db);
424
static int init_dumping_tables(char *);
425
static int init_dumping(char *, int init_func(char*));
426
static int dump_databases(char **);
151
427
static int dump_all_databases(void);
152
int get_server_type();
153
void dump_all_tables(void);
154
void generate_dump(void);
155
void generate_dump_db(void);
157
void dump_all_tables(void)
159
std::vector<DrizzleDumpDatabase*>::iterator i;
160
for (i= database_store.begin(); i != database_store.end(); ++i)
162
if ((not (*i)->populateTables()) && (not ignore_errors))
163
maybe_exit(EX_DRIZZLEERR);
167
void generate_dump(void)
169
std::vector<DrizzleDumpDatabase*>::iterator i;
173
cout << endl << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;"
174
<< endl << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
178
cout << "SET AUTOCOMMIT=0;" << endl;
180
for (i= database_store.begin(); i != database_store.end(); ++i)
182
DrizzleDumpDatabase *database= *i;
188
cout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;"
189
<< endl << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
193
void generate_dump_db(void)
195
std::vector<DrizzleDumpDatabase*>::iterator i;
196
DrizzleStringBuf sbuf(1024);
199
destination_connection= new DrizzleDumpConnection(opt_destination_host,
200
opt_destination_port, opt_destination_user, opt_destination_password,
203
catch (std::exception&)
205
cerr << "Could not connect to destination database server" << endl;
206
maybe_exit(EX_DRIZZLEERR);
208
sbuf.setConnection(destination_connection);
209
std::ostream sout(&sbuf);
210
sout.exceptions(ios_base::badbit);
214
sout << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;" << endl;
215
sout << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
219
cout << "SET AUTOCOMMIT=0;" << endl;
221
for (i= database_store.begin(); i != database_store.end(); ++i)
225
DrizzleDumpDatabase *database= *i;
228
catch (std::exception&)
230
std::cout << _("Error inserting into destination database") << std::endl;
231
if (not ignore_errors)
232
maybe_exit(EX_DRIZZLEERR);
238
sout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;" << endl;
239
sout << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
428
static char *quote_name(const char *name, char *buff, bool force);
429
char check_if_ignore_table(const char *table_name, char *table_type);
430
static char *primary_key_fields(const char *table_name);
433
Print the supplied message if in verbose mode
438
... variable number of parameters
440
static void verbose_msg(const char *fmt, ...)
449
vfprintf(stderr, fmt, args);
244
456
exit with message if ferror(file)
251
463
static void check_io(FILE *file)
335
889
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
338
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
892
fprintf(stderr, "%s: %s\n", my_progname, buffer);
341
895
ignore_errors= 0; /* force the exit */
342
896
maybe_exit(error_num);
901
Prints out an error message and maybe kills the process.
905
error_num - process return value
906
fmt_reason - a format string for use by vsnprintf.
907
... - variable arguments for above fmt_reason string
910
This call prints out the formatted error message to stderr and then
911
terminates the process, unless the --force command line option is used.
913
This call should be used for non-fatal errors (such as database
914
errors) that the code may still be able to continue to the next unit
918
static void maybe_die(int error_num, const char* fmt_reason, ...)
922
va_start(args,fmt_reason);
923
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
926
fprintf(stderr, "%s: %s\n", my_progname, buffer);
929
maybe_exit(error_num);
935
Sends a query to server, optionally reads result, prints error message if
939
drizzleclient_query_with_error_report()
940
drizzle_con connection to use
941
res if non zero, result will be put there with
942
drizzleclient_store_result()
943
query query to send to server
946
0 query sending and (if res!=0) result reading went ok
950
static int drizzleclient_query_with_error_report(DRIZZLE *drizzle_con, DRIZZLE_RES **res,
953
if (drizzleclient_query(drizzle_con, query) ||
954
(res && !((*res)= drizzleclient_store_result(drizzle_con))))
956
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
957
query, drizzleclient_error(drizzle_con), drizzleclient_errno(drizzle_con));
964
Open a new .sql file to dump the table or view into
967
open_sql_file_for_table
968
name name of the table or view
971
0 Failed to open file
972
> 0 Handle of the open file
974
static FILE* open_sql_file_for_table(const char* table)
977
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
978
convert_dirname(tmp_path,path,NULL);
979
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
980
O_WRONLY, MYF(MY_WME));
345
985
static void free_resources(void)
347
987
if (md_result_file && md_result_file != stdout)
348
fclose(md_result_file);
349
opt_password.erase();
988
my_fclose(md_result_file, MYF(0));
990
if (hash_inited(&ignore_table))
991
hash_free(&ignore_table);
993
free_defaults(defaults_argv);
353
void maybe_exit(int error)
998
static void maybe_exit(int error)
355
1000
if (!first_error)
356
1001
first_error= error;
357
1002
if (ignore_errors)
359
delete db_connection;
360
delete destination_connection;
1005
drizzleclient_close(drizzle);
361
1006
free_resources();
1012
db_connect -- connects to the host and selects DB.
1015
static int connect_to_db(char *host, char *user,char *passwd)
1017
verbose_msg(_("-- Connecting to %s...\n"), host ? host : "localhost");
1018
drizzleclient_create(&drizzleclient_connection);
1020
drizzleclient_options(&drizzleclient_connection,DRIZZLE_OPT_COMPRESS,NULL);
1021
if (!(drizzle= drizzleclient_connect(&drizzleclient_connection,host,user,passwd,
1022
NULL,opt_drizzle_port, NULL,
1025
DB_error(&drizzleclient_connection, "when trying to connect");
1030
} /* connect_to_db */
1034
** dbDisconnect -- disconnects from the host.
1036
static void dbDisconnect(char *host)
1038
verbose_msg(_("-- Disconnecting from %s...\n"), host ? host : "localhost");
1039
drizzleclient_close(drizzle);
1040
} /* dbDisconnect */
1043
static void unescape(FILE *file,char *pos,uint32_t length)
1047
if (!(tmp=(char*) malloc(length*2+1)))
1048
die(EX_DRIZZLEERR, _("Couldn't allocate memory"));
1050
drizzleclient_escape_string(tmp, pos, length);
1060
static bool test_if_special_chars(const char *str)
1062
for ( ; *str ; str++)
1063
if (!my_isvar(charset_info,*str) && *str != '$')
1066
} /* test_if_special_chars */
1071
quote_name(name, buff, force)
1073
Quotes char string, taking into account compatible mode
1077
name Unquoted string containing that which will be quoted
1078
buff The buffer that contains the quoted value, also returned
1079
force Flag to make it ignore 'test_if_special_chars'
1086
static char *quote_name(const char *name, char *buff, bool force)
1089
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1091
if (!force && !opt_quoted && !test_if_special_chars(name))
1092
return (char*) name;
1107
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1111
name name of the table
1112
buff quoted name of the table
1115
Quote \, _, ' and % characters
1117
Note: Because DRIZZLE uses the C escape syntax in strings
1118
(for example, '\n' to represent newline), you must double
1119
any '\' that you use in your LIKE strings. For example, to
1120
search for '\n', specify it as '\\n'. To search for '\', specify
1121
it as '\\\\' (the backslashes are stripped once by the parser
1122
and another time when the pattern match is done, leaving a
1123
single backslash to be matched).
1125
Example: "t\1" => "t\\\\1"
1128
static char *quote_for_like(const char *name, char *buff)
1140
else if (*name == '\'' || *name == '_' || *name == '%')
1151
Quote and print a string.
1155
xml_file - output file
1156
str - string to print
1160
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1163
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
1167
for (end= str + len; str != end; str++)
1171
fputs("<", xml_file);
1174
fputs(">", xml_file);
1177
fputs("&", xml_file);
1180
fputs(""", xml_file);
1183
fputc(*str, xml_file);
1192
Print xml tag. Optionally add attribute(s).
1195
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1196
..., attribute_name_n, attribute_value_n, NULL)
1197
xml_file - output file
1198
sbeg - line beginning
1199
line_end - line ending
1200
tag_name - XML tag name.
1201
first_attribute_name - tag and first attribute
1202
first_attribute_value - (Implied) value of first attribute
1203
attribute_name_n - attribute n
1204
attribute_value_n - value of attribute n
1207
Print XML tag with any number of attribute="value" pairs to the xml_file.
1210
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1211
attribute_name_n="attribute_value_n">send
1213
Additional arguments must be present in attribute/value pairs.
1214
The last argument should be the null character pointer.
1215
All attribute_value arguments MUST be NULL terminated strings.
1216
All attribute_value arguments will be quoted before output.
1219
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1220
const char* line_end,
1221
const char* tag_name,
1222
const char* first_attribute_name, ...)
1225
const char *attribute_name, *attribute_value;
1227
fputs(sbeg, xml_file);
1228
fputc('<', xml_file);
1229
fputs(tag_name, xml_file);
1231
va_start(arg_list, first_attribute_name);
1232
attribute_name= first_attribute_name;
1233
while (attribute_name != NULL)
1235
attribute_value= va_arg(arg_list, char *);
1236
assert(attribute_value != NULL);
1238
fputc(' ', xml_file);
1239
fputs(attribute_name, xml_file);
1240
fputc('\"', xml_file);
1242
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1243
fputc('\"', xml_file);
1245
attribute_name= va_arg(arg_list, char *);
1249
fputc('>', xml_file);
1250
fputs(line_end, xml_file);
1256
Print xml tag with for a field that is null
1259
print_xml_null_tag()
1260
xml_file - output file
1261
sbeg - line beginning
1262
stag_atr - tag and attribute
1263
sval - value of attribute
1264
line_end - line ending
1267
Print tag with one attribute to the xml_file. Format is:
1268
<stag_atr="sval" xsi:nil="true"/>
1270
sval MUST be a NULL terminated string.
1271
sval string will be qouted before output.
1274
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1275
const char* stag_atr, const char* sval,
1276
const char* line_end)
1278
fputs(sbeg, xml_file);
1279
fputs("<", xml_file);
1280
fputs(stag_atr, xml_file);
1281
fputs("\"", xml_file);
1282
print_quoted_xml(xml_file, sval, strlen(sval));
1283
fputs("\" xsi:nil=\"true\" />", xml_file);
1284
fputs(line_end, xml_file);
1290
Print xml tag with many attributes.
1294
xml_file - output file
1295
row_name - xml tag name
1296
tableRes - query result
1300
Print tag with many attribute to the xml_file. Format is:
1301
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1303
All atributes and values will be quoted before output.
1306
static void print_xml_row(FILE *xml_file, const char *row_name,
1307
DRIZZLE_RES *tableRes, DRIZZLE_ROW *row)
1310
DRIZZLE_FIELD *field;
1311
uint32_t *lengths= drizzleclient_fetch_lengths(tableRes);
1313
fprintf(xml_file, "\t\t<%s", row_name);
1315
drizzleclient_field_seek(tableRes, 0);
1316
for (i= 0; (field= drizzleclient_fetch_field(tableRes)); i++)
1320
fputc(' ', xml_file);
1321
print_quoted_xml(xml_file, field->name, field->name_length);
1322
fputs("=\"", xml_file);
1323
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1324
fputc('"', xml_file);
1328
fputs(" />\n", xml_file);
1334
Print hex value for blob data.
1338
output_file - output file
1339
str - string to print
1343
Print hex value for blob data.
1346
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
1348
/* sakaik got the idea to to provide blob's in hex notation. */
1349
const char *ptr= str, *end= ptr + len;
1350
for (; ptr < end ; ptr++)
1351
fprintf(output_file, "%02X", *((unsigned char *)ptr));
1352
check_io(output_file);
1356
get_table_structure -- retrievs database structure, prints out corresponding
1357
CREATE statement and fills out insert_pat if the table is the type we will
1363
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1364
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1365
num_fields - number of fields in the table
1368
true if success, false if error
1371
static bool get_table_structure(char *table, char *db, char *table_type,
1372
char *ignore_flag, uint64_t *num_fields)
1374
bool init=0, delayed, write_data, complete_insert;
1375
char *result_table, *opt_quoted_table;
1376
const char *insert_option;
1377
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
1378
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
1379
FILE *sql_file= md_result_file;
1380
DRIZZLE_RES *result;
1383
*ignore_flag= check_if_ignore_table(table, table_type);
1385
delayed= opt_delayed;
1386
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
1389
verbose_msg(_("-- Warning: Unable to use delayed inserts for table '%s' "
1390
"because it's of type %s\n"), table, table_type);
1394
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1396
complete_insert= opt_complete_insert;
1400
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1401
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
1403
verbose_msg(_("-- Retrieving table structure for table %s...\n"), table);
1405
result_table= quote_name(table, table_buff, 1);
1406
opt_quoted_table= quote_name(table, table_buff2, 0);
1408
if (opt_order_by_primary)
1411
order_by= primary_key_fields(result_table);
1416
/* using SHOW CREATE statement */
1417
if (!opt_no_create_info)
1419
/* Make an sql-file, if path was given iow. option -T was given */
1420
char buff[20+FN_REFLEN];
1421
const DRIZZLE_FIELD *field;
1423
snprintf(buff, sizeof(buff), "show create table %s", result_table);
1425
if (drizzleclient_query_with_error_report(drizzle, &result, buff))
1430
if (!(sql_file= open_sql_file_for_table(table)))
1433
write_header(sql_file, db);
1435
if (!opt_xml && opt_comments)
1437
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1444
Even if the "table" is a view, we do a DROP TABLE here.
1446
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
1450
field= drizzleclient_fetch_field_direct(result, 0);
1452
row= drizzleclient_fetch_row(result);
1454
fprintf(sql_file, "%s;\n", row[1]);
1457
drizzleclient_free_result(result);
1459
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1461
if (drizzleclient_query_with_error_report(drizzle, &result, query_buff))
1464
my_fclose(sql_file, MYF(MY_WME));
1469
If write_data is true, then we build up insert statements for
1470
the table's data. Note: in subsequent lines of code, this test
1471
will have to be performed each time we are appending to
1476
if (opt_replace_into)
1477
insert_pat.append("REPLACE ");
1479
insert_pat.append("INSERT ");
1480
insert_pat.append(insert_option);
1481
insert_pat.append("INTO ");
1482
insert_pat.append(opt_quoted_table);
1483
if (complete_insert)
1485
insert_pat.append(" (");
1489
insert_pat.append(" VALUES ");
1490
if (!extended_insert)
1491
insert_pat.append("(");
1495
while ((row= drizzleclient_fetch_row(result)))
1497
if (complete_insert)
1501
insert_pat.append(", ");
1504
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1507
*num_fields= drizzleclient_num_rows(result);
1508
drizzleclient_free_result(result);
1512
verbose_msg(_("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n"),
1513
my_progname, drizzleclient_error(drizzle));
1515
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1517
if (drizzleclient_query_with_error_report(drizzle, &result, query_buff))
1520
/* Make an sql-file, if path was given iow. option -T was given */
1521
if (!opt_no_create_info)
1525
if (!(sql_file= open_sql_file_for_table(table)))
1527
write_header(sql_file, db);
1529
if (!opt_xml && opt_comments)
1530
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1533
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1535
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1537
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1544
if (opt_replace_into)
1545
insert_pat.append("REPLACE ");
1547
insert_pat.append("INSERT ");
1548
insert_pat.append(insert_option);
1549
insert_pat.append("INTO ");
1550
insert_pat.append(result_table);
1551
if (complete_insert)
1552
insert_pat.append(" (");
1555
insert_pat.append(" VALUES ");
1556
if (!extended_insert)
1557
insert_pat.append("(");
1561
while ((row= drizzleclient_fetch_row(result)))
1563
uint32_t *lengths= drizzleclient_fetch_lengths(result);
1566
if (!opt_xml && !opt_no_create_info)
1568
fputs(",\n",sql_file);
1571
if (complete_insert)
1572
insert_pat.append(", ");
1575
if (complete_insert)
1576
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1577
if (!opt_no_create_info)
1581
print_xml_row(sql_file, "field", result, &row);
1586
fprintf(sql_file, " %s.%s %s", result_table,
1587
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1590
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1593
if (row[SHOW_DEFAULT])
1595
fputs(" DEFAULT ", sql_file);
1596
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1598
if (!row[SHOW_NULL][0])
1599
fputs(" NOT NULL", sql_file);
1600
if (row[SHOW_EXTRA][0])
1601
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1605
*num_fields= drizzleclient_num_rows(result);
1606
drizzleclient_free_result(result);
1607
if (!opt_no_create_info)
1609
/* Make an sql-file, if path was given iow. option -T was given */
1610
char buff[20+FN_REFLEN];
1611
uint32_t keynr,primary_key;
1612
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1613
if (drizzleclient_query_with_error_report(drizzle, &result, buff))
1615
if (drizzleclient_errno(drizzle) == ER_WRONG_OBJECT)
1618
fputs("\t\t<options Comment=\"view\" />\n", sql_file);
1621
fprintf(stderr, _("%s: Can't get keys for table %s (%s)\n"),
1622
my_progname, result_table, drizzleclient_error(drizzle));
1624
my_fclose(sql_file, MYF(MY_WME));
1628
/* Find first which key is primary key */
1630
primary_key=INT_MAX;
1631
while ((row= drizzleclient_fetch_row(result)))
1633
if (atoi(row[3]) == 1)
1636
#ifdef FORCE_PRIMARY_KEY
1637
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1640
if (!strcmp(row[2],"PRIMARY"))
1647
drizzleclient_data_seek(result,0);
1649
while ((row= drizzleclient_fetch_row(result)))
1653
print_xml_row(sql_file, "key", result, &row);
1657
if (atoi(row[3]) == 1)
1660
putc(')', sql_file);
1661
if (atoi(row[1])) /* Test if duplicate key */
1662
/* Duplicate allowed */
1663
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1664
else if (keynr == primary_key)
1665
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1667
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1671
putc(',', sql_file);
1672
fputs(quote_name(row[4], name_buff, 0), sql_file);
1674
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1677
drizzleclient_free_result(result);
1681
putc(')', sql_file);
1682
fputs("\n)",sql_file);
1685
/* Get DRIZZLE specific create options */
1688
char show_name_buff[NAME_LEN*2+2+24];
1690
/* Check memory for quote_for_like() */
1691
snprintf(buff, sizeof(buff), "show table status like %s",
1692
quote_for_like(table, show_name_buff));
1694
if (drizzleclient_query_with_error_report(drizzle, &result, buff))
1696
if (drizzleclient_errno(drizzle) != ER_PARSE_ERROR)
1697
{ /* If old DRIZZLE version */
1698
verbose_msg(_("-- Warning: Couldn't get status information for " \
1699
"table %s (%s)\n"), result_table,drizzleclient_error(drizzle));
1702
else if (!(row= drizzleclient_fetch_row(result)))
1705
_("Error: Couldn't read status information for table %s (%s)\n"),
1706
result_table,drizzleclient_error(drizzle));
1711
print_xml_row(sql_file, "options", result, &row);
1714
fputs("/*!",sql_file);
1715
print_value(sql_file,result,row,"engine=","Engine",0);
1716
print_value(sql_file,result,row,"","Create_options",0);
1717
print_value(sql_file,result,row,"comment=","Comment",1);
1719
fputs(" */",sql_file);
1723
drizzleclient_free_result(result); /* Is always safe to free */
1727
fputs(";\n", sql_file);
1729
fputs("\t</table_structure>\n", sql_file);
1733
if (complete_insert) {
1734
insert_pat.append(") VALUES ");
1735
if (!extended_insert)
1736
insert_pat.append("(");
1738
if (sql_file != md_result_file)
1740
fputs("\n", sql_file);
1741
write_footer(sql_file);
1742
my_fclose(sql_file, MYF(MY_WME));
1745
} /* get_table_structure */
1747
static void add_load_option(string &str, const char *option,
1748
const char *option_value)
1752
/* Null value means we don't add this option. */
1758
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
1760
/* It's a hex constant, don't escape */
1761
str.append(option_value);
1765
/* char constant; escape */
1766
field_escape(str, option_value);
1772
Allow the user to specify field terminator strings like:
1773
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
1774
This is done by doubling ' and add a end -\ if needed to avoid
1775
syntax errors from the SQL parser.
1778
static void field_escape(string &in, const char *from)
1780
uint32_t end_backslashes= 0;
1789
end_backslashes^=1; /* find odd number of backslashes */
1792
if (*from == '\'' && !end_backslashes)
1794
/* We want a duplicate of "'" for DRIZZLE */
1801
/* Add missing backslashes if user has specified odd number of backs.*/
1802
if (end_backslashes)
1815
dump_table saves database contents as a series of INSERT statements.
1826
static void dump_table(char *table, char *db)
1829
char buf[200], table_buff[NAME_LEN+3];
1830
string query_string;
1831
char table_type[NAME_LEN];
1832
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
1834
uint32_t rownr, row_break, total_length, init_length;
1835
uint64_t num_fields= 0;
1837
DRIZZLE_FIELD *field;
1842
Make sure you get the create table info before the following check for
1843
--no-data flag below. Otherwise, the create table info won't be printed.
1845
if (!get_table_structure(table, db, table_type, &ignore_flag, &num_fields))
1847
maybe_die(EX_TABLE_STATUS, _("Error retrieving table structure for table: \"%s\""), table);
1851
/* Check --no-data flag */
1854
verbose_msg(_("-- Skipping dump data for table '%s', --no-data was used\n"),
1860
If the table type is a merge table or any type that has to be
1861
_completely_ ignored and no data dumped
1863
if (ignore_flag & IGNORE_DATA)
1865
verbose_msg(_("-- Warning: Skipping data for table '%s' because " \
1866
"it's of type %s\n"), table, table_type);
1869
/* Check that there are any fields in the table */
1870
if (num_fields == 0)
1872
verbose_msg(_("-- Skipping dump data for table '%s', it has no fields\n"),
1877
result_table= quote_name(table,table_buff, 1);
1878
opt_quoted_table= quote_name(table, table_buff2, 0);
1880
verbose_msg(_("-- Sending SELECT query...\n"));
1882
query_string.clear();
1883
query_string.reserve(1024);
1887
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1890
Convert the path to native os format
1891
and resolve to the full filepath.
1893
convert_dirname(tmp_path,path,NULL);
1894
my_load_path(tmp_path, tmp_path, NULL);
1895
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1897
/* Must delete the file that 'INTO OUTFILE' will write to */
1898
my_delete(filename, MYF(0));
1900
/* now build the query string */
1902
query_string.append( "SELECT * INTO OUTFILE '");
1903
query_string.append( filename);
1904
query_string.append( "'");
1906
if (fields_terminated || enclosed || opt_enclosed || escaped)
1907
query_string.append( " FIELDS");
1909
add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1910
add_load_option(query_string, " ENCLOSED BY ", enclosed);
1911
add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
1912
add_load_option(query_string, " ESCAPED BY ", escaped);
1913
add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
1915
query_string.append( " FROM ");
1916
query_string.append( result_table);
1920
query_string.append( " WHERE ");
1921
query_string.append( where);
1926
query_string.append( " ORDER BY ");
1927
query_string.append( order_by);
1930
if (drizzleclient_real_query(drizzle, query_string.c_str(), query_string.length()))
1932
DB_error(drizzle, _("when executing 'SELECT INTO OUTFILE'"));
1938
if (!opt_xml && opt_comments)
1940
fprintf(md_result_file,_("\n--\n-- Dumping data for table %s\n--\n"),
1942
check_io(md_result_file);
1945
query_string.append( "SELECT * FROM ");
1946
query_string.append( result_table);
1950
if (!opt_xml && opt_comments)
1952
fprintf(md_result_file, "-- WHERE: %s\n", where);
1953
check_io(md_result_file);
1956
query_string.append( " WHERE ");
1957
query_string.append( where);
1961
if (!opt_xml && opt_comments)
1963
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
1964
check_io(md_result_file);
1966
query_string.append( " ORDER BY ");
1967
query_string.append( order_by);
1970
if (!opt_xml && !opt_compact)
1972
fputs("\n", md_result_file);
1973
check_io(md_result_file);
1975
if (drizzleclient_query_with_error_report(drizzle, 0, query_string.c_str()))
1977
DB_error(drizzle, _("when retrieving data from server"));
1981
res=drizzleclient_use_result(drizzle);
1983
res=drizzleclient_store_result(drizzle);
1986
DB_error(drizzle, _("when retrieving data from server"));
1990
verbose_msg(_("-- Retrieving rows...\n"));
1991
if (drizzleclient_num_fields(res) != num_fields)
1993
fprintf(stderr,_("%s: Error in field count for table: %s ! Aborting.\n"),
1994
my_progname, result_table);
1995
error= EX_CONSCHECK;
2001
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2002
check_io(md_result_file);
2004
/* Moved disable keys to after lock per bug 15977 */
2005
if (opt_disable_keys)
2007
fprintf(md_result_file, "ALTER TABLE %s DISABLE KEYS;\n",
2009
check_io(md_result_file);
2012
total_length= opt_net_buffer_length; /* Force row break */
2015
init_length=(uint32_t) insert_pat.length()+4;
2017
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2021
fprintf(md_result_file, "set autocommit=0;\n");
2022
check_io(md_result_file);
2025
while ((row= drizzleclient_fetch_row(res)))
2028
uint32_t *lengths= drizzleclient_fetch_lengths(res);
2030
if ((rownr % show_progress_size) == 0)
2032
verbose_msg(_("-- %"PRIu32" of ~%"PRIu64" rows dumped for table %s\n"), rownr, total_rows, opt_quoted_table);
2034
if (!extended_insert && !opt_xml)
2036
fputs(insert_pat.c_str(),md_result_file);
2037
check_io(md_result_file);
2039
drizzleclient_field_seek(res,0);
2043
fputs("\t<row>\n", md_result_file);
2044
check_io(md_result_file);
2047
for (i= 0; i < drizzleclient_num_fields(res); i++)
2050
uint32_t length= lengths[i];
2052
if (!(field= drizzleclient_fetch_field(res)))
2054
_("Not enough fields from table %s! Aborting.\n"),
2058
63 is my_charset_bin. If charsetnr is not 63,
2059
we have not a BLOB but a TEXT column.
2060
we'll dump in hex only BLOB columns.
2062
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
2063
(field->type == DRIZZLE_TYPE_VARCHAR ||
2064
field->type == DRIZZLE_TYPE_BLOB)) ? 1 : 0;
2065
if (extended_insert && !opt_xml)
2069
extended_row.clear();
2070
extended_row.append("(");
2073
extended_row.append(",");
2079
if (!(field->type & NUM_FLAG))
2082
"length * 2 + 2" is OK for both HEX and non-HEX modes:
2083
- In HEX mode we need exactly 2 bytes per character
2084
plus 2 bytes for '0x' prefix.
2085
- In non-HEX mode we need up to 2 bytes per character,
2086
plus 2 bytes for leading and trailing '\'' characters.
2087
Also we need to reserve 1 byte for terminating '\0'.
2089
char * tmp_str= (char *)malloc(length * 2 + 2 + 1);
2090
memset(tmp_str, '\0', length * 2 + 2 + 1);
2091
if (opt_hex_blob && is_blob)
2093
extended_row.append("0x");
2094
drizzleclient_drizzleclient_octet2hex(tmp_str, row[i], length);
2095
extended_row.append(tmp_str);
2099
extended_row.append("'");
2100
drizzleclient_escape_string(tmp_str,
2102
extended_row.append(tmp_str);
2103
extended_row.append("'");
2109
/* change any strings ("inf", "-inf", "nan") into NULL */
2111
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2112
my_isalpha(charset_info, ptr[1])))
2113
extended_row.append( "NULL");
2116
extended_row.append( ptr);
2121
extended_row.append("''");
2124
extended_row.append("NULL");
2130
fputc(',', md_result_file);
2131
check_io(md_result_file);
2135
if (!(field->type & NUM_FLAG))
2139
if (opt_hex_blob && is_blob && length)
2141
/* Define xsi:type="xs:hexBinary" for hex encoded data */
2142
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2143
field->name, "xsi:type=", "xs:hexBinary", NULL);
2144
print_blob_as_hex(md_result_file, row[i], length);
2148
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2150
print_quoted_xml(md_result_file, row[i], length);
2152
fputs("</field>\n", md_result_file);
2154
else if (opt_hex_blob && is_blob && length)
2156
fputs("0x", md_result_file);
2157
print_blob_as_hex(md_result_file, row[i], length);
2160
unescape(md_result_file, row[i], length);
2164
/* change any strings ("inf", "-inf", "nan") into NULL */
2168
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2170
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2172
fputs("</field>\n", md_result_file);
2174
else if (my_isalpha(charset_info, *ptr) ||
2175
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
2176
fputs("NULL", md_result_file);
2178
fputs(ptr, md_result_file);
2183
/* The field value is NULL */
2185
fputs("NULL", md_result_file);
2187
print_xml_null_tag(md_result_file, "\t\t", "field name=",
2190
check_io(md_result_file);
2196
fputs("\t</row>\n", md_result_file);
2197
check_io(md_result_file);
2200
if (extended_insert)
2202
uint32_t row_length;
2203
extended_row.append(")");
2204
row_length= 2 + extended_row.length();
2205
if (total_length + row_length < opt_net_buffer_length)
2207
total_length+= row_length;
2208
fputc(',',md_result_file); /* Always row break */
2209
fputs(extended_row.c_str(),md_result_file);
2214
fputs(";\n", md_result_file);
2215
row_break=1; /* This is first row */
2217
fputs(insert_pat.c_str(),md_result_file);
2218
fputs(extended_row.c_str(),md_result_file);
2219
total_length= row_length+init_length;
2221
check_io(md_result_file);
2225
fputs(");\n", md_result_file);
2226
check_io(md_result_file);
2230
/* XML - close table tag and supress regular output */
2232
fputs("\t</table_data>\n", md_result_file);
2233
else if (extended_insert && row_break)
2234
fputs(";\n", md_result_file); /* If not empty table */
2235
fflush(md_result_file);
2236
check_io(md_result_file);
2237
if (drizzleclient_errno(drizzle))
2239
snprintf(buf, sizeof(buf),
2240
_("%s: Error %d: %s when dumping table %s at row: %d\n"),
2242
drizzleclient_errno(drizzle),
2243
drizzleclient_error(drizzle),
2247
error= EX_CONSCHECK;
2251
/* Moved enable keys to before unlock per bug 15977 */
2252
if (opt_disable_keys)
2254
fprintf(md_result_file,"ALTER TABLE %s ENABLE KEYS;\n",
2256
check_io(md_result_file);
2260
fputs("UNLOCK TABLES;\n", md_result_file);
2261
check_io(md_result_file);
2265
fprintf(md_result_file, "commit;\n");
2266
check_io(md_result_file);
2268
drizzleclient_free_result(res);
2278
static char *getTableName(int reset)
2280
static DRIZZLE_RES *res= NULL;
2285
if (!(res= drizzleclient_list_tables(drizzle,NULL)))
2288
if ((row= drizzleclient_fetch_row(res)))
2289
return((char*) row[0]);
2292
drizzleclient_data_seek(res,0); /* We want to read again */
2295
drizzleclient_free_result(res);
2299
} /* getTableName */
365
2302
static int dump_all_databases()
368
drizzle_result_st *tableres;
2305
DRIZZLE_RES *tableres;
371
DrizzleDumpDatabase *database;
374
std::cerr << _("-- Retrieving database structures...") << std::endl;
376
/* Blocking the MySQL privilege tables too because we can't import them due to bug#646187 */
377
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
378
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
380
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
382
tableres= db_connection->query(query);
383
while ((row= drizzle_row_next(tableres)))
2308
if (drizzleclient_query_with_error_report(drizzle, &tableres, "SHOW DATABASES"))
2310
while ((row= drizzleclient_fetch_row(tableres)))
385
std::string database_name(row[0]);
386
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
387
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
389
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
391
database->setCollate(row[1]);
392
database_store.push_back(database);
2312
if (dump_all_tables_in_db(row[0]))
394
db_connection->freeResult(tableres);
397
2317
/* dump_all_databases */
400
static int dump_databases(const vector<string> &db_names)
2320
static int dump_databases(char **db_names)
404
DrizzleDumpDatabase *database;
406
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
2326
for (db= db_names ; *db ; db++)
409
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
410
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
412
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
413
database_store.push_back(database);
2328
if (dump_all_tables_in_db(*db))
416
2332
} /* dump_databases */
418
static int dump_selected_tables(const string &db, const vector<string> &table_names)
420
DrizzleDumpDatabase *database;
422
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
423
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
425
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
427
if (not database->populateTables(table_names))
430
if (not ignore_errors)
431
maybe_exit(EX_DRIZZLEERR);
434
database_store.push_back(database);
2336
Table Specific database initalization.
2340
qdatabase quoted name of the database
2347
int init_dumping_tables(char *qdatabase)
2355
DRIZZLE_RES *dbinfo;
2357
snprintf(qbuf, sizeof(qbuf),
2358
"SHOW CREATE DATABASE IF NOT EXISTS %s",
2361
if (drizzleclient_query(drizzle, qbuf) || !(dbinfo = drizzleclient_store_result(drizzle)))
2363
/* Old server version, dump generic CREATE DATABASE */
2364
if (opt_drop_database)
2365
fprintf(md_result_file,
2366
"\nDROP DATABASE IF EXISTS %s;\n",
2368
fprintf(md_result_file,
2369
"\nCREATE DATABASE IF NOT EXISTS %s;\n",
2374
if (opt_drop_database)
2375
fprintf(md_result_file,
2376
"\nDROP DATABASE IF EXISTS %s;\n",
2378
row = drizzleclient_fetch_row(dbinfo);
2381
fprintf(md_result_file,"\n%s;\n",row[1]);
2383
drizzleclient_free_result(dbinfo);
2387
} /* init_dumping_tables */
2390
static int init_dumping(char *database, int init_func(char*))
2392
if (drizzleclient_get_server_version(drizzle) >= 50003 &&
2393
!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
2396
if (drizzleclient_select_db(drizzle, database))
2398
DB_error(drizzle, _("when selecting the database"));
2399
return 1; /* If --force */
2401
if (!path && !opt_xml)
2403
if (opt_databases || opt_alldbs)
2406
length of table name * 2 (if name contains quotes), 2 quotes and 0
2408
char quoted_database_buf[NAME_LEN*2+3];
2409
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
2412
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
2413
check_io(md_result_file);
2416
/* Call the view or table specific function */
2417
init_func(qdatabase);
2419
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
2420
check_io(md_result_file);
2423
if (extended_insert)
2424
extended_row.clear();
2426
} /* init_dumping */
2429
/* Return 1 if we should copy the table */
2431
static bool include_table(const unsigned char *hash_key, size_t len)
2433
return !hash_search(&ignore_table, hash_key, len);
2437
static int dump_all_tables_in_db(char *database)
2441
char table_buff[NAME_LEN*2+3];
2442
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
2445
afterdot= strcpy(hash_key, database) + strlen(database);
2448
if (init_dumping(database, init_dumping_tables))
2451
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
2454
string query("LOCK TABLES ");
2455
for (numrows= 0 ; (table= getTableName(1)) ; )
2457
char *end= strcpy(afterdot, table) + strlen(table);
2458
if (include_table((unsigned char*) hash_key,end - hash_key))
2461
query.append( quote_name(table, table_buff, 1));
2462
query.append( " READ LOCAL,");
2465
if (numrows && drizzleclient_real_query(drizzle, query.c_str(), query.length()-1))
2466
DB_error(drizzle, _("when using LOCK TABLES"));
2467
/* We shall continue here, if --force was given */
2472
if (drizzleclient_refresh(drizzle, REFRESH_LOG))
2473
DB_error(drizzle, _("when doing refresh"));
2474
/* We shall continue here, if --force was given */
2476
while ((table= getTableName(0)))
2478
char *end= strcpy(afterdot, table) + strlen(table);
2479
if (include_table((unsigned char*) hash_key, end - hash_key))
2481
dump_table(table,database);
2488
fputs("</database>\n", md_result_file);
2489
check_io(md_result_file);
2492
drizzleclient_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
2495
} /* dump_all_tables_in_db */
2499
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2500
table name from the server for the table name given on the command line.
2501
we do this because the table name given on the command line may be a
2502
different case (e.g. T1 vs t1)
2505
pointer to the table name
2509
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2512
DRIZZLE_RES *table_res;
2514
char query[50 + 2*NAME_LEN];
2515
char show_name_buff[FN_REFLEN];
2518
/* Check memory for quote_for_like() */
2519
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2520
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2521
quote_for_like(old_table_name, show_name_buff));
2523
if (drizzleclient_query_with_error_report(drizzle, 0, query))
2526
if ((table_res= drizzleclient_store_result(drizzle)))
2528
uint64_t num_rows= drizzleclient_num_rows(table_res);
2534
TODO: Return all matching rows
2536
row= drizzleclient_fetch_row(table_res);
2537
lengths= drizzleclient_fetch_lengths(table_res);
2538
name= strmake_root(root, row[0], lengths[0]);
2540
drizzleclient_free_result(table_res);
2546
static int dump_selected_tables(char *db, char **table_names, int tables)
2548
char table_buff[NAME_LEN*2+3];
2549
string lock_tables_query("LOCK TABLES ");
2551
char **dump_tables, **pos, **end;
2554
if (init_dumping(db, init_dumping_tables))
2557
init_alloc_root(&root, 8192, 0);
2558
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2559
die(EX_EOM, _("alloc_root failure."));
2561
for (; tables > 0 ; tables-- , table_names++)
2563
/* the table name passed on commandline may be wrong case */
2564
if ((*pos= get_actual_table_name(*table_names, &root)))
2566
/* Add found table name to lock_tables_query */
2569
lock_tables_query.append( quote_name(*pos, table_buff, 1));
2570
lock_tables_query.append( " READ LOCAL,");
2578
free_root(&root, MYF(0));
2580
maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""), *table_names);
2581
/* We shall countinue here, if --force was given */
2588
if (drizzleclient_real_query(drizzle, lock_tables_query.c_str(),
2589
lock_tables_query.length()-1))
2593
free_root(&root, MYF(0));
2595
DB_error(drizzle, _("when doing LOCK TABLES"));
2596
/* We shall countinue here, if --force was given */
2601
if (drizzleclient_refresh(drizzle, REFRESH_LOG))
2604
free_root(&root, MYF(0));
2605
DB_error(drizzle, _("when doing refresh"));
2607
/* We shall countinue here, if --force was given */
2610
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NULL);
2612
/* Dump each selected table */
2613
for (pos= dump_tables; pos < end; pos++)
2614
dump_table(*pos, db);
2616
free_root(&root, MYF(0));
2621
fputs("</database>\n", md_result_file);
2622
check_io(md_result_file);
2625
drizzleclient_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
437
2627
} /* dump_selected_tables */
439
static int do_flush_tables_read_lock()
2630
static int do_show_master_status(DRIZZLE *drizzle_con)
2633
DRIZZLE_RES *master;
2634
const char *comment_prefix=
2635
(opt_master_data == DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
2636
if (drizzleclient_query_with_error_report(drizzle_con, &master, "SHOW MASTER STATUS"))
2642
row= drizzleclient_fetch_row(master);
2643
if (row && row[0] && row[1])
2645
/* SHOW MASTER STATUS reports file and position */
2647
fprintf(md_result_file,
2648
"\n--\n-- Position to start replication or point-in-time "
2649
"recovery from\n--\n\n");
2650
fprintf(md_result_file,
2651
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
2652
comment_prefix, row[0], row[1]);
2653
check_io(md_result_file);
2655
else if (!ignore_errors)
2657
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2658
my_printf_error(0, _("Error: Binlogging on server not active"),
2660
drizzleclient_free_result(master);
2661
maybe_exit(EX_DRIZZLEERR);
2664
drizzleclient_free_result(master);
2669
static int do_stop_slave_sql(DRIZZLE *drizzle_con)
2672
/* We need to check if the slave sql is running in the first place */
2673
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2677
DRIZZLE_ROW row= drizzleclient_fetch_row(slave);
2680
/* if SLAVE SQL is not running, we don't stop it */
2681
if (!strcmp(row[11],"No"))
2683
drizzleclient_free_result(slave);
2684
/* Silently assume that they don't have the slave running */
2689
drizzleclient_free_result(slave);
2691
/* now, stop slave if running */
2692
if (drizzleclient_query_with_error_report(drizzle_con, 0, "STOP SLAVE SQL_THREAD"))
2698
static int add_stop_slave(void)
2701
fprintf(md_result_file,
2702
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
2703
fprintf(md_result_file, "STOP SLAVE;\n");
2707
static int add_slave_statements(void)
2710
fprintf(md_result_file,
2711
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
2712
fprintf(md_result_file, "START SLAVE;\n");
2716
static int do_show_slave_status(DRIZZLE *drizzle_con)
2719
const char *comment_prefix=
2720
(opt_slave_data == DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
2721
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2725
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
2726
my_printf_error(0, _("Error: Slave not set up"), MYF(0));
2732
DRIZZLE_ROW row= drizzleclient_fetch_row(slave);
2733
if (row && row[9] && row[21])
2735
/* SHOW MASTER STATUS reports file and position */
2737
fprintf(md_result_file,
2738
"\n--\n-- Position to start replication or point-in-time "
2739
"recovery from (the master of this slave)\n--\n\n");
2741
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
2743
if (opt_include_master_host_port)
2746
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
2748
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
2750
fprintf(md_result_file,
2751
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
2753
check_io(md_result_file);
2755
drizzleclient_free_result(slave);
2760
static int do_start_slave_sql(DRIZZLE *drizzle_con)
2763
/* We need to check if the slave sql is stopped in the first place */
2764
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2768
DRIZZLE_ROW row= drizzleclient_fetch_row(slave);
2771
/* if SLAVE SQL is not running, we don't start it */
2772
if (!strcmp(row[11],"Yes"))
2774
drizzleclient_free_result(slave);
2775
/* Silently assume that they don't have the slave running */
2780
drizzleclient_free_result(slave);
2782
/* now, start slave if stopped */
2783
if (drizzleclient_query_with_error_report(drizzle_con, 0, "START SLAVE"))
2785
my_printf_error(0, _("Error: Unable to start slave"), MYF(0));
2793
static int do_flush_tables_read_lock(DRIZZLE *drizzle_con)
442
2796
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
443
2797
will wait but will not stall the whole mysqld, and when the long update is
444
2798
done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
445
FLUSH TABLES is to lower the probability of a stage where both drizzled
2799
FLUSH TABLES is to lower the probability of a stage where both mysqldump
446
2800
and most client connections are stalled. Of course, if a second long
447
2801
update starts between the two FLUSHes, we have that bad stall.
450
db_connection->queryNoResult("FLUSH TABLES");
451
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
456
static int do_unlock_tables()
458
db_connection->queryNoResult("UNLOCK TABLES");
462
static int start_transaction()
464
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
465
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
2804
( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES") ||
2805
drizzleclient_query_with_error_report(drizzle_con, 0,
2806
"FLUSH TABLES WITH READ LOCK") );
2810
static int do_unlock_tables(DRIZZLE *drizzle_con)
2812
return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES");
2815
static int get_bin_log_name(DRIZZLE *drizzle_con,
2816
char* buff_log_name, uint32_t buff_len)
2821
if (drizzleclient_query(drizzle_con, "SHOW MASTER STATUS") ||
2822
!(res= drizzleclient_store_result(drizzle)))
2825
if (!(row= drizzleclient_fetch_row(res)))
2827
drizzleclient_free_result(res);
2831
Only one row is returned, and the first column is the name of the
2834
strncpy(buff_log_name, row[0], buff_len - 1);
2836
drizzleclient_free_result(res);
2840
static int purge_bin_logs_to(DRIZZLE *drizzle_con, char* log_name)
2843
string str= "PURGE BINARY LOGS TO '";
2844
str.append(log_name);
2846
err = drizzleclient_query_with_error_report(drizzle_con, 0, str.c_str());
2851
static int start_transaction(DRIZZLE *drizzle_con)
2853
return (drizzleclient_query_with_error_report(drizzle_con, 0,
2854
"SET SESSION TRANSACTION ISOLATION "
2855
"LEVEL REPEATABLE READ") ||
2856
drizzleclient_query_with_error_report(drizzle_con, 0,
2857
"START TRANSACTION "
2858
"WITH CONSISTENT SNAPSHOT"));
2862
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
2863
char **err_pos, uint32_t *err_len)
2865
const char *end= x + length;
2870
*err_pos= 0; /* No error yet */
2871
while (end > x && my_isspace(charset_info, end[-1]))
2877
const char *start= x;
2880
const char *pos= start;
2883
for (; pos != end && *pos != ','; pos++) ;
2884
var_len= (uint32_t) (pos - start);
2885
strncpy(buff, start, min((uint32_t)sizeof(buff), var_len));
2886
find= find_type(buff, lib, var_len);
2889
*err_pos= (char*) start;
2893
found|= (uint32_t)((int64_t) 1 << (find - 1));
2903
/* Print a value with a prefix on file */
2904
static void print_value(FILE *file, DRIZZLE_RES *result, DRIZZLE_ROW row,
2905
const char *prefix, const char *name,
2908
DRIZZLE_FIELD *field;
2909
drizzleclient_field_seek(result, 0);
2911
for ( ; (field= drizzleclient_fetch_field(result)) ; row++)
2913
if (!strcmp(field->name,name))
2915
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2918
fputs(prefix, file);
2920
unescape(file,row[0],(uint32_t) strlen(row[0]));
2922
fputs(row[0], file);
2928
return; /* This shouldn't happen */
2932
* Fetches a row from a result based on a field name
2933
* Returns const char* of the data in that row or NULL if not found
2936
static const char* fetch_named_row(DRIZZLE_RES *result, DRIZZLE_ROW row, const char *name)
2938
DRIZZLE_FIELD *field;
2939
drizzleclient_field_seek(result, 0);
2940
for ( ; (field= drizzleclient_fetch_field(result)) ; row++)
2942
if (!strcmp(field->name,name))
2944
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2946
drizzleclient_field_seek(result, 0);
2951
drizzleclient_field_seek(result, 0);
2959
Check if we the table is one of the table types that should be ignored:
2960
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
2961
If the table should be altogether ignored, it returns a true, false if it
2962
should not be ignored. If the user has selected to use INSERT DELAYED, it
2963
sets the value of the bool pointer supports_delayed_inserts to 0 if not
2964
supported, 1 if it is supported.
2968
check_if_ignore_table()
2969
table_name Table name to check
2970
table_type Type of table
2973
drizzle Drizzle connection
2974
verbose Write warning messages
2977
char (bit value) See IGNORE_ values at top
2980
char check_if_ignore_table(const char *table_name, char *table_type)
2982
char result= IGNORE_NONE;
2983
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
2984
const char *number_of_rows= NULL;
2985
DRIZZLE_RES *res= NULL;
2988
/* Check memory for quote_for_like() */
2989
assert(2*sizeof(table_name) < sizeof(show_name_buff));
2990
snprintf(buff, sizeof(buff), "show table status like %s",
2991
quote_for_like(table_name, show_name_buff));
2992
if (drizzleclient_query_with_error_report(drizzle, &res, buff))
2994
if (drizzleclient_errno(drizzle) != ER_PARSE_ERROR)
2995
{ /* If old DRIZZLE version */
2996
verbose_msg(_("-- Warning: Couldn't get status information for "
2997
"table %s (%s)\n"), table_name, drizzleclient_error(drizzle));
2998
return(result); /* assume table is ok */
3001
if (!(row= drizzleclient_fetch_row(res)))
3004
_("Error: Couldn't read status information for table %s (%s)\n"),
3005
table_name, drizzleclient_error(drizzle));
3006
drizzleclient_free_result(res);
3007
return(result); /* assume table is ok */
3011
if ((number_of_rows= fetch_named_row(res, row, "Rows")) != NULL)
3013
total_rows= strtoul(number_of_rows, NULL, 10);
3017
If the table type matches any of these, we do support delayed inserts.
3018
Note: we do not want to skip dumping this table if if is not one of
3019
these types, but we do want to use delayed inserts in the dump if
3020
the table type is _NOT_ one of these types
3023
strncpy(table_type, row[1], NAME_LEN-1);
3026
if (strcmp(table_type,"MyISAM") &&
3027
strcmp(table_type,"ARCHIVE") &&
3028
strcmp(table_type,"HEAP") &&
3029
strcmp(table_type,"MEMORY"))
3030
result= IGNORE_INSERT_DELAYED;
3033
drizzleclient_free_result(res);
3039
Get string of comma-separated primary key field names
3042
char *primary_key_fields(const char *table_name)
3043
RETURNS pointer to allocated buffer (must be freed by caller)
3044
table_name quoted table name
3047
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
3048
field names, and then build that string and return the pointer
3051
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
3052
or if there is some failure. It is better to continue to dump
3053
the table unsorted, rather than exit without dumping the data.
3056
static char *primary_key_fields(const char *table_name)
3058
DRIZZLE_RES *res= NULL;
3060
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
3061
char show_keys_buff[15 + NAME_LEN * 2 + 3];
3062
uint32_t result_length= 0;
3064
char buff[NAME_LEN * 2 + 3];
3067
snprintf(show_keys_buff, sizeof(show_keys_buff),
3068
"SHOW KEYS FROM %s", table_name);
3069
if (drizzleclient_query(drizzle, show_keys_buff) ||
3070
!(res= drizzleclient_store_result(drizzle)))
3072
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
3073
" records are NOT sorted (%s)\n"),
3074
table_name, drizzleclient_error(drizzle));
3075
/* Don't exit, because it's better to print out unsorted records */
3080
* Figure out the length of the ORDER BY clause result.
3081
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
3082
* row, and UNIQUE keys come before others. So we only need to check
3083
* the first key, not all keys.
3085
if ((row= drizzleclient_fetch_row(res)) && atoi(row[1]) == 0)
3090
quoted_field= quote_name(row[4], buff, 0);
3091
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
3092
} while ((row= drizzleclient_fetch_row(res)) && atoi(row[3]) > 1);
3095
/* Build the ORDER BY clause result */
3099
/* result (terminating \0 is already in result_length) */
3100
result= (char *)malloc(result_length + 10);
3103
fprintf(stderr, _("Error: Not enough memory to store ORDER BY clause\n"));
3106
drizzleclient_data_seek(res, 0);
3107
row= drizzleclient_fetch_row(res);
3108
quoted_field= quote_name(row[4], buff, 0);
3109
end= strcpy(result, quoted_field) + strlen(quoted_field);
3110
while ((row= drizzleclient_fetch_row(res)) && atoi(row[3]) > 1)
3112
quoted_field= quote_name(row[4], buff, 0);
3113
end+= sprintf(end,",%s",quoted_field);
3119
drizzleclient_free_result(res);
469
3125
int main(int argc, char **argv)
3127
char bin_log_name[FN_REFLEN];
475
po::options_description commandline_options(N_("Options used only in command line"));
476
commandline_options.add_options()
477
("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
478
N_("Dump all the databases. This will be same as --databases with all databases selected."))
479
("all-tablespaces,Y", po::value<bool>(&opt_alltspcs)->default_value(false)->zero_tokens(),
480
N_("Dump all the tablespaces."))
481
("complete-insert,c", po::value<bool>(&opt_complete_insert)->default_value(false)->zero_tokens(),
482
N_("Use complete insert statements."))
483
("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
484
N_("Flush logs file in server before starting dump. Note that if you dump many databases at once (using the option --databases= or --all-databases), the logs will be flushed for each database dumped. The exception is when using --lock-all-tables in this case the logs will be flushed only once, corresponding to the moment all tables are locked. So if you want your dump and the log flush to happen at the same exact moment you should use --lock-all-tables or --flush-logs"))
485
("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
486
N_("Continue even if we get an sql-error."))
487
("help,?", N_("Display this help message and exit."))
488
("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
489
N_("Locks all tables across all databases. This is achieved by taking a global read lock for the duration of the whole dump. Automatically turns --single-transaction off."))
490
("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
491
N_("Creates a consistent snapshot by dumping all tables in a single transaction. Works ONLY for tables stored in storage engines which support multiversioning (currently only InnoDB does); the dump is NOT guaranteed to be consistent for other storage engines. While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents), no other connection should use the following statements: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them."))
493
N_("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, ---extended-insert and --disable-keys."))
494
("tables", N_("Overrides option --databases (-B)."))
495
("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
496
N_("Number of rows before each output progress report (requires --verbose)."))
497
("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
498
N_("Print info about the various stages."))
499
("version,V", N_("Output version information and exit."))
500
("skip-comments", N_("Turn off Comments"))
501
("skip-create", N_("Turn off create-options"))
502
("skip-extended-insert", N_("Turn off extended-insert"))
503
("skip-dump-date",N_( "Turn off dump date at the end of the output"))
504
("no-defaults", N_("Do not read from the configuration files"))
507
po::options_description dump_options(N_("Options specific to the drizzle client"));
508
dump_options.add_options()
509
("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
510
N_("Add a 'DROP DATABASE' before each create."))
511
("skip-drop-table", N_("Do not add a 'drop table' before each create."))
512
("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
513
N_("Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys"))
514
("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
515
N_("To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output."))
516
("skip-disable-keys,K",
517
N_("'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will not be put in the output."))
518
("ignore-table", po::value<string>(),
519
N_("Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names, e.g. --ignore-table=database.table"))
520
("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
521
N_("Insert rows with INSERT IGNORE."))
522
("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
523
N_("Wrap a table's data in START TRANSACTION/COMMIT statements."))
524
("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
525
N_("'CREATE DATABASE IF NOT EXISTS db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given."))
526
("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
527
N_("No row information."))
528
("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
529
N_("Use REPLACE INTO instead of INSERT INTO."))
530
("destination-type", po::value<string>()->default_value("stdout"),
531
N_("Where to send output to (stdout|database"))
532
("destination-host", po::value<string>(&opt_destination_host)->default_value("localhost"),
533
N_("Hostname for destination db server (requires --destination-type=database)"))
534
("destination-port", po::value<uint16_t>(&opt_destination_port)->default_value(4427),
535
N_("Port number for destination db server (requires --destination-type=database)"))
536
("destination-user", po::value<string>(&opt_destination_user),
537
N_("User name for destination db server (resquires --destination-type=database)"))
538
("destination-password", po::value<string>(&opt_destination_password),
539
N_("Password for destination db server (requires --destination-type=database)"))
540
("destination-database", po::value<string>(&opt_destination_database),
541
N_("The database in the destination db server (requires --destination-type=database, not for use with --all-databases)"))
544
po::options_description client_options(N_("Options specific to the client"));
545
client_options.add_options()
546
("host,h", po::value<string>(¤t_host)->default_value("localhost"),
547
N_("Connect to host."))
548
("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
549
N_("Password to use when connecting to server. If password is not given it's solicited on the tty."))
550
("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
551
N_("Port number to use for connection."))
552
("user,u", po::value<string>(¤t_user)->default_value(""),
553
N_("User for login if not current user."))
554
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
555
N_("The protocol of connection (mysql or drizzle)."))
558
po::options_description hidden_options(N_("Hidden Options"));
559
hidden_options.add_options()
560
("database-used", po::value<vector<string> >(), N_("Used to select the database"))
561
("Table-used", po::value<vector<string> >(), N_("Used to select the tables"))
564
po::options_description all_options(N_("Allowed Options + Hidden Options"));
565
all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
567
po::options_description long_options(N_("Allowed Options"));
568
long_options.add(commandline_options).add(dump_options).add(client_options);
570
std::string system_config_dir_dump(SYSCONFDIR);
571
system_config_dir_dump.append("/drizzle/drizzledump.cnf");
573
std::string system_config_dir_client(SYSCONFDIR);
574
system_config_dir_client.append("/drizzle/client.cnf");
576
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
578
if (user_config_dir.compare(0, 2, "~/") == 0)
581
homedir= getenv("HOME");
583
user_config_dir.replace(0, 1, homedir);
586
po::positional_options_description p;
587
p.add("database-used", 1);
588
p.add("Table-used",-1);
590
md_result_file= stdout;
592
po::variables_map vm;
594
// Disable allow_guessing
595
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
597
po::store(po::command_line_parser(argc, argv).style(style).
598
options(all_options).positional(p).
599
extra_parser(parse_password_arg).run(), vm);
601
if (! vm.count("no-defaults"))
603
std::string user_config_dir_dump(user_config_dir);
604
user_config_dir_dump.append("/drizzle/drizzledump.cnf");
606
std::string user_config_dir_client(user_config_dir);
607
user_config_dir_client.append("/drizzle/client.cnf");
609
ifstream user_dump_ifs(user_config_dir_dump.c_str());
610
po::store(parse_config_file(user_dump_ifs, dump_options), vm);
612
ifstream user_client_ifs(user_config_dir_client.c_str());
613
po::store(parse_config_file(user_client_ifs, client_options), vm);
615
ifstream system_dump_ifs(system_config_dir_dump.c_str());
616
po::store(parse_config_file(system_dump_ifs, dump_options), vm);
618
ifstream system_client_ifs(system_config_dir_client.c_str());
619
po::store(parse_config_file(system_client_ifs, client_options), vm);
624
if ((not vm.count("database-used") && not vm.count("Table-used")
625
&& not opt_alldbs && path.empty())
626
|| (vm.count("help")) || vm.count("version"))
628
printf(_("Drizzledump %s build %s, for %s-%s (%s)\n"),
629
drizzle_version(), VERSION, HOST_VENDOR, HOST_OS, HOST_CPU);
630
if (vm.count("version"))
633
puts(_("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"));
634
puts(_("Dumps definitions and data from a Drizzle database server"));
635
printf(_("Usage: %s [OPTIONS] database [tables]\n"), progname.c_str());
636
printf(_("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
638
printf(_("OR %s [OPTIONS] --all-databases [OPTIONS]\n"), progname.c_str());
639
cout << long_options;
640
if (vm.count("help"))
646
/* Inverted Booleans */
648
opt_drop= (vm.count("skip-drop-table")) ? false : true;
649
opt_comments= (vm.count("skip-comments")) ? false : true;
650
extended_insert= (vm.count("skip-extended-insert")) ? false : true;
651
opt_dump_date= (vm.count("skip-dump-date")) ? false : true;
652
opt_disable_keys= (vm.count("skip-disable-keys")) ? false : true;
653
opt_quoted= (vm.count("skip-quote-names")) ? false : true;
655
if (vm.count("protocol"))
657
std::transform(opt_protocol.begin(), opt_protocol.end(),
658
opt_protocol.begin(), ::tolower);
660
if (not opt_protocol.compare("mysql"))
661
use_drizzle_protocol=false;
662
else if (not opt_protocol.compare("drizzle"))
663
use_drizzle_protocol=true;
666
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
671
if (vm.count("port"))
673
/* If the port number is > 65535 it is not a valid port
674
* This also helps with potential data loss casting unsigned long to a
677
if (opt_drizzle_port > 65535)
679
fprintf(stderr, _("Value supplied for port is not valid.\n"));
684
if(vm.count("password"))
686
if (!opt_password.empty())
687
opt_password.erase();
688
if (password == PASSWORD_SENTINEL)
694
opt_password= password;
708
if (vm.count("skip-opt"))
710
extended_insert= opt_drop= create_options= 0;
716
opt_comments= opt_drop= opt_disable_keys= 0;
721
extended_insert= opt_drop= create_options= 1;
725
if (vm.count("tables"))
727
opt_databases= false;
730
if (vm.count("ignore-table"))
732
if (!strchr(vm["ignore-table"].as<string>().c_str(), '.'))
734
fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
735
exit(EXIT_ARGUMENT_INVALID);
737
string tmpptr(vm["ignore-table"].as<string>());
738
ignore_table.insert(tmpptr);
741
if (vm.count("skip-create"))
743
opt_create_db= opt_no_create_info= create_options= false;
746
exit_code= get_options();
3129
MY_INIT("drizzledump");
3131
compatible_mode_normal_str[0]= 0;
3132
default_charset= (char *)drizzle_universal_client_charset;
3133
memset(&ignore_table, 0, sizeof(ignore_table));
3135
exit_code= get_options(&argc, &argv);
749
3138
free_resources();
750
3139
exit(exit_code);
754
db_connection = new DrizzleDumpConnection(current_host, opt_drizzle_port,
755
current_user, opt_password, use_drizzle_protocol);
757
catch (std::exception&)
759
maybe_exit(EX_DRIZZLEERR);
762
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
763
db_connection->queryNoResult("SET NAMES 'utf8'");
765
if (vm.count("destination-type"))
767
string tmp_destination(vm["destination-type"].as<string>());
768
if (tmp_destination.compare("database") == 0)
769
opt_destination= DESTINATION_DB;
770
else if (tmp_destination.compare("stdout") == 0)
771
opt_destination= DESTINATION_STDOUT;
773
exit(EXIT_ARGUMENT_INVALID);
777
if (path.empty() && vm.count("database-used"))
779
string database_used= *vm["database-used"].as< vector<string> >().begin();
780
write_header((char *)database_used.c_str());
783
if ((opt_lock_all_tables) && do_flush_tables_read_lock())
785
if (opt_single_transaction && start_transaction())
787
if (opt_lock_all_tables)
788
db_connection->queryNoResult("FLUSH LOGS");
789
if (opt_single_transaction && do_unlock_tables()) /* unlock but no commit! */
3142
if (connect_to_db(current_host, current_user, opt_password))
3145
exit(EX_DRIZZLEERR);
3148
write_header(md_result_file, *argv);
3150
if (opt_slave_data && do_stop_slave_sql(drizzle))
3153
if ((opt_lock_all_tables || opt_master_data) &&
3154
do_flush_tables_read_lock(drizzle))
3156
if (opt_single_transaction && start_transaction(drizzle))
3158
if (opt_delete_master_logs)
3160
if (drizzleclient_refresh(drizzle, REFRESH_LOG) ||
3161
get_bin_log_name(drizzle, bin_log_name, sizeof(bin_log_name)))
3165
if (opt_lock_all_tables || opt_master_data)
3167
if (flush_logs && drizzleclient_refresh(drizzle, REFRESH_LOG))
3169
flush_logs= 0; /* not anymore; that would not be sensible */
3171
/* Add 'STOP SLAVE to beginning of dump */
3172
if (opt_slave_apply && add_stop_slave())
3174
if (opt_master_data && do_show_master_status(drizzle))
3176
if (opt_slave_data && do_show_slave_status(drizzle))
3178
if (opt_single_transaction && do_unlock_tables(drizzle)) /* unlock but no commit! */
794
3183
dump_all_databases();
797
if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
3185
else if (argc > 1 && !opt_databases)
799
string database_used= *vm["database-used"].as< vector<string> >().begin();
800
3187
/* Only one database and selected table(s) */
801
dump_selected_tables(database_used, vm["Table-used"].as< vector<string> >());
804
if (vm.count("Table-used") and opt_databases)
806
vector<string> database_used= vm["database-used"].as< vector<string> >();
807
vector<string> table_used= vm["Table-used"].as< vector<string> >();
809
for (vector<string>::iterator it= table_used.begin();
810
it != table_used.end();
813
database_used.insert(database_used.end(), *it);
816
dump_databases(database_used);
820
if (vm.count("database-used") && ! vm.count("Table-used"))
822
dump_databases(vm["database-used"].as< vector<string> >());
826
if (opt_destination == DESTINATION_STDOUT)
3188
dump_selected_tables(*argv, (argv + 1), (argc - 1));
3192
dump_databases(argv);
3195
/* if --dump-slave , start the slave sql thread */
3196
if (opt_slave_data && do_start_slave_sql(drizzle))
3199
/* add 'START SLAVE' to end of dump */
3200
if (opt_slave_apply && add_slave_statements())
831
3203
/* ensure dumped data flushed */
832
3204
if (md_result_file && fflush(md_result_file))