73
62
/* Size of buffer for dump's select query */
74
63
#define QUERY_LENGTH 1536
64
#define DRIZZLE_MAX_LINE_LENGTH 1024*1024L-1025
76
66
/* ignore table flags */
77
67
#define IGNORE_NONE 0x00 /* no ignore */
78
68
#define IGNORE_DATA 0x01 /* don't dump data for this table */
79
69
#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;
71
static void add_load_option(string &str, const char *option,
72
const char *option_value);
73
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
74
char **err_pos, uint32_t *err_len);
76
static void field_escape(string &in, const char *from);
77
static bool verbose= false, opt_no_create_info= false, opt_no_data= false,
78
quick= true, extended_insert= true,
79
lock_tables= true, ignore_errors= false, flush_logs= false,
80
opt_drop= true, opt_keywords= false,
81
opt_lock= true, opt_compress= false,
82
opt_delayed= false, create_options= true, opt_quoted= false,
83
opt_databases= false, opt_alldbs= false, opt_create_db= false,
84
opt_lock_all_tables= false,
85
opt_set_charset= false, opt_dump_date= true,
86
opt_autocommit= false, opt_disable_keys= true, opt_xml= false,
87
opt_delete_master_logs= false, tty_password= false,
88
opt_single_transaction= false, opt_comments= false,
89
opt_compact= false, opt_hex_blob= false,
90
opt_order_by_primary=false, opt_ignore= false,
91
opt_complete_insert= false, opt_drop_database= false,
92
opt_replace_into= false,
94
opt_slave_apply= false,
95
opt_include_master_host_port= false,
97
static bool debug_info_flag= false, debug_check_flag= false;
98
static uint32_t show_progress_size= 0;
99
static uint64_t total_rows= 0;
100
static drizzle_st drizzle;
101
static drizzle_con_st dcon;
107
102
static string insert_pat;
103
static char *opt_password= NULL, *current_user= NULL,
104
*current_host= NULL, *path= NULL, *fields_terminated= NULL,
105
*lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
107
*where= NULL, *order_by= NULL,
108
*opt_compatible_mode_str= NULL,
110
static char **defaults_argv= NULL;
111
static char compatible_mode_normal_str[255];
112
static uint32_t opt_compatible_mode= 0;
113
#define DRIZZLE_OPT_MASTER_DATA_EFFECTIVE_SQL 1
114
#define DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL 2
115
#define DRIZZLE_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
116
#define DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL 2
108
117
static uint32_t opt_drizzle_port= 0;
118
static uint32_t opt_master_data;
119
static uint32_t opt_slave_data;
120
static uint32_t my_end_arg;
109
121
static int first_error= 0;
110
122
static string extended_row;
111
123
FILE *md_result_file= 0;
112
124
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);
127
Constant for detection of default value of default_charset.
128
If default_charset is equal to drizzle_universal_client_charset, then
129
it is the default value which assigned at the very beginning of main().
131
static const char *drizzle_universal_client_charset=
132
DRIZZLE_UNIVERSAL_CLIENT_CHARSET;
133
static char *default_charset;
134
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
135
const char *default_dbug_option="d:t:o,/tmp/drizzledump.trace";
136
const char *compatible_mode_names[]=
138
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
139
"MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
143
#define MASK_ANSI_QUOTES \
145
(1<<2) | /* POSTGRESQL */\
146
(1<<3) | /* ORACLE */\
147
(1<<4) | /* MSSQL */\
149
(1<<6) | /* MAXDB */\
152
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
153
"", compatible_mode_names, NULL};
157
static struct my_option my_long_options[] =
159
{"all", 'a', "Deprecated. Use --create-options instead.",
160
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
162
{"all-databases", 'A',
163
"Dump all the databases. This will be same as --databases with all databases selected.",
164
(char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
166
{"all-tablespaces", 'Y',
167
"Dump all the tablespaces.",
168
(char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
170
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
171
(char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
173
{"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
174
(char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
176
{"add-locks", OPT_LOCKS, "Add locks around insert statements.",
177
(char**) &opt_lock, (char**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
179
{"allow-keywords", OPT_KEYWORDS,
180
"Allow creation of column names that are keywords.", (char**) &opt_keywords,
181
(char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
182
{"apply-slave-statements", OPT_DRIZZLEDUMP_SLAVE_APPLY,
183
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
184
(char**) &opt_slave_apply, (char**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
186
{"comments", 'i', "Write additional information.",
187
(char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
189
{"compatible", OPT_COMPATIBLE,
190
"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.",
191
(char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
192
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
193
{"compact", OPT_COMPACT,
194
"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",
195
(char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
197
{"complete-insert", 'c', "Use complete insert statements.",
198
(char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
199
NO_ARG, 0, 0, 0, 0, 0, 0},
200
{"compress", 'C', "Use compression in server/client protocol.",
201
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
203
{"create-options", OPT_CREATE_OPTIONS,
204
"Include all DRIZZLE specific create options.",
205
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
208
"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.",
209
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
211
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
212
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
213
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
214
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
215
(char**) &debug_info_flag, (char**) &debug_info_flag,
216
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
217
{"default-character-set", OPT_DEFAULT_CHARSET,
218
"Set the default character set.", (char**) &default_charset,
219
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
220
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
221
(char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
223
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
224
"Delete logs on master after backup. This automatically enables --master-data.",
225
(char**) &opt_delete_master_logs, (char**) &opt_delete_master_logs, 0,
226
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
227
{"disable-keys", 'K',
228
"'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.", (char**) &opt_disable_keys,
229
(char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
230
{"dump-slave", OPT_DRIZZLEDUMP_SLAVE_DATA,
231
"This causes the binary log position and filename of the master to be "
232
"appended to the dumped data output. Setting the value to 1, will print"
233
"it as a CHANGE MASTER command in the dumped data output; if equal"
234
" to 2, that command will be prefixed with a comment symbol. "
235
"This option will turn --lock-all-tables on, unless "
236
"--single-transaction is specified too (in which case a "
237
"global read lock is only taken a short time at the beginning of the dump "
238
"- don't forget to read about --single-transaction below). In all cases "
239
"any action on logs will happen at the exact moment of the dump."
240
"Option automatically turns --lock-tables off.",
241
(char**) &opt_slave_data, (char**) &opt_slave_data, 0,
242
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
243
{"extended-insert", 'e',
244
"Allows utilization of the new, much faster INSERT syntax.",
245
(char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
247
{"fields-terminated-by", OPT_FTB,
248
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
249
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
250
{"fields-enclosed-by", OPT_ENC,
251
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
252
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
253
{"fields-optionally-enclosed-by", OPT_O_ENC,
254
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
255
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
256
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
257
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
258
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
259
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
261
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
262
"Note that if you dump many databases at once (using the option "
263
"--databases= or --all-databases), the logs will be flushed for "
264
"each database dumped. The exception is when using --lock-all-tables "
266
"in this case the logs will be flushed only once, corresponding "
267
"to the moment all tables are locked. So if you want your dump and "
268
"the log flush to happen at the same exact moment you should use "
269
"--lock-all-tables or --master-data with --flush-logs",
270
(char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
272
{"force", 'f', "Continue even if we get an sql-error.",
273
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
275
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
276
NO_ARG, 0, 0, 0, 0, 0, 0},
277
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
278
"VARBINARY, BLOB) in hexadecimal format.",
279
(char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
280
{"host", 'h', "Connect to host.", (char**) ¤t_host,
281
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
282
{"ignore-table", OPT_IGNORE_TABLE,
283
"Do not dump the specified table. To specify more than one table to ignore, "
284
"use the directive multiple times, once for each table. Each table must "
285
"be specified with both database and table names, e.g. --ignore-table=database.table",
286
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
287
{"include-master-host-port", OPT_DRIZZLEDUMP_INCLUDE_MASTER_HOST_PORT,
288
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
289
(char**) &opt_include_master_host_port,
290
(char**) &opt_include_master_host_port,
293
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
294
(char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
296
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
297
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
298
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
299
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
300
"is achieved by taking a global read lock for the duration of the whole "
301
"dump. Automatically turns --single-transaction and --lock-tables off.",
302
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
304
{"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
305
(char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
306
{"master-data", OPT_MASTER_DATA,
307
"This causes the binary log position and filename to be appended to the "
308
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
309
" to 2, that command will be prefixed with a comment symbol. "
310
"This option will turn --lock-all-tables on, unless "
311
"--single-transaction is specified too (in which case a "
312
"global read lock is only taken a short time at the beginning of the dump "
313
"- don't forget to read about --single-transaction below). In all cases "
314
"any action on logs will happen at the exact moment of the dump."
315
"Option automatically turns --lock-tables off.",
316
(char**) &opt_master_data, (char**) &opt_master_data, 0,
317
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
318
{"no-autocommit", OPT_AUTOCOMMIT,
319
"Wrap tables with autocommit/commit statements.",
320
(char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
322
{"no-create-db", 'n',
323
"'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.}.",
324
(char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
326
{"no-create-info", 't', "Don't write table creation info.",
327
(char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
328
NO_ARG, 0, 0, 0, 0, 0, 0},
329
{"no-data", 'd', "No row information.", (char**) &opt_no_data,
330
(char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
331
{"no-set-names", 'N',
332
"Deprecated. Use --skip-set-charset instead.",
333
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
334
{"opt", OPT_OPTIMIZE,
335
"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.",
336
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
337
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
338
"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.",
339
(char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
341
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
342
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
343
{"port", 'p', "Port number to use for connection.",
344
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
345
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
346
(char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
347
{"quote-names",'Q', "Quote table and column names with backticks (`).",
348
(char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
350
{"replace", OPT_DRIZZLE_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
351
(char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
354
"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).",
355
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
356
{"routines", 'R', "Dump stored routines (functions and procedures).",
357
(char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
358
NO_ARG, 0, 0, 0, 0, 0, 0},
360
Note that the combination --single-transaction --master-data
361
will give bullet-proof binlog position only if server >=4.1.3. That's the
362
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
364
{"single-transaction", OPT_TRANSACTION,
365
"Creates a consistent snapshot by dumping all tables in a single "
366
"transaction. Works ONLY for tables stored in storage engines which "
367
"support multiversioning (currently only InnoDB does); the dump is NOT "
368
"guaranteed to be consistent for other storage engines. "
369
"While a --single-transaction dump is in process, to ensure a valid "
370
"dump file (correct table contents and binary log position), no other "
371
"connection should use the following statements: ALTER TABLE, DROP "
372
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
373
"isolated from them. Option automatically turns off --lock-tables.",
374
(char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
375
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
376
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
377
(char**) &opt_dump_date, (char**) &opt_dump_date, 0,
378
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
379
{"skip-opt", OPT_SKIP_OPTIMIZATION,
380
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
381
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
383
"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.",
384
(char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
385
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
386
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
387
{"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of rows before each output progress report (requires --verbose)."),
388
(char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
389
10000, 0, 0, 0, 0, 0},
390
#ifndef DONT_ALLOW_USER_CHANGE
391
{"user", 'u', "User for login if not current user.",
392
(char**) ¤t_user, (char**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
395
{"verbose", 'v', "Print info about the various stages.",
396
(char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
397
{"version",'V', "Output version information and exit.", 0, 0, 0,
398
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
399
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
400
(char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
401
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
402
NO_ARG, 0, 0, 0, 0, 0, 0},
403
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
406
static const char *load_default_groups[]= { "drizzledump","client",0 };
408
static void maybe_exit(int error);
147
409
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);
410
static void maybe_die(int error, const char* reason, ...);
411
static void write_header(FILE *sql_file, char *db_name);
412
static void print_value(FILE *file, drizzle_result_st *result,
413
drizzle_row_t row, const char *prefix, const char *name,
415
static const char* fetch_named_row(drizzle_result_st *result, drizzle_row_t row,
417
static int dump_selected_tables(char *db, char **table_names, int tables);
418
static int dump_all_tables_in_db(char *db);
419
static int init_dumping_tables(char *);
420
static int init_dumping(char *, int init_func(char*));
421
static int dump_databases(char **);
151
422
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;
423
static char *quote_name(const char *name, char *buff, bool force);
424
char check_if_ignore_table(const char *table_name, char *table_type);
425
static char *primary_key_fields(const char *table_name);
428
Print the supplied message if in verbose mode
433
... variable number of parameters
435
static void verbose_msg(const char *fmt, ...)
444
vfprintf(stderr, fmt, args);
244
451
exit with message if ferror(file)
251
458
static void check_io(FILE *file)
335
883
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
338
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
886
fprintf(stderr, "%s: %s\n", my_progname, buffer);
341
889
ignore_errors= 0; /* force the exit */
342
890
maybe_exit(error_num);
895
Prints out an error message and maybe kills the process.
899
error_num - process return value
900
fmt_reason - a format string for use by vsnprintf.
901
... - variable arguments for above fmt_reason string
904
This call prints out the formatted error message to stderr and then
905
terminates the process, unless the --force command line option is used.
907
This call should be used for non-fatal errors (such as database
908
errors) that the code may still be able to continue to the next unit
912
static void maybe_die(int error_num, const char* fmt_reason, ...)
916
va_start(args,fmt_reason);
917
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
920
fprintf(stderr, "%s: %s\n", my_progname, buffer);
923
maybe_exit(error_num);
929
Sends a query to server, optionally reads result, prints error message if
933
drizzleclient_query_with_error_report()
934
drizzle_con connection to use
935
res if non zero, result will be put there with
936
drizzleclient_store_result()
937
query query to send to server
940
0 query sending and (if res!=0) result reading went ok
944
static int drizzleclient_query_with_error_report(drizzle_con_st *con,
945
drizzle_result_st *result,
946
const char *query_str,
949
drizzle_return_t ret;
951
if (drizzle_query_str(con, result, query_str, &ret) == NULL ||
952
ret != DRIZZLE_RETURN_OK)
954
if (ret == DRIZZLE_RETURN_ERROR_CODE)
956
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
957
query_str, drizzle_result_error(result),
958
drizzle_result_error_code(result));
959
drizzle_result_free(result);
963
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
964
query_str, drizzle_con_error(con), ret);
970
ret= drizzle_column_buffer(result);
972
ret= drizzle_result_buffer(result);
973
if (ret != DRIZZLE_RETURN_OK)
975
drizzle_result_free(result);
976
maybe_die(EX_DRIZZLEERR, _("Couldn't execute '%s': %s (%d)"),
977
query_str, drizzle_con_error(con), ret);
985
Open a new .sql file to dump the table or view into
988
open_sql_file_for_table
989
name name of the table or view
992
0 Failed to open file
993
> 0 Handle of the open file
995
static FILE* open_sql_file_for_table(const char* table)
998
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
999
convert_dirname(tmp_path,path,NULL);
1000
res= fopen(fn_format(filename, table, tmp_path, ".sql", 4), "w");
345
1006
static void free_resources(void)
347
1008
if (md_result_file && md_result_file != stdout)
348
1009
fclose(md_result_file);
349
opt_password.erase();
1011
if (hash_inited(&ignore_table))
1012
hash_free(&ignore_table);
1014
free_defaults(defaults_argv);
353
void maybe_exit(int error)
1019
static void maybe_exit(int error)
355
1021
if (!first_error)
356
1022
first_error= error;
357
1023
if (ignore_errors)
359
delete db_connection;
360
delete destination_connection;
1025
drizzle_con_free(&dcon);
1026
drizzle_free(&drizzle);
361
1027
free_resources();
1033
db_connect -- connects to the host and selects DB.
1036
static int connect_to_db(char *host, char *user,char *passwd)
1038
drizzle_return_t ret;
1040
verbose_msg(_("-- Connecting to %s...\n"), host ? host : "localhost");
1041
drizzle_create(&drizzle);
1042
drizzle_con_create(&drizzle, &dcon);
1043
drizzle_con_set_tcp(&dcon, host, opt_drizzle_port);
1044
drizzle_con_set_auth(&dcon, user, passwd);
1045
ret= drizzle_con_connect(&dcon);
1046
if (ret != DRIZZLE_RETURN_OK)
1048
DB_error(NULL, ret, "when trying to connect");
1053
} /* connect_to_db */
1057
** dbDisconnect -- disconnects from the host.
1059
static void dbDisconnect(char *host)
1061
verbose_msg(_("-- Disconnecting from %s...\n"), host ? host : "localhost");
1062
drizzle_con_free(&dcon);
1063
drizzle_free(&drizzle);
1064
} /* dbDisconnect */
1067
static void unescape(FILE *file,char *pos,uint32_t length)
1071
if (!(tmp=(char*) malloc(length*2+1)))
1072
die(EX_DRIZZLEERR, _("Couldn't allocate memory"));
1074
drizzle_escape_string(tmp, pos, length);
1084
static bool test_if_special_chars(const char *str)
1086
for ( ; *str ; str++)
1087
if (!my_isvar(charset_info,*str) && *str != '$')
1090
} /* test_if_special_chars */
1095
quote_name(name, buff, force)
1097
Quotes char string, taking into account compatible mode
1101
name Unquoted string containing that which will be quoted
1102
buff The buffer that contains the quoted value, also returned
1103
force Flag to make it ignore 'test_if_special_chars'
1110
static char *quote_name(const char *name, char *buff, bool force)
1113
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1115
if (!force && !opt_quoted && !test_if_special_chars(name))
1116
return (char*) name;
1131
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1135
name name of the table
1136
buff quoted name of the table
1139
Quote \, _, ' and % characters
1141
Note: Because DRIZZLE uses the C escape syntax in strings
1142
(for example, '\n' to represent newline), you must double
1143
any '\' that you use in your LIKE strings. For example, to
1144
search for '\n', specify it as '\\n'. To search for '\', specify
1145
it as '\\\\' (the backslashes are stripped once by the parser
1146
and another time when the pattern match is done, leaving a
1147
single backslash to be matched).
1149
Example: "t\1" => "t\\\\1"
1152
static char *quote_for_like(const char *name, char *buff)
1164
else if (*name == '\'' || *name == '_' || *name == '%')
1175
Quote and print a string.
1179
xml_file - output file
1180
str - string to print
1184
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1187
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
1191
for (end= str + len; str != end; str++)
1195
fputs("<", xml_file);
1198
fputs(">", xml_file);
1201
fputs("&", xml_file);
1204
fputs(""", xml_file);
1207
fputc(*str, xml_file);
1216
Print xml tag. Optionally add attribute(s).
1219
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1220
..., attribute_name_n, attribute_value_n, NULL)
1221
xml_file - output file
1222
sbeg - line beginning
1223
line_end - line ending
1224
tag_name - XML tag name.
1225
first_attribute_name - tag and first attribute
1226
first_attribute_value - (Implied) value of first attribute
1227
attribute_name_n - attribute n
1228
attribute_value_n - value of attribute n
1231
Print XML tag with any number of attribute="value" pairs to the xml_file.
1234
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1235
attribute_name_n="attribute_value_n">send
1237
Additional arguments must be present in attribute/value pairs.
1238
The last argument should be the null character pointer.
1239
All attribute_value arguments MUST be NULL terminated strings.
1240
All attribute_value arguments will be quoted before output.
1243
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1244
const char* line_end,
1245
const char* tag_name,
1246
const char* first_attribute_name, ...)
1249
const char *attribute_name, *attribute_value;
1251
fputs(sbeg, xml_file);
1252
fputc('<', xml_file);
1253
fputs(tag_name, xml_file);
1255
va_start(arg_list, first_attribute_name);
1256
attribute_name= first_attribute_name;
1257
while (attribute_name != NULL)
1259
attribute_value= va_arg(arg_list, char *);
1260
assert(attribute_value != NULL);
1262
fputc(' ', xml_file);
1263
fputs(attribute_name, xml_file);
1264
fputc('\"', xml_file);
1266
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1267
fputc('\"', xml_file);
1269
attribute_name= va_arg(arg_list, char *);
1273
fputc('>', xml_file);
1274
fputs(line_end, xml_file);
1280
Print xml tag with for a field that is null
1283
print_xml_null_tag()
1284
xml_file - output file
1285
sbeg - line beginning
1286
stag_atr - tag and attribute
1287
sval - value of attribute
1288
line_end - line ending
1291
Print tag with one attribute to the xml_file. Format is:
1292
<stag_atr="sval" xsi:nil="true"/>
1294
sval MUST be a NULL terminated string.
1295
sval string will be qouted before output.
1298
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1299
const char* stag_atr, const char* sval,
1300
const char* line_end)
1302
fputs(sbeg, xml_file);
1303
fputs("<", xml_file);
1304
fputs(stag_atr, xml_file);
1305
fputs("\"", xml_file);
1306
print_quoted_xml(xml_file, sval, strlen(sval));
1307
fputs("\" xsi:nil=\"true\" />", xml_file);
1308
fputs(line_end, xml_file);
1314
Print xml tag with many attributes.
1318
xml_file - output file
1319
row_name - xml tag name
1320
tableRes - query result
1324
Print tag with many attribute to the xml_file. Format is:
1325
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1327
All atributes and values will be quoted before output.
1330
static void print_xml_row(FILE *xml_file, const char *row_name,
1331
drizzle_result_st *tableRes, drizzle_row_t *row)
1334
drizzle_column_st *column;
1335
size_t *lengths= drizzle_row_field_sizes(tableRes);
1337
fprintf(xml_file, "\t\t<%s", row_name);
1339
drizzle_column_seek(tableRes, 0);
1340
for (i= 0; (column= drizzle_column_next(tableRes)); i++)
1344
fputc(' ', xml_file);
1345
print_quoted_xml(xml_file, drizzle_column_name(column),
1346
strlen(drizzle_column_name(column)));
1347
fputs("=\"", xml_file);
1348
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1349
fputc('"', xml_file);
1353
fputs(" />\n", xml_file);
1359
Print hex value for blob data.
1363
output_file - output file
1364
str - string to print
1368
Print hex value for blob data.
1371
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
1373
/* sakaik got the idea to to provide blob's in hex notation. */
1374
const char *ptr= str, *end= ptr + len;
1375
for (; ptr < end ; ptr++)
1376
fprintf(output_file, "%02X", *((unsigned char *)ptr));
1377
check_io(output_file);
1381
get_table_structure -- retrievs database structure, prints out corresponding
1382
CREATE statement and fills out insert_pat if the table is the type we will
1388
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1389
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1390
num_fields - number of fields in the table
1393
true if success, false if error
1396
static bool get_table_structure(char *table, char *db, char *table_type,
1397
char *ignore_flag, uint64_t *num_fields)
1399
bool init=0, delayed, write_data, complete_insert;
1400
char *result_table, *opt_quoted_table;
1401
const char *insert_option;
1402
char name_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE+3];
1403
char table_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+3];
1404
char table_buff2[DRIZZLE_MAX_TABLE_SIZE*2+3];
1405
char query_buff[QUERY_LENGTH];
1406
FILE *sql_file= md_result_file;
1407
drizzle_result_st result;
1410
*ignore_flag= check_if_ignore_table(table, table_type);
1412
delayed= opt_delayed;
1413
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
1416
verbose_msg(_("-- Warning: Unable to use delayed inserts for table '%s' "
1417
"because it's of type %s\n"), table, table_type);
1421
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1423
complete_insert= opt_complete_insert;
1427
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1428
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
1430
verbose_msg(_("-- Retrieving table structure for table %s...\n"), table);
1432
result_table= quote_name(table, table_buff, 1);
1433
opt_quoted_table= quote_name(table, table_buff2, 0);
1435
if (opt_order_by_primary)
1438
order_by= primary_key_fields(result_table);
1443
/* using SHOW CREATE statement */
1444
if (!opt_no_create_info)
1446
/* Make an sql-file, if path was given iow. option -T was given */
1447
char buff[20+FN_REFLEN];
1448
const drizzle_column_st *column;
1450
snprintf(buff, sizeof(buff), "show create table %s", result_table);
1452
if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1457
if (!(sql_file= open_sql_file_for_table(table)))
1459
drizzle_result_free(&result);
1463
write_header(sql_file, db);
1465
if (!opt_xml && opt_comments)
1467
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1474
Even if the "table" is a view, we do a DROP TABLE here.
1476
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
1480
column= drizzle_column_index(&result, 0);
1482
row= drizzle_row_next(&result);
1484
fprintf(sql_file, "%s;\n", row[1]);
1487
drizzle_result_free(&result);
1490
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1493
if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
1501
If write_data is true, then we build up insert statements for
1502
the table's data. Note: in subsequent lines of code, this test
1503
will have to be performed each time we are appending to
1508
if (opt_replace_into)
1509
insert_pat.append("REPLACE ");
1511
insert_pat.append("INSERT ");
1512
insert_pat.append(insert_option);
1513
insert_pat.append("INTO ");
1514
insert_pat.append(opt_quoted_table);
1515
if (complete_insert)
1517
insert_pat.append(" (");
1521
insert_pat.append(" VALUES ");
1522
if (!extended_insert)
1523
insert_pat.append("(");
1527
while ((row= drizzle_row_next(&result)))
1529
if (complete_insert)
1533
insert_pat.append(", ");
1536
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1539
*num_fields= drizzle_result_row_count(&result);
1540
drizzle_result_free(&result);
1544
verbose_msg(_("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n"),
1545
my_progname, drizzle_con_error(&dcon));
1547
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1549
if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
1552
/* Make an sql-file, if path was given iow. option -T was given */
1553
if (!opt_no_create_info)
1557
if (!(sql_file= open_sql_file_for_table(table)))
1559
drizzle_result_free(&result);
1562
write_header(sql_file, db);
1564
if (!opt_xml && opt_comments)
1565
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1568
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1570
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1572
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1579
if (opt_replace_into)
1580
insert_pat.append("REPLACE ");
1582
insert_pat.append("INSERT ");
1583
insert_pat.append(insert_option);
1584
insert_pat.append("INTO ");
1585
insert_pat.append(result_table);
1586
if (complete_insert)
1587
insert_pat.append(" (");
1590
insert_pat.append(" VALUES ");
1591
if (!extended_insert)
1592
insert_pat.append("(");
1596
while ((row= drizzle_row_next(&result)))
1598
size_t *lengths= drizzle_row_field_sizes(&result);
1601
if (!opt_xml && !opt_no_create_info)
1603
fputs(",\n",sql_file);
1606
if (complete_insert)
1607
insert_pat.append(", ");
1610
if (complete_insert)
1611
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1612
if (!opt_no_create_info)
1616
print_xml_row(sql_file, "field", &result, &row);
1621
fprintf(sql_file, " %s.%s %s", result_table,
1622
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1625
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1628
if (row[SHOW_DEFAULT])
1630
fputs(" DEFAULT ", sql_file);
1631
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1633
if (!row[SHOW_NULL][0])
1634
fputs(" NOT NULL", sql_file);
1635
if (row[SHOW_EXTRA][0])
1636
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1640
*num_fields= drizzle_result_row_count(&result);
1641
drizzle_result_free(&result);
1643
if (!opt_no_create_info)
1645
/* Make an sql-file, if path was given iow. option -T was given */
1646
char buff[20+FN_REFLEN];
1647
uint32_t keynr,primary_key;
1648
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1649
if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1651
fprintf(stderr, _("%s: Can't get keys for table %s\n"),
1652
my_progname, result_table);
1658
/* Find first which key is primary key */
1660
primary_key=INT_MAX;
1661
while ((row= drizzle_row_next(&result)))
1663
if (atoi(row[3]) == 1)
1666
#ifdef FORCE_PRIMARY_KEY
1667
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1670
if (!strcmp(row[2],"PRIMARY"))
1677
drizzle_row_seek(&result,0);
1679
while ((row= drizzle_row_next(&result)))
1683
print_xml_row(sql_file, "key", &result, &row);
1687
if (atoi(row[3]) == 1)
1690
putc(')', sql_file);
1691
if (atoi(row[1])) /* Test if duplicate key */
1692
/* Duplicate allowed */
1693
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1694
else if (keynr == primary_key)
1695
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1697
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1701
putc(',', sql_file);
1702
fputs(quote_name(row[4], name_buff, 0), sql_file);
1704
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1707
drizzle_result_free(&result);
1711
putc(')', sql_file);
1712
fputs("\n)",sql_file);
1715
/* Get DRIZZLE specific create options */
1718
char show_name_buff[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+2+24];
1720
/* Check memory for quote_for_like() */
1721
snprintf(buff, sizeof(buff), "show table status like %s",
1722
quote_for_like(table, show_name_buff));
1724
if (!drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1726
if (!(row= drizzle_row_next(&result)))
1729
_("Error: Couldn't read status information for table %s\n"),
1735
print_xml_row(sql_file, "options", &result, &row);
1738
fputs("/*!",sql_file);
1739
print_value(sql_file,&result,row,"engine=","Engine",0);
1740
print_value(sql_file,&result,row,"","Create_options",0);
1741
print_value(sql_file,&result,row,"comment=","Comment",1);
1743
fputs(" */",sql_file);
1747
drizzle_result_free(&result);
1751
fputs(";\n", sql_file);
1753
fputs("\t</table_structure>\n", sql_file);
1757
if (complete_insert) {
1758
insert_pat.append(") VALUES ");
1759
if (!extended_insert)
1760
insert_pat.append("(");
1762
if (sql_file != md_result_file)
1764
fputs("\n", sql_file);
1765
write_footer(sql_file);
1769
} /* get_table_structure */
1771
static void add_load_option(string &str, const char *option,
1772
const char *option_value)
1776
/* Null value means we don't add this option. */
1782
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
1784
/* It's a hex constant, don't escape */
1785
str.append(option_value);
1789
/* char constant; escape */
1790
field_escape(str, option_value);
1796
Allow the user to specify field terminator strings like:
1797
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
1798
This is done by doubling ' and add a end -\ if needed to avoid
1799
syntax errors from the SQL parser.
1802
static void field_escape(string &in, const char *from)
1804
uint32_t end_backslashes= 0;
1813
end_backslashes^=1; /* find odd number of backslashes */
1816
if (*from == '\'' && !end_backslashes)
1818
/* We want a duplicate of "'" for DRIZZLE */
1825
/* Add missing backslashes if user has specified odd number of backs.*/
1826
if (end_backslashes)
1839
dump_table saves database contents as a series of INSERT statements.
1850
static void dump_table(char *table, char *db)
1853
char table_buff[DRIZZLE_MAX_TABLE_SIZE+3];
1854
string query_string;
1855
char table_type[DRIZZLE_MAX_TABLE_SIZE];
1856
char *result_table, table_buff2[DRIZZLE_MAX_TABLE_SIZE*2+3], *opt_quoted_table;
1858
uint32_t rownr, row_break, total_length, init_length;
1859
uint64_t num_fields= 0;
1860
drizzle_return_t ret;
1861
drizzle_result_st result;
1862
drizzle_column_st *column;
1867
Make sure you get the create table info before the following check for
1868
--no-data flag below. Otherwise, the create table info won't be printed.
1870
if (!get_table_structure(table, db, table_type, &ignore_flag, &num_fields))
1872
maybe_die(EX_TABLE_STATUS, _("Error retrieving table structure for table: \"%s\""), table);
1876
/* Check --no-data flag */
1879
verbose_msg(_("-- Skipping dump data for table '%s', --no-data was used\n"),
1885
If the table type is a merge table or any type that has to be
1886
_completely_ ignored and no data dumped
1888
if (ignore_flag & IGNORE_DATA)
1890
verbose_msg(_("-- Warning: Skipping data for table '%s' because " \
1891
"it's of type %s\n"), table, table_type);
1894
/* Check that there are any fields in the table */
1895
if (num_fields == 0)
1897
verbose_msg(_("-- Skipping dump data for table '%s', it has no fields\n"),
1902
result_table= quote_name(table,table_buff, 1);
1903
opt_quoted_table= quote_name(table, table_buff2, 0);
1905
verbose_msg(_("-- Sending SELECT query...\n"));
1907
query_string.clear();
1908
query_string.reserve(1024);
1912
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1915
Convert the path to native os format
1916
and resolve to the full filepath.
1918
convert_dirname(tmp_path,path,NULL);
1919
my_load_path(tmp_path, tmp_path, NULL);
1920
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1922
/* Must delete the file that 'INTO OUTFILE' will write to */
1923
my_delete(filename, MYF(0));
1925
/* now build the query string */
1927
query_string.append( "SELECT * INTO OUTFILE '");
1928
query_string.append( filename);
1929
query_string.append( "'");
1931
if (fields_terminated || enclosed || opt_enclosed || escaped)
1932
query_string.append( " FIELDS");
1934
add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1935
add_load_option(query_string, " ENCLOSED BY ", enclosed);
1936
add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
1937
add_load_option(query_string, " ESCAPED BY ", escaped);
1938
add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
1940
query_string.append( " FROM ");
1941
query_string.append( result_table);
1945
query_string.append( " WHERE ");
1946
query_string.append( where);
1951
query_string.append( " ORDER BY ");
1952
query_string.append( order_by);
1955
if (drizzle_query(&dcon, &result, query_string.c_str(),
1956
query_string.length(), &ret) == NULL ||
1957
ret != DRIZZLE_RETURN_OK)
1959
DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
1963
drizzle_result_free(&result);
1967
if (!opt_xml && opt_comments)
1969
fprintf(md_result_file,_("\n--\n-- Dumping data for table %s\n--\n"),
1971
check_io(md_result_file);
1974
query_string.append( "SELECT * FROM ");
1975
query_string.append( result_table);
1979
if (!opt_xml && opt_comments)
1981
fprintf(md_result_file, "-- WHERE: %s\n", where);
1982
check_io(md_result_file);
1985
query_string.append( " WHERE ");
1986
query_string.append( where);
1990
if (!opt_xml && opt_comments)
1992
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
1993
check_io(md_result_file);
1995
query_string.append( " ORDER BY ");
1996
query_string.append( order_by);
1999
if (!opt_xml && !opt_compact)
2001
fputs("\n", md_result_file);
2002
check_io(md_result_file);
2004
if (drizzleclient_query_with_error_report(&dcon, &result,
2005
query_string.c_str(), quick))
2010
verbose_msg(_("-- Retrieving rows...\n"));
2011
if (drizzle_result_column_count(&result) != num_fields)
2013
fprintf(stderr,_("%s: Error in field count for table: %s ! Aborting.\n"),
2014
my_progname, result_table);
2015
error= EX_CONSCHECK;
2016
drizzle_result_free(&result);
2022
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2023
check_io(md_result_file);
2025
/* Moved disable keys to after lock per bug 15977 */
2026
if (opt_disable_keys)
2028
fprintf(md_result_file, "ALTER TABLE %s DISABLE KEYS;\n",
2030
check_io(md_result_file);
2033
total_length= DRIZZLE_MAX_LINE_LENGTH; /* Force row break */
2036
init_length=(uint32_t) insert_pat.length()+4;
2038
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2042
fprintf(md_result_file, "set autocommit=0;\n");
2043
check_io(md_result_file);
2056
drizzle_row_free(&result, row);
2058
row= drizzle_row_buffer(&result, &ret);
2059
if (ret != DRIZZLE_RETURN_OK)
2062
_("%s: Error reading rows for table: %s (%d:%s) ! Aborting.\n"),
2063
my_progname, result_table, ret, drizzle_con_error(&dcon));
2064
drizzle_result_free(&result);
2069
row= drizzle_row_next(&result);
2074
lengths= drizzle_row_field_sizes(&result);
2077
if ((rownr % show_progress_size) == 0)
2079
verbose_msg(_("-- %"PRIu32" of ~%"PRIu64" rows dumped for table %s\n"), rownr, total_rows, opt_quoted_table);
2081
if (!extended_insert && !opt_xml)
2083
fputs(insert_pat.c_str(),md_result_file);
2084
check_io(md_result_file);
2086
drizzle_column_seek(&result,0);
2090
fputs("\t<row>\n", md_result_file);
2091
check_io(md_result_file);
2094
for (i= 0; i < drizzle_result_column_count(&result); i++)
2097
uint32_t length= lengths[i];
2099
if (!(column= drizzle_column_next(&result)))
2101
_("Not enough fields from table %s! Aborting.\n"),
2105
63 is my_charset_bin. If charsetnr is not 63,
2106
we have not a BLOB but a TEXT column.
2107
we'll dump in hex only BLOB columns.
2109
is_blob= (opt_hex_blob && drizzle_column_charset(column) == 63 &&
2110
(drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_VARCHAR ||
2111
drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_BLOB)) ? 1 : 0;
2112
if (extended_insert && !opt_xml)
2116
extended_row.clear();
2117
extended_row.append("(");
2120
extended_row.append(",");
2126
if (!(drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NUM))
2129
"length * 2 + 2" is OK for both HEX and non-HEX modes:
2130
- In HEX mode we need exactly 2 bytes per character
2131
plus 2 bytes for '0x' prefix.
2132
- In non-HEX mode we need up to 2 bytes per character,
2133
plus 2 bytes for leading and trailing '\'' characters.
2134
Also we need to reserve 1 byte for terminating '\0'.
2136
char * tmp_str= (char *)malloc(length * 2 + 2 + 1);
2137
memset(tmp_str, '\0', length * 2 + 2 + 1);
2138
if (opt_hex_blob && is_blob)
2140
extended_row.append("0x");
2141
drizzle_hex_string(tmp_str, row[i], length);
2142
extended_row.append(tmp_str);
2146
extended_row.append("'");
2147
drizzle_escape_string(tmp_str, row[i],length);
2148
extended_row.append(tmp_str);
2149
extended_row.append("'");
2155
/* change any strings ("inf", "-inf", "nan") into NULL */
2157
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2158
my_isalpha(charset_info, ptr[1])))
2159
extended_row.append( "NULL");
2162
extended_row.append( ptr);
2167
extended_row.append("''");
2170
extended_row.append("NULL");
2176
fputc(',', md_result_file);
2177
check_io(md_result_file);
2181
if (!(drizzle_column_flags(column) & DRIZZLE_COLUMN_FLAGS_NUM))
2185
if (opt_hex_blob && is_blob && length)
2187
/* Define xsi:type="xs:hexBinary" for hex encoded data */
2188
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2189
drizzle_column_name(column), "xsi:type=", "xs:hexBinary", NULL);
2190
print_blob_as_hex(md_result_file, row[i], length);
2194
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2195
drizzle_column_name(column), NULL);
2196
print_quoted_xml(md_result_file, row[i], length);
2198
fputs("</field>\n", md_result_file);
2200
else if (opt_hex_blob && is_blob && length)
2202
fputs("0x", md_result_file);
2203
print_blob_as_hex(md_result_file, row[i], length);
2206
unescape(md_result_file, row[i], length);
2210
/* change any strings ("inf", "-inf", "nan") into NULL */
2214
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2215
drizzle_column_name(column), NULL);
2216
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2218
fputs("</field>\n", md_result_file);
2220
else if (my_isalpha(charset_info, *ptr) ||
2221
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
2222
fputs("NULL", md_result_file);
2224
fputs(ptr, md_result_file);
2229
/* The field value is NULL */
2231
fputs("NULL", md_result_file);
2233
print_xml_null_tag(md_result_file, "\t\t", "field name=",
2234
drizzle_column_name(column), "\n");
2236
check_io(md_result_file);
2242
fputs("\t</row>\n", md_result_file);
2243
check_io(md_result_file);
2246
if (extended_insert)
2248
uint32_t row_length;
2249
extended_row.append(")");
2250
row_length= 2 + extended_row.length();
2251
if (total_length + row_length < DRIZZLE_MAX_LINE_LENGTH)
2253
total_length+= row_length;
2254
fputc(',',md_result_file); /* Always row break */
2255
fputs(extended_row.c_str(),md_result_file);
2260
fputs(";\n", md_result_file);
2261
row_break=1; /* This is first row */
2263
fputs(insert_pat.c_str(),md_result_file);
2264
fputs(extended_row.c_str(),md_result_file);
2265
total_length= row_length+init_length;
2267
check_io(md_result_file);
2271
fputs(");\n", md_result_file);
2272
check_io(md_result_file);
2276
/* XML - close table tag and supress regular output */
2278
fputs("\t</table_data>\n", md_result_file);
2279
else if (extended_insert && row_break)
2280
fputs(";\n", md_result_file); /* If not empty table */
2281
fflush(md_result_file);
2282
check_io(md_result_file);
2284
/* Moved enable keys to before unlock per bug 15977 */
2285
if (opt_disable_keys)
2287
fprintf(md_result_file,"ALTER TABLE %s ENABLE KEYS;\n",
2289
check_io(md_result_file);
2293
fputs("UNLOCK TABLES;\n", md_result_file);
2294
check_io(md_result_file);
2298
fprintf(md_result_file, "commit;\n");
2299
check_io(md_result_file);
2301
drizzle_result_free(&result);
2311
static char *getTableName(int reset)
2313
static drizzle_result_st result;
2314
static bool have_result= false;
2319
if (drizzleclient_query_with_error_report(&dcon, &result, "SHOW TABLES", false))
2324
if ((row= drizzle_row_next(&result)))
2328
drizzle_row_seek(&result, 0);
2331
drizzle_result_free(&result);
2335
} /* getTableName */
365
2338
static int dump_all_databases()
367
2340
drizzle_row_t row;
368
drizzle_result_st *tableres;
2341
drizzle_result_st 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)))
2344
if (drizzleclient_query_with_error_report(&dcon, &tableres, "SHOW DATABASES", false))
2346
while ((row= drizzle_row_next(&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);
2348
if (dump_all_tables_in_db(row[0]))
394
db_connection->freeResult(tableres);
2351
drizzle_result_free(&tableres);
397
2354
/* dump_all_databases */
400
static int dump_databases(const vector<string> &db_names)
2357
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)
2363
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);
2365
if (dump_all_tables_in_db(*db))
416
2369
} /* 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);
2373
Table Specific database initalization.
2377
qdatabase quoted name of the database
2384
int init_dumping_tables(char *qdatabase)
2390
drizzle_result_st result;
2391
drizzle_return_t ret;
2393
snprintf(qbuf, sizeof(qbuf),
2394
"SHOW CREATE DATABASE IF NOT EXISTS %s",
2397
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
2398
ret != DRIZZLE_RETURN_OK)
2400
if (ret == DRIZZLE_RETURN_ERROR_CODE)
2401
drizzle_result_free(&result);
2403
/* Old server version, dump generic CREATE DATABASE */
2404
if (opt_drop_database)
2405
fprintf(md_result_file,
2406
"\nDROP DATABASE IF EXISTS %s;\n",
2408
fprintf(md_result_file,
2409
"\nCREATE DATABASE IF NOT EXISTS %s;\n",
2414
if (drizzle_result_buffer(&result) == DRIZZLE_RETURN_OK)
2416
if (opt_drop_database)
2417
fprintf(md_result_file,
2418
"\nDROP DATABASE IF EXISTS %s;\n",
2420
row = drizzle_row_next(&result);
2421
if (row != NULL && row[1])
2423
fprintf(md_result_file,"\n%s;\n",row[1]);
2426
drizzle_result_free(&result);
2430
} /* init_dumping_tables */
2433
static int init_dumping(char *database, int init_func(char*))
2435
drizzle_result_st result;
2436
drizzle_return_t ret;
2438
if (!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
2441
if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
2442
ret != DRIZZLE_RETURN_OK)
2444
DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
2445
return 1; /* If --force */
2447
drizzle_result_free(&result);
2449
if (!path && !opt_xml)
2451
if (opt_databases || opt_alldbs)
2454
length of table name * 2 (if name contains quotes), 2 quotes and 0
2456
char quoted_database_buf[DRIZZLE_MAX_DB_SIZE*2+3];
2457
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
2460
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
2461
check_io(md_result_file);
2464
/* Call the view or table specific function */
2465
init_func(qdatabase);
2467
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
2468
check_io(md_result_file);
2471
if (extended_insert)
2472
extended_row.clear();
2474
} /* init_dumping */
2477
/* Return 1 if we should copy the table */
2479
static bool include_table(const unsigned char *hash_key, size_t len)
2481
return !hash_search(&ignore_table, hash_key, len);
2485
static int dump_all_tables_in_db(char *database)
2489
char table_buff[DRIZZLE_MAX_TABLE_SIZE*2+3];
2490
char hash_key[DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2]; /* "db.tablename" */
2492
drizzle_result_st result;
2493
drizzle_return_t ret;
2495
afterdot= strcpy(hash_key, database) + strlen(database);
2498
if (init_dumping(database, init_dumping_tables))
2501
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
2504
string query("LOCK TABLES ");
2505
for (numrows= 0 ; (table= getTableName(1)) ; )
2507
char *end= strcpy(afterdot, table) + strlen(table);
2508
if (include_table((unsigned char*) hash_key,end - hash_key))
2511
query.append( quote_name(table, table_buff, 1));
2512
query.append( " READ LOCAL,");
2517
if (drizzle_query(&dcon, &result, query.c_str(),
2518
query.length()-1, &ret) == NULL ||
2519
ret != DRIZZLE_RETURN_OK)
2521
DB_error(&result, ret, _("when using LOCK TABLES"));
2522
/* We shall continue here, if --force was given */
2525
drizzle_result_free(&result);
2531
if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
2532
ret != DRIZZLE_RETURN_OK)
2534
DB_error(&result, ret, _("when doing refresh"));
2535
/* We shall continue here, if --force was given */
2538
drizzle_result_free(&result);
2540
while ((table= getTableName(0)))
2542
char *end= strcpy(afterdot, table) + strlen(table);
2543
if (include_table((unsigned char*) hash_key, end - hash_key))
2545
dump_table(table,database);
2552
fputs("</database>\n", md_result_file);
2553
check_io(md_result_file);
2557
if (!drizzleclient_query_with_error_report(&dcon, &result, "UNLOCK TABLES", false))
2558
drizzle_result_free(&result);
2562
} /* dump_all_tables_in_db */
2566
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2567
table name from the server for the table name given on the command line.
2568
we do this because the table name given on the command line may be a
2569
different case (e.g. T1 vs t1)
2572
pointer to the table name
2576
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2579
drizzle_result_st result;
2581
char query[50 + 2*DRIZZLE_MAX_TABLE_SIZE];
2582
char show_name_buff[FN_REFLEN];
2586
/* Check memory for quote_for_like() */
2587
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2588
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2589
quote_for_like(old_table_name, show_name_buff));
2591
if (drizzleclient_query_with_error_report(&dcon, &result, query, false))
2594
num_rows= drizzle_result_row_count(&result);
2600
TODO: Return all matching rows
2602
row= drizzle_row_next(&result);
2603
lengths= drizzle_row_field_sizes(&result);
2604
name= strmake_root(root, row[0], lengths[0]);
2606
drizzle_result_free(&result);
2612
static int dump_selected_tables(char *db, char **table_names, int tables)
2614
char table_buff[DRIZZLE_MAX_TABLE_SIZE*2+3];
2615
string lock_tables_query("LOCK TABLES ");
2617
char **dump_tables, **pos, **end;
2618
drizzle_result_st result;
2619
drizzle_return_t ret;
2622
if (init_dumping(db, init_dumping_tables))
2625
init_alloc_root(&root, 8192, 0);
2626
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2627
die(EX_EOM, _("alloc_root failure."));
2629
for (; tables > 0 ; tables-- , table_names++)
2631
/* the table name passed on commandline may be wrong case */
2632
if ((*pos= get_actual_table_name(*table_names, &root)))
2634
/* Add found table name to lock_tables_query */
2637
lock_tables_query.append( quote_name(*pos, table_buff, 1));
2638
lock_tables_query.append( " READ LOCAL,");
2646
free_root(&root, MYF(0));
2648
maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""), *table_names);
2649
/* We shall countinue here, if --force was given */
2656
if (drizzle_query(&dcon, &result, lock_tables_query.c_str(),
2657
lock_tables_query.length()-1, &ret) == NULL ||
2658
ret != DRIZZLE_RETURN_OK)
2662
free_root(&root, MYF(0));
2664
DB_error(&result, ret, _("when doing LOCK TABLES"));
2665
/* We shall countinue here, if --force was given */
2668
drizzle_result_free(&result);
2672
if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
2673
ret != DRIZZLE_RETURN_OK)
2676
free_root(&root, MYF(0));
2677
DB_error(&result, ret, _("when doing refresh"));
2678
/* We shall countinue here, if --force was given */
2681
drizzle_result_free(&result);
2684
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NULL);
2686
/* Dump each selected table */
2687
for (pos= dump_tables; pos < end; pos++)
2688
dump_table(*pos, db);
2690
free_root(&root, MYF(0));
2695
fputs("</database>\n", md_result_file);
2696
check_io(md_result_file);
2700
if (!(drizzleclient_query_with_error_report(&dcon, &result, "UNLOCK TABLES", false)))
2701
drizzle_result_free(&result);
437
2704
} /* dump_selected_tables */
439
static int do_flush_tables_read_lock()
2707
static int do_show_master_status(drizzle_con_st *drizzle_con)
2710
drizzle_result_st master;
2711
const char *comment_prefix=
2712
(opt_master_data == DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
2713
if (drizzleclient_query_with_error_report(drizzle_con, &master, "SHOW MASTER STATUS", false))
2719
row= drizzle_row_next(&master);
2720
if (row && row[0] && row[1])
2722
/* SHOW MASTER STATUS reports file and position */
2724
fprintf(md_result_file,
2725
"\n--\n-- Position to start replication or point-in-time "
2726
"recovery from\n--\n\n");
2727
fprintf(md_result_file,
2728
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
2729
comment_prefix, row[0], row[1]);
2730
check_io(md_result_file);
2732
else if (!ignore_errors)
2734
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2735
my_printf_error(0, _("Error: Binlogging on server not active"),
2737
drizzle_result_free(&master);
2738
maybe_exit(EX_DRIZZLEERR);
2741
drizzle_result_free(&master);
2746
static int do_stop_slave_sql(drizzle_con_st *drizzle_con)
2748
drizzle_result_st slave;
2749
/* We need to check if the slave sql is running in the first place */
2750
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS", false))
2754
drizzle_row_t row= drizzle_row_next(&slave);
2757
/* if SLAVE SQL is not running, we don't stop it */
2758
if (!strcmp(row[11],"No"))
2760
drizzle_result_free(&slave);
2761
/* Silently assume that they don't have the slave running */
2766
drizzle_result_free(&slave);
2768
/* now, stop slave if running */
2769
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "STOP SLAVE SQL_THREAD", false))
2771
drizzle_result_free(&slave);
2776
static int add_stop_slave(void)
2779
fprintf(md_result_file,
2780
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
2781
fprintf(md_result_file, "STOP SLAVE;\n");
2785
static int add_slave_statements(void)
2788
fprintf(md_result_file,
2789
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
2790
fprintf(md_result_file, "START SLAVE;\n");
2794
static int do_show_slave_status(drizzle_con_st *drizzle_con)
2796
drizzle_result_st slave;
2797
const char *comment_prefix=
2798
(opt_slave_data == DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
2799
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS", false))
2803
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
2804
my_printf_error(0, _("Error: Slave not set up"), MYF(0));
2810
drizzle_row_t row= drizzle_row_next(&slave);
2811
if (row && row[9] && row[21])
2813
/* SHOW MASTER STATUS reports file and position */
2815
fprintf(md_result_file,
2816
"\n--\n-- Position to start replication or point-in-time "
2817
"recovery from (the master of this slave)\n--\n\n");
2819
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
2821
if (opt_include_master_host_port)
2824
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
2826
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
2828
fprintf(md_result_file,
2829
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
2831
check_io(md_result_file);
2833
drizzle_result_free(&slave);
2838
static int do_start_slave_sql(drizzle_con_st *drizzle_con)
2840
drizzle_result_st slave;
2841
/* We need to check if the slave sql is stopped in the first place */
2842
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS", false))
2846
drizzle_row_t row= drizzle_row_next(&slave);
2849
/* if SLAVE SQL is not running, we don't start it */
2850
if (!strcmp(row[11],"Yes"))
2852
drizzle_result_free(&slave);
2853
/* Silently assume that they don't have the slave running */
2857
drizzle_result_free(&slave);
2860
/* now, start slave if stopped */
2861
if (drizzleclient_query_with_error_report(drizzle_con, &slave, "START SLAVE", false))
2863
my_printf_error(0, _("Error: Unable to start slave"), MYF(0));
2866
drizzle_result_free(&slave);
2872
static int do_flush_tables_read_lock(drizzle_con_st *drizzle_con)
442
2875
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
443
2876
will wait but will not stall the whole mysqld, and when the long update is
444
2877
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
2878
FLUSH TABLES is to lower the probability of a stage where both mysqldump
446
2879
and most client connections are stalled. Of course, if a second long
447
2880
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");
2883
( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES", false) ||
2884
drizzleclient_query_with_error_report(drizzle_con, 0,
2885
"FLUSH TABLES WITH READ LOCK", false) );
2889
static int do_unlock_tables(drizzle_con_st *drizzle_con)
2891
return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES", false);
2894
static int get_bin_log_name(drizzle_con_st *drizzle_con,
2895
char* buff_log_name, uint32_t buff_len)
2897
drizzle_result_st res;
2900
if (drizzleclient_query_with_error_report(drizzle_con, &res, "SHOW MASTER STATUS", false))
2903
if (!(row= drizzle_row_next(&res)))
2905
drizzle_result_free(&res);
2909
Only one row is returned, and the first column is the name of the
2912
strncpy(buff_log_name, row[0], buff_len - 1);
2914
drizzle_result_free(&res);
2918
static int purge_bin_logs_to(drizzle_con_st *drizzle_con, char* log_name)
2921
string str= "PURGE BINARY LOGS TO '";
2922
str.append(log_name);
2924
drizzle_result_st res;
2925
err= drizzleclient_query_with_error_report(drizzle_con, &res, str.c_str(),
2929
drizzle_result_free(&res);
2934
static int start_transaction(drizzle_con_st *drizzle_con)
2936
return (drizzleclient_query_with_error_report(drizzle_con, 0,
2937
"SET SESSION TRANSACTION ISOLATION "
2938
"LEVEL REPEATABLE READ", false) ||
2939
drizzleclient_query_with_error_report(drizzle_con, 0,
2940
"START TRANSACTION "
2941
"WITH CONSISTENT SNAPSHOT", false));
2945
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
2946
char **err_pos, uint32_t *err_len)
2948
const char *end= x + length;
2953
*err_pos= 0; /* No error yet */
2954
while (end > x && my_isspace(charset_info, end[-1]))
2960
const char *start= x;
2963
const char *pos= start;
2966
for (; pos != end && *pos != ','; pos++) ;
2967
var_len= (uint32_t) (pos - start);
2968
strncpy(buff, start, min((uint32_t)sizeof(buff), var_len));
2969
find= find_type(buff, lib, var_len);
2972
*err_pos= (char*) start;
2976
found|= (uint32_t)((int64_t) 1 << (find - 1));
2986
/* Print a value with a prefix on file */
2987
static void print_value(FILE *file, drizzle_result_st *result, drizzle_row_t row,
2988
const char *prefix, const char *name,
2991
drizzle_column_st *column;
2992
drizzle_column_seek(result, 0);
2994
for ( ; (column= drizzle_column_next(result)) ; row++)
2996
if (!strcmp(drizzle_column_name(column),name))
2998
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
3001
fputs(prefix, file);
3003
unescape(file,row[0],(uint32_t) strlen(row[0]));
3005
fputs(row[0], file);
3011
return; /* This shouldn't happen */
3015
* Fetches a row from a result based on a field name
3016
* Returns const char* of the data in that row or NULL if not found
3019
static const char* fetch_named_row(drizzle_result_st *result, drizzle_row_t row, const char *name)
3021
drizzle_column_st *column;
3022
drizzle_column_seek(result, 0);
3024
for ( ; (column= drizzle_column_next(result)) ; row++)
3026
if (!strcmp(drizzle_column_name(column),name))
3028
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
3030
drizzle_column_seek(result, 0);
3035
drizzle_column_seek(result, 0);
3043
Check if we the table is one of the table types that should be ignored:
3044
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
3045
If the table should be altogether ignored, it returns a true, false if it
3046
should not be ignored. If the user has selected to use INSERT DELAYED, it
3047
sets the value of the bool pointer supports_delayed_inserts to 0 if not
3048
supported, 1 if it is supported.
3052
check_if_ignore_table()
3053
table_name Table name to check
3054
table_type Type of table
3057
drizzle Drizzle connection
3058
verbose Write warning messages
3061
char (bit value) See IGNORE_ values at top
3064
char check_if_ignore_table(const char *table_name, char *table_type)
3066
char result= IGNORE_NONE;
3067
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
3068
const char *number_of_rows= NULL;
3069
drizzle_result_st res;
3072
/* Check memory for quote_for_like() */
3073
assert(2*sizeof(table_name) < sizeof(show_name_buff));
3074
snprintf(buff, sizeof(buff), "show table status like %s",
3075
quote_for_like(table_name, show_name_buff));
3076
if (drizzleclient_query_with_error_report(&dcon, &res, buff, false))
3080
if (!(row= drizzle_row_next(&res)))
3083
_("Error: Couldn't read status information for table %s\n"),
3085
drizzle_result_free(&res);
3086
return(result); /* assume table is ok */
3090
if ((number_of_rows= fetch_named_row(&res, row, "Rows")) != NULL)
3092
total_rows= strtoul(number_of_rows, NULL, 10);
3096
If the table type matches any of these, we do support delayed inserts.
3097
Note: we do not want to skip dumping this table if if is not one of
3098
these types, but we do want to use delayed inserts in the dump if
3099
the table type is _NOT_ one of these types
3102
strncpy(table_type, row[1], DRIZZLE_MAX_TABLE_SIZE-1);
3105
if (strcmp(table_type,"MyISAM") &&
3106
strcmp(table_type,"ARCHIVE") &&
3107
strcmp(table_type,"HEAP") &&
3108
strcmp(table_type,"MEMORY"))
3109
result= IGNORE_INSERT_DELAYED;
3112
drizzle_result_free(&res);
3118
Get string of comma-separated primary key field names
3121
char *primary_key_fields(const char *table_name)
3122
RETURNS pointer to allocated buffer (must be freed by caller)
3123
table_name quoted table name
3126
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
3127
field names, and then build that string and return the pointer
3130
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
3131
or if there is some failure. It is better to continue to dump
3132
the table unsorted, rather than exit without dumping the data.
3135
static char *primary_key_fields(const char *table_name)
3137
drizzle_result_st res;
3138
drizzle_return_t ret;
3140
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
3141
char show_keys_buff[15 + DRIZZLE_MAX_TABLE_SIZE * 2 + 3];
3142
uint32_t result_length= 0;
3144
char buff[DRIZZLE_MAX_TABLE_SIZE * 2 + 3];
3147
snprintf(show_keys_buff, sizeof(show_keys_buff),
3148
"SHOW KEYS FROM %s", table_name);
3149
if (drizzle_query_str(&dcon, &res, show_keys_buff, &ret) == NULL ||
3150
ret != DRIZZLE_RETURN_OK)
3152
if (ret == DRIZZLE_RETURN_ERROR_CODE)
3154
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
3155
" records are NOT sorted (%s)\n"),
3156
table_name, drizzle_result_error(&res));
3157
drizzle_result_free(&res);
3161
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
3162
" records are NOT sorted (%s)\n"),
3163
table_name, drizzle_con_error(&dcon));
3169
if (drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
3171
fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
3172
" records are NOT sorted (%s)\n"),
3173
table_name, drizzle_con_error(&dcon));
3178
* Figure out the length of the ORDER BY clause result.
3179
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
3180
* row, and UNIQUE keys come before others. So we only need to check
3181
* the first key, not all keys.
3183
if ((row= drizzle_row_next(&res)) && atoi(row[1]) == 0)
3188
quoted_field= quote_name(row[4], buff, 0);
3189
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
3190
} while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1);
3193
/* Build the ORDER BY clause result */
3197
/* result (terminating \0 is already in result_length) */
3198
result= (char *)malloc(result_length + 10);
3201
fprintf(stderr, _("Error: Not enough memory to store ORDER BY clause\n"));
3202
drizzle_result_free(&res);
3205
drizzle_row_seek(&res, 0);
3206
row= drizzle_row_next(&res);
3207
quoted_field= quote_name(row[4], buff, 0);
3208
end= strcpy(result, quoted_field) + strlen(quoted_field);
3209
while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1)
3211
quoted_field= quote_name(row[4], buff, 0);
3212
end+= sprintf(end,",%s",quoted_field);
3216
drizzle_result_free(&res);
469
3221
int main(int argc, char **argv)
3223
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();
3225
MY_INIT("drizzledump");
3226
drizzle_result_st result;
3228
compatible_mode_normal_str[0]= 0;
3229
default_charset= (char *)drizzle_universal_client_charset;
3230
memset(&ignore_table, 0, sizeof(ignore_table));
3232
exit_code= get_options(&argc, &argv);
749
3235
free_resources();
750
3236
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! */
3239
if (connect_to_db(current_host, current_user, opt_password))
3242
exit(EX_DRIZZLEERR);
3245
write_header(md_result_file, *argv);
3247
if (opt_slave_data && do_stop_slave_sql(&dcon))
3250
if ((opt_lock_all_tables || opt_master_data) &&
3251
do_flush_tables_read_lock(&dcon))
3253
if (opt_single_transaction && start_transaction(&dcon))
3255
if (opt_delete_master_logs)
3257
if (drizzleclient_query_with_error_report(&dcon, &result, "FLUSH LOGS", false))
3259
drizzle_result_free(&result);
3260
if (get_bin_log_name(&dcon, bin_log_name, sizeof(bin_log_name)))
3264
if (opt_lock_all_tables || opt_master_data)
3266
if (drizzleclient_query_with_error_report(&dcon, &result, "FLUSH LOGS", false))
3268
drizzle_result_free(&result);
3269
flush_logs= 0; /* not anymore; that would not be sensible */
3271
/* Add 'STOP SLAVE to beginning of dump */
3272
if (opt_slave_apply && add_stop_slave())
3274
if (opt_master_data && do_show_master_status(&dcon))
3276
if (opt_slave_data && do_show_slave_status(&dcon))
3278
if (opt_single_transaction && do_unlock_tables(&dcon)) /* unlock but no commit! */
794
3283
dump_all_databases();
797
if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
3285
else if (argc > 1 && !opt_databases)
799
string database_used= *vm["database-used"].as< vector<string> >().begin();
800
3287
/* 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)
3288
dump_selected_tables(*argv, (argv + 1), (argc - 1));
3292
dump_databases(argv);
3295
/* if --dump-slave , start the slave sql thread */
3296
if (opt_slave_data && do_start_slave_sql(&dcon))
3299
/* add 'START SLAVE' to end of dump */
3300
if (opt_slave_apply && add_slave_statements())
831
3303
/* ensure dumped data flushed */
832
3304
if (md_result_file && fflush(md_result_file))