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, uint length,
73
char **err_pos, uint *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 uint opt_master_data;
117
static uint opt_slave_data;
118
static uint 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
{"character-sets-dir", OPT_CHARSETS_DIR,
185
"Directory where character sets are.", (char**) &charsets_dir,
186
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
187
{"comments", 'i', "Write additional information.",
188
(char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
190
{"compatible", OPT_COMPATIBLE,
191
"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.",
192
(char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
193
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
194
{"compact", OPT_COMPACT,
195
"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",
196
(char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
198
{"complete-insert", 'c', "Use complete insert statements.",
199
(char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
200
NO_ARG, 0, 0, 0, 0, 0, 0},
201
{"compress", 'C', "Use compression in server/client protocol.",
202
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
204
{"create-options", OPT_CREATE_OPTIONS,
205
"Include all DRIZZLE specific create options.",
206
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
209
"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.",
210
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
212
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
213
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
214
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
215
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
216
(char**) &debug_info_flag, (char**) &debug_info_flag,
217
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
218
{"default-character-set", OPT_DEFAULT_CHARSET,
219
"Set the default character set.", (char**) &default_charset,
220
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
221
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
222
(char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
224
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
225
"Delete logs on master after backup. This automatically enables --master-data.",
226
(char**) &opt_delete_master_logs, (char**) &opt_delete_master_logs, 0,
227
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
228
{"disable-keys", 'K',
229
"'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.", (char**) &opt_disable_keys,
230
(char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
231
{"dump-slave", OPT_DRIZZLEDUMP_SLAVE_DATA,
232
"This causes the binary log position and filename of the master to be "
233
"appended to the dumped data output. Setting the value to 1, will print"
234
"it as a CHANGE MASTER command in the dumped data output; if equal"
235
" to 2, that command will be prefixed with a comment symbol. "
236
"This option will turn --lock-all-tables on, unless "
237
"--single-transaction is specified too (in which case a "
238
"global read lock is only taken a short time at the beginning of the dump "
239
"- don't forget to read about --single-transaction below). In all cases "
240
"any action on logs will happen at the exact moment of the dump."
241
"Option automatically turns --lock-tables off.",
242
(char**) &opt_slave_data, (char**) &opt_slave_data, 0,
243
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
244
{"extended-insert", 'e',
245
"Allows utilization of the new, much faster INSERT syntax.",
246
(char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
248
{"fields-terminated-by", OPT_FTB,
249
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
250
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
251
{"fields-enclosed-by", OPT_ENC,
252
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
253
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
254
{"fields-optionally-enclosed-by", OPT_O_ENC,
255
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
256
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
257
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
258
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
259
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
260
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
262
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
263
"Note that if you dump many databases at once (using the option "
264
"--databases= or --all-databases), the logs will be flushed for "
265
"each database dumped. The exception is when using --lock-all-tables "
267
"in this case the logs will be flushed only once, corresponding "
268
"to the moment all tables are locked. So if you want your dump and "
269
"the log flush to happen at the same exact moment you should use "
270
"--lock-all-tables or --master-data with --flush-logs",
271
(char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
273
{"force", 'f', "Continue even if we get an sql-error.",
274
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
276
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
277
NO_ARG, 0, 0, 0, 0, 0, 0},
278
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
279
"VARBINARY, BLOB) in hexadecimal format.",
280
(char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
281
{"host", 'h', "Connect to host.", (char**) ¤t_host,
282
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
283
{"ignore-table", OPT_IGNORE_TABLE,
284
"Do not dump the specified table. To specify more than one table to ignore, "
285
"use the directive multiple times, once for each table. Each table must "
286
"be specified with both database and table names, e.g. --ignore-table=database.table",
287
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
288
{"include-master-host-port", OPT_DRIZZLEDUMP_INCLUDE_MASTER_HOST_PORT,
289
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
290
(char**) &opt_include_master_host_port,
291
(char**) &opt_include_master_host_port,
294
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
295
(char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
297
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
298
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
299
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
300
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
301
"is achieved by taking a global read lock for the duration of the whole "
302
"dump. Automatically turns --single-transaction and --lock-tables off.",
303
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
305
{"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
306
(char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
307
{"master-data", OPT_MASTER_DATA,
308
"This causes the binary log position and filename to be appended to the "
309
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
310
" to 2, that command will be prefixed with a comment symbol. "
311
"This option will turn --lock-all-tables on, unless "
312
"--single-transaction is specified too (in which case a "
313
"global read lock is only taken a short time at the beginning of the dump "
314
"- don't forget to read about --single-transaction below). In all cases "
315
"any action on logs will happen at the exact moment of the dump."
316
"Option automatically turns --lock-tables off.",
317
(char**) &opt_master_data, (char**) &opt_master_data, 0,
318
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
319
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
320
(char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
321
GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
322
(int64_t) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
323
{"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
324
(char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0,
325
GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
326
MALLOC_OVERHEAD-1024, 1024, 0},
327
{"no-autocommit", OPT_AUTOCOMMIT,
328
"Wrap tables with autocommit/commit statements.",
329
(char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
331
{"no-create-db", 'n',
332
"'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.}.",
333
(char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
335
{"no-create-info", 't', "Don't write table creation info.",
336
(char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
337
NO_ARG, 0, 0, 0, 0, 0, 0},
338
{"no-data", 'd', "No row information.", (char**) &opt_no_data,
339
(char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
340
{"no-set-names", 'N',
341
"Deprecated. Use --skip-set-charset instead.",
342
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
343
{"opt", OPT_OPTIMIZE,
344
"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.",
345
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
346
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
347
"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.",
348
(char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
350
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
351
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
352
{"port", 'p', "Port number to use for connection.",
353
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
354
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
355
(char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
356
{"quote-names",'Q', "Quote table and column names with backticks (`).",
357
(char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
359
{"replace", OPT_DRIZZLE_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
360
(char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
363
"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).",
364
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
365
{"routines", 'R', "Dump stored routines (functions and procedures).",
366
(char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
367
NO_ARG, 0, 0, 0, 0, 0, 0},
369
Note that the combination --single-transaction --master-data
370
will give bullet-proof binlog position only if server >=4.1.3. That's the
371
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
373
{"single-transaction", OPT_TRANSACTION,
374
"Creates a consistent snapshot by dumping all tables in a single "
375
"transaction. Works ONLY for tables stored in storage engines which "
376
"support multiversioning (currently only InnoDB does); the dump is NOT "
377
"guaranteed to be consistent for other storage engines. "
378
"While a --single-transaction dump is in process, to ensure a valid "
379
"dump file (correct table contents and binary log position), no other "
380
"connection should use the following statements: ALTER TABLE, DROP "
381
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
382
"isolated from them. Option automatically turns off --lock-tables.",
383
(char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
384
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
385
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
386
(char**) &opt_dump_date, (char**) &opt_dump_date, 0,
387
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
388
{"skip-opt", OPT_SKIP_OPTIMIZATION,
389
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
390
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
392
"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.",
393
(char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
394
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
395
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
396
{"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of rows before each output progress report (requires --verbose)."),
397
(char**) &show_progress_size, (char**) &show_progress_size, 0, GET_ULONG, REQUIRED_ARG,
398
10000, 0, 0, 0, 0, 0},
399
#ifndef DONT_ALLOW_USER_CHANGE
400
{"user", 'u', "User for login if not current user.",
401
(char**) ¤t_user, (char**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
404
{"verbose", 'v', "Print info about the various stages.",
405
(char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
406
{"version",'V', "Output version information and exit.", 0, 0, 0,
407
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
408
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
409
(char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
410
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
411
NO_ARG, 0, 0, 0, 0, 0, 0},
412
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
415
static const char *load_default_groups[]= { "drizzledump","client",0 };
417
static void maybe_exit(int error);
147
418
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);
419
static void maybe_die(int error, const char* reason, ...);
420
static void write_header(FILE *sql_file, char *db_name);
421
static void print_value(FILE *file, DRIZZLE_RES *result, DRIZZLE_ROW row,
422
const char *prefix,const char *name,
424
static const char* fetch_named_row(DRIZZLE_RES *result, DRIZZLE_ROW row, const char* name);
425
static int dump_selected_tables(char *db, char **table_names, int tables);
426
static int dump_all_tables_in_db(char *db);
427
static int init_dumping_tables(char *);
428
static int init_dumping(char *, int init_func(char*));
429
static int dump_databases(char **);
151
430
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;
431
static char *quote_name(const char *name, char *buff, bool force);
432
char check_if_ignore_table(const char *table_name, char *table_type);
433
static char *primary_key_fields(const char *table_name);
436
Print the supplied message if in verbose mode
441
... variable number of parameters
443
static void verbose_msg(const char *fmt, ...)
452
vfprintf(stderr, fmt, args);
244
459
exit with message if ferror(file)
251
466
static void check_io(FILE *file)
335
893
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
338
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
896
fprintf(stderr, "%s: %s\n", my_progname, buffer);
341
899
ignore_errors= 0; /* force the exit */
342
900
maybe_exit(error_num);
905
Prints out an error message and maybe kills the process.
909
error_num - process return value
910
fmt_reason - a format string for use by vsnprintf.
911
... - variable arguments for above fmt_reason string
914
This call prints out the formatted error message to stderr and then
915
terminates the process, unless the --force command line option is used.
917
This call should be used for non-fatal errors (such as database
918
errors) that the code may still be able to continue to the next unit
922
static void maybe_die(int error_num, const char* fmt_reason, ...)
926
va_start(args,fmt_reason);
927
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
930
fprintf(stderr, "%s: %s\n", my_progname, buffer);
933
maybe_exit(error_num);
939
Sends a query to server, optionally reads result, prints error message if
943
drizzleclient_query_with_error_report()
944
drizzle_con connection to use
945
res if non zero, result will be put there with
946
drizzleclient_store_result()
947
query query to send to server
950
0 query sending and (if res!=0) result reading went ok
954
static int drizzleclient_query_with_error_report(DRIZZLE *drizzle_con, DRIZZLE_RES **res,
957
if (drizzleclient_query(drizzle_con, query) ||
958
(res && !((*res)= drizzleclient_store_result(drizzle_con))))
960
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
961
query, drizzleclient_error(drizzle_con), drizzleclient_errno(drizzle_con));
968
Open a new .sql file to dump the table or view into
971
open_sql_file_for_table
972
name name of the table or view
975
0 Failed to open file
976
> 0 Handle of the open file
978
static FILE* open_sql_file_for_table(const char* table)
981
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
982
convert_dirname(tmp_path,path,NULL);
983
res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
984
O_WRONLY, MYF(MY_WME));
345
989
static void free_resources(void)
347
991
if (md_result_file && md_result_file != stdout)
348
fclose(md_result_file);
349
opt_password.erase();
992
my_fclose(md_result_file, MYF(0));
994
if (hash_inited(&ignore_table))
995
hash_free(&ignore_table);
997
free_defaults(defaults_argv);
353
void maybe_exit(int error)
1002
static void maybe_exit(int error)
355
1004
if (!first_error)
356
1005
first_error= error;
357
1006
if (ignore_errors)
359
delete db_connection;
360
delete destination_connection;
1009
drizzleclient_close(drizzle);
361
1010
free_resources();
1016
db_connect -- connects to the host and selects DB.
1019
static int connect_to_db(char *host, char *user,char *passwd)
1021
verbose_msg(_("-- Connecting to %s...\n"), host ? host : "localhost");
1022
drizzleclient_create(&drizzleclient_connection);
1024
drizzleclient_options(&drizzleclient_connection,DRIZZLE_OPT_COMPRESS,NULL);
1025
if (!(drizzle= drizzleclient_connect(&drizzleclient_connection,host,user,passwd,
1026
NULL,opt_drizzle_port, NULL,
1029
DB_error(&drizzleclient_connection, "when trying to connect");
1034
} /* connect_to_db */
1038
** dbDisconnect -- disconnects from the host.
1040
static void dbDisconnect(char *host)
1042
verbose_msg(_("-- Disconnecting from %s...\n"), host ? host : "localhost");
1043
drizzleclient_close(drizzle);
1044
} /* dbDisconnect */
1047
static void unescape(FILE *file,char *pos,uint length)
1051
if (!(tmp=(char*) malloc(length*2+1)))
1052
die(EX_DRIZZLEERR, _("Couldn't allocate memory"));
1054
drizzleclient_escape_string(tmp, pos, length);
1064
static bool test_if_special_chars(const char *str)
1066
for ( ; *str ; str++)
1067
if (!my_isvar(charset_info,*str) && *str != '$')
1070
} /* test_if_special_chars */
1075
quote_name(name, buff, force)
1077
Quotes char string, taking into account compatible mode
1081
name Unquoted string containing that which will be quoted
1082
buff The buffer that contains the quoted value, also returned
1083
force Flag to make it ignore 'test_if_special_chars'
1090
static char *quote_name(const char *name, char *buff, bool force)
1093
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1095
if (!force && !opt_quoted && !test_if_special_chars(name))
1096
return (char*) name;
1111
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1115
name name of the table
1116
buff quoted name of the table
1119
Quote \, _, ' and % characters
1121
Note: Because DRIZZLE uses the C escape syntax in strings
1122
(for example, '\n' to represent newline), you must double
1123
any '\' that you use in your LIKE strings. For example, to
1124
search for '\n', specify it as '\\n'. To search for '\', specify
1125
it as '\\\\' (the backslashes are stripped once by the parser
1126
and another time when the pattern match is done, leaving a
1127
single backslash to be matched).
1129
Example: "t\1" => "t\\\\1"
1132
static char *quote_for_like(const char *name, char *buff)
1144
else if (*name == '\'' || *name == '_' || *name == '%')
1155
Quote and print a string.
1159
xml_file - output file
1160
str - string to print
1164
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1167
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
1171
for (end= str + len; str != end; str++)
1175
fputs("<", xml_file);
1178
fputs(">", xml_file);
1181
fputs("&", xml_file);
1184
fputs(""", xml_file);
1187
fputc(*str, xml_file);
1196
Print xml tag. Optionally add attribute(s).
1199
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1200
..., attribute_name_n, attribute_value_n, NULL)
1201
xml_file - output file
1202
sbeg - line beginning
1203
line_end - line ending
1204
tag_name - XML tag name.
1205
first_attribute_name - tag and first attribute
1206
first_attribute_value - (Implied) value of first attribute
1207
attribute_name_n - attribute n
1208
attribute_value_n - value of attribute n
1211
Print XML tag with any number of attribute="value" pairs to the xml_file.
1214
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1215
attribute_name_n="attribute_value_n">send
1217
Additional arguments must be present in attribute/value pairs.
1218
The last argument should be the null character pointer.
1219
All attribute_value arguments MUST be NULL terminated strings.
1220
All attribute_value arguments will be quoted before output.
1223
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1224
const char* line_end,
1225
const char* tag_name,
1226
const char* first_attribute_name, ...)
1229
const char *attribute_name, *attribute_value;
1231
fputs(sbeg, xml_file);
1232
fputc('<', xml_file);
1233
fputs(tag_name, xml_file);
1235
va_start(arg_list, first_attribute_name);
1236
attribute_name= first_attribute_name;
1237
while (attribute_name != NULL)
1239
attribute_value= va_arg(arg_list, char *);
1240
assert(attribute_value != NULL);
1242
fputc(' ', xml_file);
1243
fputs(attribute_name, xml_file);
1244
fputc('\"', xml_file);
1246
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1247
fputc('\"', xml_file);
1249
attribute_name= va_arg(arg_list, char *);
1253
fputc('>', xml_file);
1254
fputs(line_end, xml_file);
1260
Print xml tag with for a field that is null
1263
print_xml_null_tag()
1264
xml_file - output file
1265
sbeg - line beginning
1266
stag_atr - tag and attribute
1267
sval - value of attribute
1268
line_end - line ending
1271
Print tag with one attribute to the xml_file. Format is:
1272
<stag_atr="sval" xsi:nil="true"/>
1274
sval MUST be a NULL terminated string.
1275
sval string will be qouted before output.
1278
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1279
const char* stag_atr, const char* sval,
1280
const char* line_end)
1282
fputs(sbeg, xml_file);
1283
fputs("<", xml_file);
1284
fputs(stag_atr, xml_file);
1285
fputs("\"", xml_file);
1286
print_quoted_xml(xml_file, sval, strlen(sval));
1287
fputs("\" xsi:nil=\"true\" />", xml_file);
1288
fputs(line_end, xml_file);
1294
Print xml tag with many attributes.
1298
xml_file - output file
1299
row_name - xml tag name
1300
tableRes - query result
1304
Print tag with many attribute to the xml_file. Format is:
1305
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1307
All atributes and values will be quoted before output.
1310
static void print_xml_row(FILE *xml_file, const char *row_name,
1311
DRIZZLE_RES *tableRes, DRIZZLE_ROW *row)
1314
DRIZZLE_FIELD *field;
1315
uint32_t *lengths= drizzleclient_fetch_lengths(tableRes);
1317
fprintf(xml_file, "\t\t<%s", row_name);
1319
drizzleclient_field_seek(tableRes, 0);
1320
for (i= 0; (field= drizzleclient_fetch_field(tableRes)); i++)
1324
fputc(' ', xml_file);
1325
print_quoted_xml(xml_file, field->name, field->name_length);
1326
fputs("=\"", xml_file);
1327
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1328
fputc('"', xml_file);
1332
fputs(" />\n", xml_file);
1338
Print hex value for blob data.
1342
output_file - output file
1343
str - string to print
1347
Print hex value for blob data.
1350
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
1352
/* sakaik got the idea to to provide blob's in hex notation. */
1353
const char *ptr= str, *end= ptr + len;
1354
for (; ptr < end ; ptr++)
1355
fprintf(output_file, "%02X", *((unsigned char *)ptr));
1356
check_io(output_file);
1360
get_table_structure -- retrievs database structure, prints out corresponding
1361
CREATE statement and fills out insert_pat if the table is the type we will
1367
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1368
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1369
num_fields - number of fields in the table
1372
true if success, false if error
1375
static bool get_table_structure(char *table, char *db, char *table_type,
1376
char *ignore_flag, uint64_t *num_fields)
1378
bool init=0, delayed, write_data, complete_insert;
1379
char *result_table, *opt_quoted_table;
1380
const char *insert_option;
1381
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
1382
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
1383
FILE *sql_file= md_result_file;
1384
DRIZZLE_RES *result;
1387
*ignore_flag= check_if_ignore_table(table, table_type);
1389
delayed= opt_delayed;
1390
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
1393
verbose_msg(_("-- Warning: Unable to use delayed inserts for table '%s' "
1394
"because it's of type %s\n"), table, table_type);
1398
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1400
complete_insert= opt_complete_insert;
1404
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1405
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
1407
verbose_msg(_("-- Retrieving table structure for table %s...\n"), table);
1409
result_table= quote_name(table, table_buff, 1);
1410
opt_quoted_table= quote_name(table, table_buff2, 0);
1412
if (opt_order_by_primary)
1415
order_by= primary_key_fields(result_table);
1420
/* using SHOW CREATE statement */
1421
if (!opt_no_create_info)
1423
/* Make an sql-file, if path was given iow. option -T was given */
1424
char buff[20+FN_REFLEN];
1425
const DRIZZLE_FIELD *field;
1427
snprintf(buff, sizeof(buff), "show create table %s", result_table);
1429
if (drizzleclient_query_with_error_report(drizzle, &result, buff))
1434
if (!(sql_file= open_sql_file_for_table(table)))
1437
write_header(sql_file, db);
1439
if (!opt_xml && opt_comments)
1441
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1448
Even if the "table" is a view, we do a DROP TABLE here.
1450
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
1454
field= drizzleclient_fetch_field_direct(result, 0);
1456
row= drizzleclient_fetch_row(result);
1458
fprintf(sql_file, "%s;\n", row[1]);
1461
drizzleclient_free_result(result);
1463
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1465
if (drizzleclient_query_with_error_report(drizzle, &result, query_buff))
1468
my_fclose(sql_file, MYF(MY_WME));
1473
If write_data is true, then we build up insert statements for
1474
the table's data. Note: in subsequent lines of code, this test
1475
will have to be performed each time we are appending to
1480
if (opt_replace_into)
1481
insert_pat.append("REPLACE ");
1483
insert_pat.append("INSERT ");
1484
insert_pat.append(insert_option);
1485
insert_pat.append("INTO ");
1486
insert_pat.append(opt_quoted_table);
1487
if (complete_insert)
1489
insert_pat.append(" (");
1493
insert_pat.append(" VALUES ");
1494
if (!extended_insert)
1495
insert_pat.append("(");
1499
while ((row= drizzleclient_fetch_row(result)))
1501
if (complete_insert)
1505
insert_pat.append(", ");
1508
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1511
*num_fields= drizzleclient_num_rows(result);
1512
drizzleclient_free_result(result);
1516
verbose_msg(_("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n"),
1517
my_progname, drizzleclient_error(drizzle));
1519
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1521
if (drizzleclient_query_with_error_report(drizzle, &result, query_buff))
1524
/* Make an sql-file, if path was given iow. option -T was given */
1525
if (!opt_no_create_info)
1529
if (!(sql_file= open_sql_file_for_table(table)))
1531
write_header(sql_file, db);
1533
if (!opt_xml && opt_comments)
1534
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1537
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1539
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1541
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1548
if (opt_replace_into)
1549
insert_pat.append("REPLACE ");
1551
insert_pat.append("INSERT ");
1552
insert_pat.append(insert_option);
1553
insert_pat.append("INTO ");
1554
insert_pat.append(result_table);
1555
if (complete_insert)
1556
insert_pat.append(" (");
1559
insert_pat.append(" VALUES ");
1560
if (!extended_insert)
1561
insert_pat.append("(");
1565
while ((row= drizzleclient_fetch_row(result)))
1567
uint32_t *lengths= drizzleclient_fetch_lengths(result);
1570
if (!opt_xml && !opt_no_create_info)
1572
fputs(",\n",sql_file);
1575
if (complete_insert)
1576
insert_pat.append(", ");
1579
if (complete_insert)
1580
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1581
if (!opt_no_create_info)
1585
print_xml_row(sql_file, "field", result, &row);
1590
fprintf(sql_file, " %s.%s %s", result_table,
1591
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1594
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1597
if (row[SHOW_DEFAULT])
1599
fputs(" DEFAULT ", sql_file);
1600
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1602
if (!row[SHOW_NULL][0])
1603
fputs(" NOT NULL", sql_file);
1604
if (row[SHOW_EXTRA][0])
1605
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1609
*num_fields= drizzleclient_num_rows(result);
1610
drizzleclient_free_result(result);
1611
if (!opt_no_create_info)
1613
/* Make an sql-file, if path was given iow. option -T was given */
1614
char buff[20+FN_REFLEN];
1615
uint keynr,primary_key;
1616
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1617
if (drizzleclient_query_with_error_report(drizzle, &result, buff))
1619
if (drizzleclient_errno(drizzle) == ER_WRONG_OBJECT)
1622
fputs("\t\t<options Comment=\"view\" />\n", sql_file);
1625
fprintf(stderr, _("%s: Can't get keys for table %s (%s)\n"),
1626
my_progname, result_table, drizzleclient_error(drizzle));
1628
my_fclose(sql_file, MYF(MY_WME));
1632
/* Find first which key is primary key */
1634
primary_key=INT_MAX;
1635
while ((row= drizzleclient_fetch_row(result)))
1637
if (atoi(row[3]) == 1)
1640
#ifdef FORCE_PRIMARY_KEY
1641
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1644
if (!strcmp(row[2],"PRIMARY"))
1651
drizzleclient_data_seek(result,0);
1653
while ((row= drizzleclient_fetch_row(result)))
1657
print_xml_row(sql_file, "key", result, &row);
1661
if (atoi(row[3]) == 1)
1664
putc(')', sql_file);
1665
if (atoi(row[1])) /* Test if duplicate key */
1666
/* Duplicate allowed */
1667
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1668
else if (keynr == primary_key)
1669
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1671
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1675
putc(',', sql_file);
1676
fputs(quote_name(row[4], name_buff, 0), sql_file);
1678
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1681
drizzleclient_free_result(result);
1685
putc(')', sql_file);
1686
fputs("\n)",sql_file);
1689
/* Get DRIZZLE specific create options */
1692
char show_name_buff[NAME_LEN*2+2+24];
1694
/* Check memory for quote_for_like() */
1695
snprintf(buff, sizeof(buff), "show table status like %s",
1696
quote_for_like(table, show_name_buff));
1698
if (drizzleclient_query_with_error_report(drizzle, &result, buff))
1700
if (drizzleclient_errno(drizzle) != ER_PARSE_ERROR)
1701
{ /* If old DRIZZLE version */
1702
verbose_msg(_("-- Warning: Couldn't get status information for " \
1703
"table %s (%s)\n"), result_table,drizzleclient_error(drizzle));
1706
else if (!(row= drizzleclient_fetch_row(result)))
1709
_("Error: Couldn't read status information for table %s (%s)\n"),
1710
result_table,drizzleclient_error(drizzle));
1715
print_xml_row(sql_file, "options", result, &row);
1718
fputs("/*!",sql_file);
1719
print_value(sql_file,result,row,"engine=","Engine",0);
1720
print_value(sql_file,result,row,"","Create_options",0);
1721
print_value(sql_file,result,row,"comment=","Comment",1);
1723
fputs(" */",sql_file);
1727
drizzleclient_free_result(result); /* Is always safe to free */
1731
fputs(";\n", sql_file);
1733
fputs("\t</table_structure>\n", sql_file);
1737
if (complete_insert) {
1738
insert_pat.append(") VALUES ");
1739
if (!extended_insert)
1740
insert_pat.append("(");
1742
if (sql_file != md_result_file)
1744
fputs("\n", sql_file);
1745
write_footer(sql_file);
1746
my_fclose(sql_file, MYF(MY_WME));
1749
} /* get_table_structure */
1751
static void add_load_option(string &str, const char *option,
1752
const char *option_value)
1756
/* Null value means we don't add this option. */
1762
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
1764
/* It's a hex constant, don't escape */
1765
str.append(option_value);
1769
/* char constant; escape */
1770
field_escape(str, option_value);
1776
Allow the user to specify field terminator strings like:
1777
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
1778
This is done by doubling ' and add a end -\ if needed to avoid
1779
syntax errors from the SQL parser.
1782
static void field_escape(string &in, const char *from)
1784
uint end_backslashes= 0;
1793
end_backslashes^=1; /* find odd number of backslashes */
1796
if (*from == '\'' && !end_backslashes)
1798
/* We want a duplicate of "'" for DRIZZLE */
1805
/* Add missing backslashes if user has specified odd number of backs.*/
1806
if (end_backslashes)
1819
dump_table saves database contents as a series of INSERT statements.
1830
static void dump_table(char *table, char *db)
1833
char buf[200], table_buff[NAME_LEN+3];
1834
string query_string;
1835
char table_type[NAME_LEN];
1836
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
1838
uint32_t rownr, row_break, total_length, init_length;
1839
uint64_t num_fields= 0;
1841
DRIZZLE_FIELD *field;
1846
Make sure you get the create table info before the following check for
1847
--no-data flag below. Otherwise, the create table info won't be printed.
1849
if (!get_table_structure(table, db, table_type, &ignore_flag, &num_fields))
1851
maybe_die(EX_TABLE_STATUS, _("Error retrieving table structure for table: \"%s\""), table);
1855
/* Check --no-data flag */
1858
verbose_msg(_("-- Skipping dump data for table '%s', --no-data was used\n"),
1864
If the table type is a merge table or any type that has to be
1865
_completely_ ignored and no data dumped
1867
if (ignore_flag & IGNORE_DATA)
1869
verbose_msg(_("-- Warning: Skipping data for table '%s' because " \
1870
"it's of type %s\n"), table, table_type);
1873
/* Check that there are any fields in the table */
1874
if (num_fields == 0)
1876
verbose_msg(_("-- Skipping dump data for table '%s', it has no fields\n"),
1881
result_table= quote_name(table,table_buff, 1);
1882
opt_quoted_table= quote_name(table, table_buff2, 0);
1884
verbose_msg(_("-- Sending SELECT query...\n"));
1886
query_string.clear();
1887
query_string.reserve(1024);
1891
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1894
Convert the path to native os format
1895
and resolve to the full filepath.
1897
convert_dirname(tmp_path,path,NULL);
1898
my_load_path(tmp_path, tmp_path, NULL);
1899
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1901
/* Must delete the file that 'INTO OUTFILE' will write to */
1902
my_delete(filename, MYF(0));
1904
/* now build the query string */
1906
query_string.append( "SELECT * INTO OUTFILE '");
1907
query_string.append( filename);
1908
query_string.append( "'");
1910
if (fields_terminated || enclosed || opt_enclosed || escaped)
1911
query_string.append( " FIELDS");
1913
add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1914
add_load_option(query_string, " ENCLOSED BY ", enclosed);
1915
add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
1916
add_load_option(query_string, " ESCAPED BY ", escaped);
1917
add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
1919
query_string.append( " FROM ");
1920
query_string.append( result_table);
1924
query_string.append( " WHERE ");
1925
query_string.append( where);
1930
query_string.append( " ORDER BY ");
1931
query_string.append( order_by);
1934
if (drizzleclient_real_query(drizzle, query_string.c_str(), query_string.length()))
1936
DB_error(drizzle, _("when executing 'SELECT INTO OUTFILE'"));
1942
if (!opt_xml && opt_comments)
1944
fprintf(md_result_file,_("\n--\n-- Dumping data for table %s\n--\n"),
1946
check_io(md_result_file);
1949
query_string.append( "SELECT * FROM ");
1950
query_string.append( result_table);
1954
if (!opt_xml && opt_comments)
1956
fprintf(md_result_file, "-- WHERE: %s\n", where);
1957
check_io(md_result_file);
1960
query_string.append( " WHERE ");
1961
query_string.append( where);
1965
if (!opt_xml && opt_comments)
1967
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
1968
check_io(md_result_file);
1970
query_string.append( " ORDER BY ");
1971
query_string.append( order_by);
1974
if (!opt_xml && !opt_compact)
1976
fputs("\n", md_result_file);
1977
check_io(md_result_file);
1979
if (drizzleclient_query_with_error_report(drizzle, 0, query_string.c_str()))
1981
DB_error(drizzle, _("when retrieving data from server"));
1985
res=drizzleclient_use_result(drizzle);
1987
res=drizzleclient_store_result(drizzle);
1990
DB_error(drizzle, _("when retrieving data from server"));
1994
verbose_msg(_("-- Retrieving rows...\n"));
1995
if (drizzleclient_num_fields(res) != num_fields)
1997
fprintf(stderr,_("%s: Error in field count for table: %s ! Aborting.\n"),
1998
my_progname, result_table);
1999
error= EX_CONSCHECK;
2005
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2006
check_io(md_result_file);
2008
/* Moved disable keys to after lock per bug 15977 */
2009
if (opt_disable_keys)
2011
fprintf(md_result_file, "ALTER TABLE %s DISABLE KEYS;\n",
2013
check_io(md_result_file);
2016
total_length= opt_net_buffer_length; /* Force row break */
2019
init_length=(uint) insert_pat.length()+4;
2021
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2025
fprintf(md_result_file, "set autocommit=0;\n");
2026
check_io(md_result_file);
2029
while ((row= drizzleclient_fetch_row(res)))
2032
uint32_t *lengths= drizzleclient_fetch_lengths(res);
2034
if ((rownr % show_progress_size) == 0)
2036
verbose_msg(_("-- %"PRIu32" of ~%"PRIu64" rows dumped for table %s\n"), rownr, total_rows, opt_quoted_table);
2038
if (!extended_insert && !opt_xml)
2040
fputs(insert_pat.c_str(),md_result_file);
2041
check_io(md_result_file);
2043
drizzleclient_field_seek(res,0);
2047
fputs("\t<row>\n", md_result_file);
2048
check_io(md_result_file);
2051
for (i= 0; i < drizzleclient_num_fields(res); i++)
2054
uint32_t length= lengths[i];
2056
if (!(field= drizzleclient_fetch_field(res)))
2058
_("Not enough fields from table %s! Aborting.\n"),
2062
63 is my_charset_bin. If charsetnr is not 63,
2063
we have not a BLOB but a TEXT column.
2064
we'll dump in hex only BLOB columns.
2066
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
2067
(field->type == DRIZZLE_TYPE_VARCHAR ||
2068
field->type == DRIZZLE_TYPE_BLOB)) ? 1 : 0;
2069
if (extended_insert && !opt_xml)
2073
extended_row.clear();
2074
extended_row.append("(");
2077
extended_row.append(",");
2083
if (!(field->type & NUM_FLAG))
2086
"length * 2 + 2" is OK for both HEX and non-HEX modes:
2087
- In HEX mode we need exactly 2 bytes per character
2088
plus 2 bytes for '0x' prefix.
2089
- In non-HEX mode we need up to 2 bytes per character,
2090
plus 2 bytes for leading and trailing '\'' characters.
2091
Also we need to reserve 1 byte for terminating '\0'.
2093
char * tmp_str= (char *)malloc(length * 2 + 2 + 1);
2094
memset(tmp_str, '\0', length * 2 + 2 + 1);
2095
if (opt_hex_blob && is_blob)
2097
extended_row.append("0x");
2098
drizzleclient_drizzleclient_octet2hex(tmp_str, row[i], length);
2099
extended_row.append(tmp_str);
2103
extended_row.append("'");
2104
drizzleclient_escape_string(tmp_str,
2106
extended_row.append(tmp_str);
2107
extended_row.append("'");
2113
/* change any strings ("inf", "-inf", "nan") into NULL */
2115
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2116
my_isalpha(charset_info, ptr[1])))
2117
extended_row.append( "NULL");
2120
extended_row.append( ptr);
2125
extended_row.append("''");
2128
extended_row.append("NULL");
2134
fputc(',', md_result_file);
2135
check_io(md_result_file);
2139
if (!(field->type & NUM_FLAG))
2143
if (opt_hex_blob && is_blob && length)
2145
/* Define xsi:type="xs:hexBinary" for hex encoded data */
2146
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2147
field->name, "xsi:type=", "xs:hexBinary", NULL);
2148
print_blob_as_hex(md_result_file, row[i], length);
2152
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2154
print_quoted_xml(md_result_file, row[i], length);
2156
fputs("</field>\n", md_result_file);
2158
else if (opt_hex_blob && is_blob && length)
2160
fputs("0x", md_result_file);
2161
print_blob_as_hex(md_result_file, row[i], length);
2164
unescape(md_result_file, row[i], length);
2168
/* change any strings ("inf", "-inf", "nan") into NULL */
2172
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2174
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2176
fputs("</field>\n", md_result_file);
2178
else if (my_isalpha(charset_info, *ptr) ||
2179
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
2180
fputs("NULL", md_result_file);
2182
fputs(ptr, md_result_file);
2187
/* The field value is NULL */
2189
fputs("NULL", md_result_file);
2191
print_xml_null_tag(md_result_file, "\t\t", "field name=",
2194
check_io(md_result_file);
2200
fputs("\t</row>\n", md_result_file);
2201
check_io(md_result_file);
2204
if (extended_insert)
2206
uint32_t row_length;
2207
extended_row.append(")");
2208
row_length= 2 + extended_row.length();
2209
if (total_length + row_length < opt_net_buffer_length)
2211
total_length+= row_length;
2212
fputc(',',md_result_file); /* Always row break */
2213
fputs(extended_row.c_str(),md_result_file);
2218
fputs(";\n", md_result_file);
2219
row_break=1; /* This is first row */
2221
fputs(insert_pat.c_str(),md_result_file);
2222
fputs(extended_row.c_str(),md_result_file);
2223
total_length= row_length+init_length;
2225
check_io(md_result_file);
2229
fputs(");\n", md_result_file);
2230
check_io(md_result_file);
2234
/* XML - close table tag and supress regular output */
2236
fputs("\t</table_data>\n", md_result_file);
2237
else if (extended_insert && row_break)
2238
fputs(";\n", md_result_file); /* If not empty table */
2239
fflush(md_result_file);
2240
check_io(md_result_file);
2241
if (drizzleclient_errno(drizzle))
2243
snprintf(buf, sizeof(buf),
2244
_("%s: Error %d: %s when dumping table %s at row: %d\n"),
2246
drizzleclient_errno(drizzle),
2247
drizzleclient_error(drizzle),
2251
error= EX_CONSCHECK;
2255
/* Moved enable keys to before unlock per bug 15977 */
2256
if (opt_disable_keys)
2258
fprintf(md_result_file,"ALTER TABLE %s ENABLE KEYS;\n",
2260
check_io(md_result_file);
2264
fputs("UNLOCK TABLES;\n", md_result_file);
2265
check_io(md_result_file);
2269
fprintf(md_result_file, "commit;\n");
2270
check_io(md_result_file);
2272
drizzleclient_free_result(res);
2282
static char *getTableName(int reset)
2284
static DRIZZLE_RES *res= NULL;
2289
if (!(res= drizzleclient_list_tables(drizzle,NULL)))
2292
if ((row= drizzleclient_fetch_row(res)))
2293
return((char*) row[0]);
2296
drizzleclient_data_seek(res,0); /* We want to read again */
2299
drizzleclient_free_result(res);
2303
} /* getTableName */
365
2306
static int dump_all_databases()
368
drizzle_result_st *tableres;
2309
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)))
2312
if (drizzleclient_query_with_error_report(drizzle, &tableres, "SHOW DATABASES"))
2314
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);
2316
if (dump_all_tables_in_db(row[0]))
394
db_connection->freeResult(tableres);
397
2321
/* dump_all_databases */
400
static int dump_databases(const vector<string> &db_names)
2324
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)
2330
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);
2332
if (dump_all_tables_in_db(*db))
416
2336
} /* 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);
2340
Table Specific database initalization.
2344
qdatabase quoted name of the database
2351
int init_dumping_tables(char *qdatabase)
2359
DRIZZLE_RES *dbinfo;
2361
snprintf(qbuf, sizeof(qbuf),
2362
"SHOW CREATE DATABASE IF NOT EXISTS %s",
2365
if (drizzleclient_query(drizzle, qbuf) || !(dbinfo = drizzleclient_store_result(drizzle)))
2367
/* Old server version, dump generic CREATE DATABASE */
2368
if (opt_drop_database)
2369
fprintf(md_result_file,
2370
"\nDROP DATABASE IF EXISTS %s;\n",
2372
fprintf(md_result_file,
2373
"\nCREATE DATABASE IF NOT EXISTS %s;\n",
2378
if (opt_drop_database)
2379
fprintf(md_result_file,
2380
"\nDROP DATABASE IF EXISTS %s;\n",
2382
row = drizzleclient_fetch_row(dbinfo);
2385
fprintf(md_result_file,"\n%s;\n",row[1]);
2387
drizzleclient_free_result(dbinfo);
2391
} /* init_dumping_tables */
2394
static int init_dumping(char *database, int init_func(char*))
2396
if (drizzleclient_get_server_version(drizzle) >= 50003 &&
2397
!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
2400
if (drizzleclient_select_db(drizzle, database))
2402
DB_error(drizzle, _("when selecting the database"));
2403
return 1; /* If --force */
2405
if (!path && !opt_xml)
2407
if (opt_databases || opt_alldbs)
2410
length of table name * 2 (if name contains quotes), 2 quotes and 0
2412
char quoted_database_buf[NAME_LEN*2+3];
2413
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
2416
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
2417
check_io(md_result_file);
2420
/* Call the view or table specific function */
2421
init_func(qdatabase);
2423
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
2424
check_io(md_result_file);
2427
if (extended_insert)
2428
extended_row.clear();
2430
} /* init_dumping */
2433
/* Return 1 if we should copy the table */
2435
static bool include_table(const unsigned char *hash_key, size_t len)
2437
return !hash_search(&ignore_table, hash_key, len);
2441
static int dump_all_tables_in_db(char *database)
2445
char table_buff[NAME_LEN*2+3];
2446
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
2449
afterdot= strcpy(hash_key, database) + strlen(database);
2452
if (init_dumping(database, init_dumping_tables))
2455
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
2458
string query("LOCK TABLES ");
2459
for (numrows= 0 ; (table= getTableName(1)) ; )
2461
char *end= strcpy(afterdot, table) + strlen(table);
2462
if (include_table((unsigned char*) hash_key,end - hash_key))
2465
query.append( quote_name(table, table_buff, 1));
2466
query.append( " READ LOCAL,");
2469
if (numrows && drizzleclient_real_query(drizzle, query.c_str(), query.length()-1))
2470
DB_error(drizzle, _("when using LOCK TABLES"));
2471
/* We shall continue here, if --force was given */
2476
if (drizzleclient_refresh(drizzle, REFRESH_LOG))
2477
DB_error(drizzle, _("when doing refresh"));
2478
/* We shall continue here, if --force was given */
2480
while ((table= getTableName(0)))
2482
char *end= strcpy(afterdot, table) + strlen(table);
2483
if (include_table((unsigned char*) hash_key, end - hash_key))
2485
dump_table(table,database);
2492
fputs("</database>\n", md_result_file);
2493
check_io(md_result_file);
2496
drizzleclient_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
2499
} /* dump_all_tables_in_db */
2503
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2504
table name from the server for the table name given on the command line.
2505
we do this because the table name given on the command line may be a
2506
different case (e.g. T1 vs t1)
2509
pointer to the table name
2513
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2516
DRIZZLE_RES *table_res;
2518
char query[50 + 2*NAME_LEN];
2519
char show_name_buff[FN_REFLEN];
2522
/* Check memory for quote_for_like() */
2523
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2524
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2525
quote_for_like(old_table_name, show_name_buff));
2527
if (drizzleclient_query_with_error_report(drizzle, 0, query))
2530
if ((table_res= drizzleclient_store_result(drizzle)))
2532
uint64_t num_rows= drizzleclient_num_rows(table_res);
2538
TODO: Return all matching rows
2540
row= drizzleclient_fetch_row(table_res);
2541
lengths= drizzleclient_fetch_lengths(table_res);
2542
name= strmake_root(root, row[0], lengths[0]);
2544
drizzleclient_free_result(table_res);
2550
static int dump_selected_tables(char *db, char **table_names, int tables)
2552
char table_buff[NAME_LEN*2+3];
2553
string lock_tables_query("LOCK TABLES ");
2555
char **dump_tables, **pos, **end;
2558
if (init_dumping(db, init_dumping_tables))
2561
init_alloc_root(&root, 8192, 0);
2562
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2563
die(EX_EOM, _("alloc_root failure."));
2565
for (; tables > 0 ; tables-- , table_names++)
2567
/* the table name passed on commandline may be wrong case */
2568
if ((*pos= get_actual_table_name(*table_names, &root)))
2570
/* Add found table name to lock_tables_query */
2573
lock_tables_query.append( quote_name(*pos, table_buff, 1));
2574
lock_tables_query.append( " READ LOCAL,");
2582
free_root(&root, MYF(0));
2584
maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""), *table_names);
2585
/* We shall countinue here, if --force was given */
2592
if (drizzleclient_real_query(drizzle, lock_tables_query.c_str(),
2593
lock_tables_query.length()-1))
2597
free_root(&root, MYF(0));
2599
DB_error(drizzle, _("when doing LOCK TABLES"));
2600
/* We shall countinue here, if --force was given */
2605
if (drizzleclient_refresh(drizzle, REFRESH_LOG))
2608
free_root(&root, MYF(0));
2609
DB_error(drizzle, _("when doing refresh"));
2611
/* We shall countinue here, if --force was given */
2614
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NULL);
2616
/* Dump each selected table */
2617
for (pos= dump_tables; pos < end; pos++)
2618
dump_table(*pos, db);
2620
free_root(&root, MYF(0));
2625
fputs("</database>\n", md_result_file);
2626
check_io(md_result_file);
2629
drizzleclient_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
437
2631
} /* dump_selected_tables */
439
static int do_flush_tables_read_lock()
2634
static int do_show_master_status(DRIZZLE *drizzle_con)
2637
DRIZZLE_RES *master;
2638
const char *comment_prefix=
2639
(opt_master_data == DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
2640
if (drizzleclient_query_with_error_report(drizzle_con, &master, "SHOW MASTER STATUS"))
2646
row= drizzleclient_fetch_row(master);
2647
if (row && row[0] && row[1])
2649
/* SHOW MASTER STATUS reports file and position */
2651
fprintf(md_result_file,
2652
"\n--\n-- Position to start replication or point-in-time "
2653
"recovery from\n--\n\n");
2654
fprintf(md_result_file,
2655
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
2656
comment_prefix, row[0], row[1]);
2657
check_io(md_result_file);
2659
else if (!ignore_errors)
2661
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2662
my_printf_error(0, _("Error: Binlogging on server not active"),
2664
drizzleclient_free_result(master);
2665
maybe_exit(EX_DRIZZLEERR);
2668
drizzleclient_free_result(master);
2673
static int do_stop_slave_sql(DRIZZLE *drizzle_con)
2676
/* We need to check if the slave sql is running in the first place */
2677
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2681
DRIZZLE_ROW row= drizzleclient_fetch_row(slave);
2684
/* if SLAVE SQL is not running, we don't stop it */
2685
if (!strcmp(row[11],"No"))
2687
drizzleclient_free_result(slave);
2688
/* Silently assume that they don't have the slave running */
2693
drizzleclient_free_result(slave);
2695
/* now, stop slave if running */
2696
if (drizzleclient_query_with_error_report(drizzle_con, 0, "STOP SLAVE SQL_THREAD"))
2702
static int add_stop_slave(void)
2705
fprintf(md_result_file,
2706
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
2707
fprintf(md_result_file, "STOP SLAVE;\n");
2711
static int add_slave_statements(void)
2714
fprintf(md_result_file,
2715
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
2716
fprintf(md_result_file, "START SLAVE;\n");
2720
static int do_show_slave_status(DRIZZLE *drizzle_con)
2723
const char *comment_prefix=
2724
(opt_slave_data == DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
2725
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2729
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
2730
my_printf_error(0, _("Error: Slave not set up"), MYF(0));
2736
DRIZZLE_ROW row= drizzleclient_fetch_row(slave);
2737
if (row && row[9] && row[21])
2739
/* SHOW MASTER STATUS reports file and position */
2741
fprintf(md_result_file,
2742
"\n--\n-- Position to start replication or point-in-time "
2743
"recovery from (the master of this slave)\n--\n\n");
2745
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
2747
if (opt_include_master_host_port)
2750
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
2752
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
2754
fprintf(md_result_file,
2755
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
2757
check_io(md_result_file);
2759
drizzleclient_free_result(slave);
2764
static int do_start_slave_sql(DRIZZLE *drizzle_con)
2767
/* We need to check if the slave sql is stopped in the first place */
2768
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2772
DRIZZLE_ROW row= drizzleclient_fetch_row(slave);
2775
/* if SLAVE SQL is not running, we don't start it */
2776
if (!strcmp(row[11],"Yes"))
2778
drizzleclient_free_result(slave);
2779
/* Silently assume that they don't have the slave running */
2784
drizzleclient_free_result(slave);
2786
/* now, start slave if stopped */
2787
if (drizzleclient_query_with_error_report(drizzle_con, 0, "START SLAVE"))
2789
my_printf_error(0, _("Error: Unable to start slave"), MYF(0));
2797
static int do_flush_tables_read_lock(DRIZZLE *drizzle_con)
442
2800
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
443
2801
will wait but will not stall the whole mysqld, and when the long update is
444
2802
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
2803
FLUSH TABLES is to lower the probability of a stage where both mysqldump
446
2804
and most client connections are stalled. Of course, if a second long
447
2805
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");
2808
( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES") ||
2809
drizzleclient_query_with_error_report(drizzle_con, 0,
2810
"FLUSH TABLES WITH READ LOCK") );
2814
static int do_unlock_tables(DRIZZLE *drizzle_con)
2816
return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES");
2819
static int get_bin_log_name(DRIZZLE *drizzle_con,
2820
char* buff_log_name, uint buff_len)
2825
if (drizzleclient_query(drizzle_con, "SHOW MASTER STATUS") ||
2826
!(res= drizzleclient_store_result(drizzle)))
2829
if (!(row= drizzleclient_fetch_row(res)))
2831
drizzleclient_free_result(res);
2835
Only one row is returned, and the first column is the name of the
2838
strncpy(buff_log_name, row[0], buff_len - 1);
2840
drizzleclient_free_result(res);
2844
static int purge_bin_logs_to(DRIZZLE *drizzle_con, char* log_name)
2847
string str= "PURGE BINARY LOGS TO '";
2848
str.append(log_name);
2850
err = drizzleclient_query_with_error_report(drizzle_con, 0, str.c_str());
2855
static int start_transaction(DRIZZLE *drizzle_con)
2857
return (drizzleclient_query_with_error_report(drizzle_con, 0,
2858
"SET SESSION TRANSACTION ISOLATION "
2859
"LEVEL REPEATABLE READ") ||
2860
drizzleclient_query_with_error_report(drizzle_con, 0,
2861
"START TRANSACTION "
2862
"WITH CONSISTENT SNAPSHOT"));
2866
static uint32_t find_set(TYPELIB *lib, const char *x, uint length,
2867
char **err_pos, uint *err_len)
2869
const char *end= x + length;
2874
*err_pos= 0; /* No error yet */
2875
while (end > x && my_isspace(charset_info, end[-1]))
2881
const char *start= x;
2884
const char *pos= start;
2887
for (; pos != end && *pos != ','; pos++) ;
2888
var_len= (uint32_t) (pos - start);
2889
strncpy(buff, start, min((uint32_t)sizeof(buff), var_len));
2890
find= find_type(buff, lib, var_len);
2893
*err_pos= (char*) start;
2897
found|= (uint32_t)((int64_t) 1 << (find - 1));
2907
/* Print a value with a prefix on file */
2908
static void print_value(FILE *file, DRIZZLE_RES *result, DRIZZLE_ROW row,
2909
const char *prefix, const char *name,
2912
DRIZZLE_FIELD *field;
2913
drizzleclient_field_seek(result, 0);
2915
for ( ; (field= drizzleclient_fetch_field(result)) ; row++)
2917
if (!strcmp(field->name,name))
2919
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2922
fputs(prefix, file);
2924
unescape(file,row[0],(uint) strlen(row[0]));
2926
fputs(row[0], file);
2932
return; /* This shouldn't happen */
2936
* Fetches a row from a result based on a field name
2937
* Returns const char* of the data in that row or NULL if not found
2940
static const char* fetch_named_row(DRIZZLE_RES *result, DRIZZLE_ROW row, const char *name)
2942
DRIZZLE_FIELD *field;
2943
drizzleclient_field_seek(result, 0);
2944
for ( ; (field= drizzleclient_fetch_field(result)) ; row++)
2946
if (!strcmp(field->name,name))
2948
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
2950
drizzleclient_field_seek(result, 0);
2955
drizzleclient_field_seek(result, 0);
2963
Check if we the table is one of the table types that should be ignored:
2964
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
2965
If the table should be altogether ignored, it returns a true, false if it
2966
should not be ignored. If the user has selected to use INSERT DELAYED, it
2967
sets the value of the bool pointer supports_delayed_inserts to 0 if not
2968
supported, 1 if it is supported.
2972
check_if_ignore_table()
2973
table_name Table name to check
2974
table_type Type of table
2977
drizzle Drizzle connection
2978
verbose Write warning messages
2981
char (bit value) See IGNORE_ values at top
2984
char check_if_ignore_table(const char *table_name, char *table_type)
2986
char result= IGNORE_NONE;
2987
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
2988
const char *number_of_rows= NULL;
2989
DRIZZLE_RES *res= NULL;
2992
/* Check memory for quote_for_like() */
2993
assert(2*sizeof(table_name) < sizeof(show_name_buff));
2994
snprintf(buff, sizeof(buff), "show table status like %s",
2995
quote_for_like(table_name, show_name_buff));
2996
if (drizzleclient_query_with_error_report(drizzle, &res, buff))
2998
if (drizzleclient_errno(drizzle) != ER_PARSE_ERROR)
2999
{ /* If old DRIZZLE version */
3000
verbose_msg(_("-- Warning: Couldn't get status information for "
3001
"table %s (%s)\n"), table_name, drizzleclient_error(drizzle));
3002
return(result); /* assume table is ok */
3005
if (!(row= drizzleclient_fetch_row(res)))
3008
_("Error: Couldn't read status information for table %s (%s)\n"),
3009
table_name, drizzleclient_error(drizzle));
3010
drizzleclient_free_result(res);
3011
return(result); /* assume table is ok */
3015
if ((number_of_rows= fetch_named_row(res, row, "Rows")) != NULL)
3017
total_rows= strtoul(number_of_rows, NULL, 10);
3021
If the table type matches any of these, we do support delayed inserts.
3022
Note: we do not want to skip dumping this table if if is not one of
3023
these types, but we do want to use delayed inserts in the dump if
3024
the table type is _NOT_ one of these types
3027
strncpy(table_type, row[1], NAME_LEN-1);
3030
if (strcmp(table_type,"MyISAM") &&
3031
strcmp(table_type,"ARCHIVE") &&
3032
strcmp(table_type,"HEAP") &&
3033
strcmp(table_type,"MEMORY"))
3034
result= IGNORE_INSERT_DELAYED;
3037
drizzleclient_free_result(res);
3043
Get string of comma-separated primary key field names
3046
char *primary_key_fields(const char *table_name)
3047
RETURNS pointer to allocated buffer (must be freed by caller)
3048
table_name quoted table name
3051
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
3052
field names, and then build that string and return the pointer
3055
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
3056
or if there is some failure. It is better to continue to dump
3057
the table unsorted, rather than exit without dumping the data.
3060
static char *primary_key_fields(const char *table_name)
3062
DRIZZLE_RES *res= NULL;
3064
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
3065
char show_keys_buff[15 + NAME_LEN * 2 + 3];
3066
uint result_length= 0;
3068
char buff[NAME_LEN * 2 + 3];
3071
snprintf(show_keys_buff, sizeof(show_keys_buff),
3072
"SHOW KEYS FROM %s", table_name);
3073
if (drizzleclient_query(drizzle, show_keys_buff) ||
3074
!(res= drizzleclient_store_result(drizzle)))
3076
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
3077
" records are NOT sorted (%s)\n"),
3078
table_name, drizzleclient_error(drizzle));
3079
/* Don't exit, because it's better to print out unsorted records */
3084
* Figure out the length of the ORDER BY clause result.
3085
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
3086
* row, and UNIQUE keys come before others. So we only need to check
3087
* the first key, not all keys.
3089
if ((row= drizzleclient_fetch_row(res)) && atoi(row[1]) == 0)
3094
quoted_field= quote_name(row[4], buff, 0);
3095
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
3096
} while ((row= drizzleclient_fetch_row(res)) && atoi(row[3]) > 1);
3099
/* Build the ORDER BY clause result */
3103
/* result (terminating \0 is already in result_length) */
3104
result= (char *)malloc(result_length + 10);
3107
fprintf(stderr, _("Error: Not enough memory to store ORDER BY clause\n"));
3110
drizzleclient_data_seek(res, 0);
3111
row= drizzleclient_fetch_row(res);
3112
quoted_field= quote_name(row[4], buff, 0);
3113
end= strcpy(result, quoted_field) + strlen(quoted_field);
3114
while ((row= drizzleclient_fetch_row(res)) && atoi(row[3]) > 1)
3116
quoted_field= quote_name(row[4], buff, 0);
3117
end+= sprintf(end,",%s",quoted_field);
3123
drizzleclient_free_result(res);
469
3129
int main(int argc, char **argv)
3131
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();
3133
MY_INIT("drizzledump");
3135
compatible_mode_normal_str[0]= 0;
3136
default_charset= (char *)drizzle_universal_client_charset;
3137
memset(&ignore_table, 0, sizeof(ignore_table));
3139
exit_code= get_options(&argc, &argv);
749
3142
free_resources();
750
3143
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! */
3146
if (connect_to_db(current_host, current_user, opt_password))
3149
exit(EX_DRIZZLEERR);
3152
write_header(md_result_file, *argv);
3154
if (opt_slave_data && do_stop_slave_sql(drizzle))
3157
if ((opt_lock_all_tables || opt_master_data) &&
3158
do_flush_tables_read_lock(drizzle))
3160
if (opt_single_transaction && start_transaction(drizzle))
3162
if (opt_delete_master_logs)
3164
if (drizzleclient_refresh(drizzle, REFRESH_LOG) ||
3165
get_bin_log_name(drizzle, bin_log_name, sizeof(bin_log_name)))
3169
if (opt_lock_all_tables || opt_master_data)
3171
if (flush_logs && drizzleclient_refresh(drizzle, REFRESH_LOG))
3173
flush_logs= 0; /* not anymore; that would not be sensible */
3175
/* Add 'STOP SLAVE to beginning of dump */
3176
if (opt_slave_apply && add_stop_slave())
3178
if (opt_master_data && do_show_master_status(drizzle))
3180
if (opt_slave_data && do_show_slave_status(drizzle))
3182
if (opt_single_transaction && do_unlock_tables(drizzle)) /* unlock but no commit! */
794
3187
dump_all_databases();
797
if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
3189
else if (argc > 1 && !opt_databases)
799
string database_used= *vm["database-used"].as< vector<string> >().begin();
800
3191
/* 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)
3192
dump_selected_tables(*argv, (argv + 1), (argc - 1));
3196
dump_databases(argv);
3199
/* if --dump-slave , start the slave sql thread */
3200
if (opt_slave_data && do_start_slave_sql(drizzle))
3203
/* add 'START SLAVE' to end of dump */
3204
if (opt_slave_apply && add_slave_statements())
831
3207
/* ensure dumped data flushed */
832
3208
if (md_result_file && fflush(md_result_file))