78
64
#define IGNORE_DATA 0x01 /* don't dump data for this table */
79
65
#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
bool opt_data_is_mangled= false;
107
uint32_t show_progress_size= 0;
67
static void add_load_option(string &str, const char *option,
68
const char *option_value);
69
static uint32_t find_set(TYPELIB *lib, const char *x, uint length,
70
char **err_pos, uint *err_len);
72
static void field_escape(string &in, const char *from);
73
static bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
74
quick= 1, extended_insert= 1,
75
lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0,
76
opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
77
opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
78
opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
79
opt_set_charset=0, opt_dump_date=1,
80
opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
81
opt_delete_master_logs=0, tty_password=0,
82
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
83
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
84
opt_complete_insert= 0, opt_drop_database= 0,
88
opt_include_master_host_port= 0,
90
opt_alltspcs=0, opt_notspcs= 0;
91
static bool debug_info_flag= 0, debug_check_flag= 0;
92
static uint32_t opt_max_allowed_packet, opt_net_buffer_length;
93
static DRIZZLE drizzle_connection,*drizzle=0;
108
94
static string insert_pat;
109
static uint32_t opt_drizzle_port= 0;
110
static int first_error= 0;
95
static char *opt_password=0,*current_user=0,
96
*current_host=0,*path=0,*fields_terminated=0,
97
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
98
*where=0, *order_by=0,
99
*opt_compatible_mode_str= 0,
101
*log_error_file= NULL;
102
static char **defaults_argv= 0;
103
static char compatible_mode_normal_str[255];
104
/* Server supports character_set_results session variable? */
105
static bool server_supports_switching_charsets= true;
106
static uint32_t opt_compatible_mode= 0;
107
#define DRIZZLE_OPT_MASTER_DATA_EFFECTIVE_SQL 1
108
#define DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL 2
109
#define DRIZZLE_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
110
#define DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL 2
111
static uint opt_drizzle_port= 0, opt_master_data;
112
static uint opt_slave_data;
113
static uint my_end_arg;
114
static int first_error=0;
111
115
static string extended_row;
112
116
FILE *md_result_file= 0;
113
FILE *stderror_file= 0;
114
std::vector<DrizzleDumpDatabase*> database_store;
115
DrizzleDumpConnection* db_connection;
116
DrizzleDumpConnection* destination_connection;
124
int opt_destination= DESTINATION_STDOUT;
125
std::string opt_destination_host;
126
uint16_t opt_destination_port;
127
std::string opt_destination_user;
128
std::string opt_destination_password;
129
std::string opt_destination_database;
131
const string progname= "drizzledump";
143
boost::unordered_set<string> ignore_table;
145
void maybe_exit(int error);
117
FILE *stderror_file=0;
120
Constant for detection of default value of default_charset.
121
If default_charset is equal to drizzle_universal_client_charset, then
122
it is the default value which assigned at the very beginning of main().
124
static const char *drizzle_universal_client_charset=
125
DRIZZLE_UNIVERSAL_CLIENT_CHARSET;
126
static char *default_charset;
127
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
128
const char *default_dbug_option="d:t:o,/tmp/drizzledump.trace";
129
/* have we seen any VIEWs during table scanning? */
131
const char *compatible_mode_names[]=
133
"MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
134
"MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
138
#define MASK_ANSI_QUOTES \
140
(1<<2) | /* POSTGRESQL */\
141
(1<<3) | /* ORACLE */\
142
(1<<4) | /* MSSQL */\
144
(1<<6) | /* MAXDB */\
147
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
148
"", compatible_mode_names, NULL};
152
static struct my_option my_long_options[] =
154
{"all", 'a', "Deprecated. Use --create-options instead.",
155
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
157
{"all-databases", 'A',
158
"Dump all the databases. This will be same as --databases with all databases selected.",
159
(char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
161
{"all-tablespaces", 'Y',
162
"Dump all the tablespaces.",
163
(char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
165
{"no-tablespaces", 'y',
166
"Do not dump any tablespace information.",
167
(char**) &opt_notspcs, (char**) &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
169
{"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
170
(char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
172
{"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
173
(char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
175
{"add-locks", OPT_LOCKS, "Add locks around insert statements.",
176
(char**) &opt_lock, (char**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
178
{"allow-keywords", OPT_KEYWORDS,
179
"Allow creation of column names that are keywords.", (char**) &opt_keywords,
180
(char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
181
{"apply-slave-statements", OPT_DRIZZLEDUMP_SLAVE_APPLY,
182
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
183
(char**) &opt_slave_apply, (char**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
185
{"character-sets-dir", OPT_CHARSETS_DIR,
186
"Directory where character sets are.", (char**) &charsets_dir,
187
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
188
{"comments", 'i', "Write additional information.",
189
(char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
191
{"compatible", OPT_COMPATIBLE,
192
"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.",
193
(char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
194
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
195
{"compact", OPT_COMPACT,
196
"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",
197
(char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
199
{"complete-insert", 'c', "Use complete insert statements.",
200
(char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
201
NO_ARG, 0, 0, 0, 0, 0, 0},
202
{"compress", 'C', "Use compression in server/client protocol.",
203
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
205
{"create-options", OPT_CREATE_OPTIONS,
206
"Include all DRIZZLE specific create options.",
207
(char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
210
"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.",
211
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
213
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
214
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
215
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
216
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
217
(char**) &debug_info_flag, (char**) &debug_info_flag,
218
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
219
{"default-character-set", OPT_DEFAULT_CHARSET,
220
"Set the default character set.", (char**) &default_charset,
221
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
222
{"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
223
(char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
225
{"delete-master-logs", OPT_DELETE_MASTER_LOGS,
226
"Delete logs on master after backup. This automatically enables --master-data.",
227
(char**) &opt_delete_master_logs, (char**) &opt_delete_master_logs, 0,
228
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
229
{"disable-keys", 'K',
230
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (char**) &opt_disable_keys,
231
(char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
232
{"dump-slave", OPT_DRIZZLEDUMP_SLAVE_DATA,
233
"This causes the binary log position and filename of the master to be "
234
"appended to the dumped data output. Setting the value to 1, will print"
235
"it as a CHANGE MASTER command in the dumped data output; if equal"
236
" to 2, that command will be prefixed with a comment symbol. "
237
"This option will turn --lock-all-tables on, unless "
238
"--single-transaction is specified too (in which case a "
239
"global read lock is only taken a short time at the beginning of the dump "
240
"- don't forget to read about --single-transaction below). In all cases "
241
"any action on logs will happen at the exact moment of the dump."
242
"Option automatically turns --lock-tables off.",
243
(char**) &opt_slave_data, (char**) &opt_slave_data, 0,
244
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
245
{"events", 'E', "Dump events.",
246
(char**) &opt_events, (char**) &opt_events, 0, GET_BOOL,
247
NO_ARG, 0, 0, 0, 0, 0, 0},
248
{"extended-insert", 'e',
249
"Allows utilization of the new, much faster INSERT syntax.",
250
(char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
252
{"fields-terminated-by", OPT_FTB,
253
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
254
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
255
{"fields-enclosed-by", OPT_ENC,
256
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
257
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
258
{"fields-optionally-enclosed-by", OPT_O_ENC,
259
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
260
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
261
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
262
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
263
{"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
264
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
266
{"flush-logs", 'F', "Flush logs file in server before starting dump. "
267
"Note that if you dump many databases at once (using the option "
268
"--databases= or --all-databases), the logs will be flushed for "
269
"each database dumped. The exception is when using --lock-all-tables "
271
"in this case the logs will be flushed only once, corresponding "
272
"to the moment all tables are locked. So if you want your dump and "
273
"the log flush to happen at the same exact moment you should use "
274
"--lock-all-tables or --master-data with --flush-logs",
275
(char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
277
{"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement "
278
"after dumping the DRIZZLE database. This option should be used any "
279
"time the dump contains the DRIZZLE database and any other database "
280
"that depends on the data in the DRIZZLE database for proper restore. ",
281
(char**) &flush_privileges, (char**) &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
283
{"force", 'f', "Continue even if we get an sql-error.",
284
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
286
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
287
NO_ARG, 0, 0, 0, 0, 0, 0},
288
{"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
289
"VARBINARY, BLOB) in hexadecimal format.",
290
(char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
291
{"host", 'h', "Connect to host.", (char**) ¤t_host,
292
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
293
{"ignore-table", OPT_IGNORE_TABLE,
294
"Do not dump the specified table. To specify more than one table to ignore, "
295
"use the directive multiple times, once for each table. Each table must "
296
"be specified with both database and table names, e.g. --ignore-table=database.table",
297
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
298
{"include-master-host-port", OPT_DRIZZLEDUMP_INCLUDE_MASTER_HOST_PORT,
299
"Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
300
(char**) &opt_include_master_host_port,
301
(char**) &opt_include_master_host_port,
304
{"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
305
(char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
307
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
308
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
309
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
310
{"lock-all-tables", 'x', "Locks all tables across all databases. This "
311
"is achieved by taking a global read lock for the duration of the whole "
312
"dump. Automatically turns --single-transaction and --lock-tables off.",
313
(char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
315
{"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
316
(char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
317
{"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.",
318
(char**) &log_error_file, (char**) &log_error_file, 0, GET_STR,
319
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
320
{"master-data", OPT_MASTER_DATA,
321
"This causes the binary log position and filename to be appended to the "
322
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
323
" to 2, that command will be prefixed with a comment symbol. "
324
"This option will turn --lock-all-tables on, unless "
325
"--single-transaction is specified too (in which case a "
326
"global read lock is only taken a short time at the beginning of the dump "
327
"- don't forget to read about --single-transaction below). In all cases "
328
"any action on logs will happen at the exact moment of the dump."
329
"Option automatically turns --lock-tables off.",
330
(char**) &opt_master_data, (char**) &opt_master_data, 0,
331
GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
332
{"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
333
(char**) &opt_max_allowed_packet, (char**) &opt_max_allowed_packet, 0,
334
GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
335
(int64_t) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
336
{"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
337
(char**) &opt_net_buffer_length, (char**) &opt_net_buffer_length, 0,
338
GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
339
MALLOC_OVERHEAD-1024, 1024, 0},
340
{"no-autocommit", OPT_AUTOCOMMIT,
341
"Wrap tables with autocommit/commit statements.",
342
(char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
344
{"no-create-db", 'n',
345
"'CREATE DATABASE /*!32312 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.}.",
346
(char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
348
{"no-create-info", 't', "Don't write table creation info.",
349
(char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
350
NO_ARG, 0, 0, 0, 0, 0, 0},
351
{"no-data", 'd', "No row information.", (char**) &opt_no_data,
352
(char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
353
{"no-set-names", 'N',
354
"Deprecated. Use --skip-set-charset instead.",
355
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
356
{"opt", OPT_OPTIMIZE,
357
"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.",
358
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
359
{"order-by-primary", OPT_ORDER_BY_PRIMARY,
360
"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.",
361
(char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
363
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
364
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
365
{"port", 'P', "Port number to use for connection.", (char**) &opt_drizzle_port,
366
(char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
368
{"quick", 'q', "Don't buffer query, dump directly to stdout.",
369
(char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
370
{"quote-names",'Q', "Quote table and column names with backticks (`).",
371
(char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
373
{"replace", OPT_DRIZZLE_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
374
(char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
377
"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).",
378
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
379
{"routines", 'R', "Dump stored routines (functions and procedures).",
380
(char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
381
NO_ARG, 0, 0, 0, 0, 0, 0},
382
{"set-variable", 'O',
383
"Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
384
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
386
Note that the combination --single-transaction --master-data
387
will give bullet-proof binlog position only if server >=4.1.3. That's the
388
old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
390
{"single-transaction", OPT_TRANSACTION,
391
"Creates a consistent snapshot by dumping all tables in a single "
392
"transaction. Works ONLY for tables stored in storage engines which "
393
"support multiversioning (currently only InnoDB does); the dump is NOT "
394
"guaranteed to be consistent for other storage engines. "
395
"While a --single-transaction dump is in process, to ensure a valid "
396
"dump file (correct table contents and binary log position), no other "
397
"connection should use the following statements: ALTER TABLE, DROP "
398
"TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
399
"isolated from them. Option automatically turns off --lock-tables.",
400
(char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
401
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
402
{"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
403
(char**) &opt_dump_date, (char**) &opt_dump_date, 0,
404
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
405
{"skip-opt", OPT_SKIP_OPTIMIZATION,
406
"Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
407
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
409
"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.",
410
(char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
411
{"tables", OPT_TABLES, "Overrides option --databases (-B).",
412
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
413
#ifndef DONT_ALLOW_USER_CHANGE
414
{"user", 'u', "User for login if not current user.",
415
(char**) ¤t_user, (char**) ¤t_user, 0, GET_STR, REQUIRED_ARG,
418
{"verbose", 'v', "Print info about the various stages.",
419
(char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
420
{"version",'V', "Output version information and exit.", 0, 0, 0,
421
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
422
{"where", 'w', "Dump only selected records; QUOTES mandatory!",
423
(char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
424
{"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
425
NO_ARG, 0, 0, 0, 0, 0, 0},
426
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
429
static const char *load_default_groups[]= { "drizzledump","client",0 };
431
static void maybe_exit(int error);
146
432
static void die(int error, const char* reason, ...);
147
static void write_header(char *db_name);
148
static int dump_selected_tables(const string &db, const vector<string> &table_names);
149
static int dump_databases(const vector<string> &db_names);
433
static void maybe_die(int error, const char* reason, ...);
434
static void write_header(FILE *sql_file, char *db_name);
435
static void print_value(FILE *file, DRIZZLE_RES *result, DRIZZLE_ROW row,
436
const char *prefix,const char *name,
438
static int dump_selected_tables(char *db, char **table_names, int tables);
439
static int dump_all_tables_in_db(char *db);
440
static int init_dumping_tables(char *);
441
static int init_dumping(char *, int init_func(char*));
442
static int dump_databases(char **);
150
443
static int dump_all_databases(void);
151
int get_server_type();
152
void dump_all_tables(void);
153
void generate_dump(void);
154
void generate_dump_db(void);
156
void dump_all_tables(void)
158
std::vector<DrizzleDumpDatabase*>::iterator i;
159
for (i= database_store.begin(); i != database_store.end(); ++i)
161
if ((not (*i)->populateTables()) && (not ignore_errors))
162
maybe_exit(EX_DRIZZLEERR);
166
void generate_dump(void)
168
std::vector<DrizzleDumpDatabase*>::iterator i;
172
cout << endl << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;"
173
<< endl << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
177
cout << "SET AUTOCOMMIT=0;" << endl;
179
for (i= database_store.begin(); i != database_store.end(); ++i)
181
DrizzleDumpDatabase *database= *i;
187
cout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;"
188
<< endl << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
192
void generate_dump_db(void)
194
std::vector<DrizzleDumpDatabase*>::iterator i;
195
DrizzleStringBuf sbuf(1024);
198
destination_connection= new DrizzleDumpConnection(opt_destination_host,
199
opt_destination_port, opt_destination_user, opt_destination_password,
202
catch (std::exception&)
204
cerr << "Could not connect to destination database server" << endl;
205
maybe_exit(EX_DRIZZLEERR);
207
sbuf.setConnection(destination_connection);
208
std::ostream sout(&sbuf);
209
sout.exceptions(ios_base::badbit);
213
sout << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;" << endl;
214
sout << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
218
cout << "SET AUTOCOMMIT=0;" << endl;
220
for (i= database_store.begin(); i != database_store.end(); ++i)
224
DrizzleDumpDatabase *database= *i;
227
catch (std::exception&)
229
std::cout << _("Error inserting into destination database") << std::endl;
230
if (not ignore_errors)
231
maybe_exit(EX_DRIZZLEERR);
237
sout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;" << endl;
238
sout << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
444
static char *quote_name(const char *name, char *buff, bool force);
445
char check_if_ignore_table(const char *table_name, char *table_type);
446
static char *primary_key_fields(const char *table_name);
449
Print the supplied message if in verbose mode
454
... variable number of parameters
456
static void verbose_msg(const char *fmt, ...)
465
vfprintf(stderr, fmt, args);
243
472
exit with message if ferror(file)
250
479
static void check_io(FILE *file)
252
481
if (ferror(file))
253
die(EX_EOF, _("Got errno %d on write"), errno);
256
static void write_header(char *db_name)
258
if ((not opt_compact) and (opt_comments))
260
cout << "-- drizzledump " << VERSION << " libdrizzle "
261
<< drizzle_version() << ", for " << HOST_VENDOR << "-" << HOST_OS
262
<< " (" << HOST_CPU << ")" << endl << "--" << endl;
263
cout << "-- Host: " << current_host << " Database: " << db_name << endl;
264
cout << "-- ------------------------------------------------------" << endl;
265
cout << "-- Server version\t" << db_connection->getServerVersion();
266
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
267
cout << " (MySQL server)";
268
else if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_DRIZZLE_FOUND)
269
cout << " (Drizzle server)";
270
cout << endl << endl;
482
die(EX_EOF, "Got errno %d on write", errno);
485
static void print_version(void)
487
printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
488
drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
489
} /* print_version */
492
static void short_usage_sub(void)
494
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
495
printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
497
printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
501
static void usage(void)
504
puts("By Igor Romanenko, Monty, Jani & Sinisa");
505
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");
506
puts("Dumping definition and data DRIZZLE database or table");
508
print_defaults("drizzle",load_default_groups);
509
my_print_help(my_long_options);
510
my_print_variables(my_long_options);
514
static void short_usage(void)
517
printf("For more options, use %s --help\n", my_progname);
520
static void write_header(FILE *sql_file, char *db_name)
524
fputs("<?xml version=\"1.0\"?>\n", sql_file);
526
Schema reference. Allows use of xsi:nil for NULL values and
527
xsi:type to define an element's data type.
529
fputs("<drizzledump ", sql_file);
530
fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
532
fputs(">\n", sql_file);
535
else if (!opt_compact)
540
"-- DRIZZLE dump %s Distrib %s, for %s (%s)\n--\n",
541
DUMP_VERSION, drizzle_get_client_info(),
542
SYSTEM_TYPE, MACHINE_TYPE);
543
fprintf(sql_file, "-- Host: %s Database: %s\n",
544
current_host ? current_host : "localhost", db_name ? db_name :
546
fputs("-- ------------------------------------------------------\n",
548
fprintf(sql_file, "-- Server version\t%s\n",
549
drizzle_get_server_info(&drizzle_connection));
553
"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
554
"\n/*!40101 SET NAMES %s */;\n",default_charset);
558
fprintf(md_result_file,"\
559
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\
560
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\
272
565
} /* write_header */
275
568
static void write_footer(FILE *sql_file)
572
fputs("</drizzledump>\n", sql_file);
575
else if (!opt_compact)
579
fprintf(md_result_file,"\
580
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\
581
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n");
584
fprintf(sql_file, "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
279
585
if (opt_comments)
281
587
if (opt_dump_date)
283
boost::posix_time::ptime time(boost::posix_time::second_clock::local_time());
590
get_date(time_str, GETDATE_DATE_TIME, 0);
284
591
fprintf(sql_file, "-- Dump completed on %s\n",
285
boost::posix_time::to_simple_string(time).c_str());
288
595
fprintf(sql_file, "-- Dump completed\n");
334
880
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
337
fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
883
fprintf(stderr, "%s: %s\n", my_progname, buffer);
340
886
ignore_errors= 0; /* force the exit */
341
887
maybe_exit(error_num);
892
Prints out an error message and maybe kills the process.
896
error_num - process return value
897
fmt_reason - a format string for use by vsnprintf.
898
... - variable arguments for above fmt_reason string
901
This call prints out the formatted error message to stderr and then
902
terminates the process, unless the --force command line option is used.
904
This call should be used for non-fatal errors (such as database
905
errors) that the code may still be able to continue to the next unit
909
static void maybe_die(int error_num, const char* fmt_reason, ...)
913
va_start(args,fmt_reason);
914
vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
917
fprintf(stderr, "%s: %s\n", my_progname, buffer);
920
maybe_exit(error_num);
926
Sends a query to server, optionally reads result, prints error message if
930
drizzle_query_with_error_report()
931
drizzle_con connection to use
932
res if non zero, result will be put there with
933
drizzle_store_result()
934
query query to send to server
937
0 query sending and (if res!=0) result reading went ok
941
static int drizzle_query_with_error_report(DRIZZLE *drizzle_con, DRIZZLE_RES **res,
944
if (drizzle_query(drizzle_con, query) ||
945
(res && !((*res)= drizzle_store_result(drizzle_con))))
947
maybe_die(EX_DRIZZLEERR, "Couldn't execute '%s': %s (%d)",
948
query, drizzle_error(drizzle_con), drizzle_errno(drizzle_con));
956
Switch charset for results to some specified charset. If the server does not
957
support character_set_results variable, nothing can be done here. As for
958
whether something should be done here, future new callers of this function
959
should be aware that the server lacking the facility of switching charsets is
962
@note If the server lacks support, then nothing is changed and no error
963
condition is returned.
965
@returns whether there was an error or not
967
static int switch_character_set_results(DRIZZLE *drizzle, const char *cs_name)
969
char query_buffer[QUERY_LENGTH];
972
/* Server lacks facility. This is not an error, by arbitrary decision . */
973
if (!server_supports_switching_charsets)
976
query_length= snprintf(query_buffer,
977
sizeof (query_buffer),
978
"SET SESSION character_set_results = '%s'",
979
(const char *) cs_name);
981
return drizzle_real_query(drizzle, query_buffer, query_length);
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= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
1001
O_WRONLY, MYF(MY_WME));
344
1006
static void free_resources(void)
346
1008
if (md_result_file && md_result_file != stdout)
347
fclose(md_result_file);
348
opt_password.erase();
1009
my_fclose(md_result_file, MYF(0));
1011
if (hash_inited(&ignore_table))
1012
hash_free(&ignore_table);
1014
free_defaults(defaults_argv);
352
void maybe_exit(int error)
1019
static void maybe_exit(int error)
354
1021
if (!first_error)
355
1022
first_error= error;
356
1023
if (ignore_errors)
358
delete db_connection;
359
delete destination_connection;
1026
drizzle_close(drizzle);
360
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
verbose_msg("-- Connecting to %s...\n", host ? host : "localhost");
1039
drizzle_create(&drizzle_connection);
1041
drizzle_options(&drizzle_connection,DRIZZLE_OPT_COMPRESS,NULL);
1042
if (!(drizzle= drizzle_connect(&drizzle_connection,host,user,passwd,
1043
NULL,opt_drizzle_port, NULL,
1046
DB_error(&drizzle_connection, "when trying to connect");
1051
} /* connect_to_db */
1055
** dbDisconnect -- disconnects from the host.
1057
static void dbDisconnect(char *host)
1059
verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost");
1060
drizzle_close(drizzle);
1061
} /* dbDisconnect */
1064
static void unescape(FILE *file,char *pos,uint length)
1068
if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
1069
die(EX_DRIZZLEERR, "Couldn't allocate memory");
1071
drizzle_escape_string(tmp, pos, length);
1081
static bool test_if_special_chars(const char *str)
1083
for ( ; *str ; str++)
1084
if (!my_isvar(charset_info,*str) && *str != '$')
1087
} /* test_if_special_chars */
1092
quote_name(name, buff, force)
1094
Quotes char string, taking into account compatible mode
1098
name Unquoted string containing that which will be quoted
1099
buff The buffer that contains the quoted value, also returned
1100
force Flag to make it ignore 'test_if_special_chars'
1107
static char *quote_name(const char *name, char *buff, bool force)
1110
char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
1112
if (!force && !opt_quoted && !test_if_special_chars(name))
1113
return (char*) name;
1128
Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1132
name name of the table
1133
buff quoted name of the table
1136
Quote \, _, ' and % characters
1138
Note: Because DRIZZLE uses the C escape syntax in strings
1139
(for example, '\n' to represent newline), you must double
1140
any '\' that you use in your LIKE strings. For example, to
1141
search for '\n', specify it as '\\n'. To search for '\', specify
1142
it as '\\\\' (the backslashes are stripped once by the parser
1143
and another time when the pattern match is done, leaving a
1144
single backslash to be matched).
1146
Example: "t\1" => "t\\\\1"
1149
static char *quote_for_like(const char *name, char *buff)
1161
else if (*name == '\'' || *name == '_' || *name == '%')
1172
Quote and print a string.
1176
xml_file - output file
1177
str - string to print
1181
Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1184
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
1188
for (end= str + len; str != end; str++)
1192
fputs("<", xml_file);
1195
fputs(">", xml_file);
1198
fputs("&", xml_file);
1201
fputs(""", xml_file);
1204
fputc(*str, xml_file);
1213
Print xml tag. Optionally add attribute(s).
1216
print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1217
..., attribute_name_n, attribute_value_n, NULL)
1218
xml_file - output file
1219
sbeg - line beginning
1220
line_end - line ending
1221
tag_name - XML tag name.
1222
first_attribute_name - tag and first attribute
1223
first_attribute_value - (Implied) value of first attribute
1224
attribute_name_n - attribute n
1225
attribute_value_n - value of attribute n
1228
Print XML tag with any number of attribute="value" pairs to the xml_file.
1231
sbeg<tag_name first_attribute_name="first_attribute_value" ...
1232
attribute_name_n="attribute_value_n">send
1234
Additional arguments must be present in attribute/value pairs.
1235
The last argument should be the null character pointer.
1236
All attribute_value arguments MUST be NULL terminated strings.
1237
All attribute_value arguments will be quoted before output.
1240
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1241
const char* line_end,
1242
const char* tag_name,
1243
const char* first_attribute_name, ...)
1246
const char *attribute_name, *attribute_value;
1248
fputs(sbeg, xml_file);
1249
fputc('<', xml_file);
1250
fputs(tag_name, xml_file);
1252
va_start(arg_list, first_attribute_name);
1253
attribute_name= first_attribute_name;
1254
while (attribute_name != NULL)
1256
attribute_value= va_arg(arg_list, char *);
1257
assert(attribute_value != NULL);
1259
fputc(' ', xml_file);
1260
fputs(attribute_name, xml_file);
1261
fputc('\"', xml_file);
1263
print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
1264
fputc('\"', xml_file);
1266
attribute_name= va_arg(arg_list, char *);
1270
fputc('>', xml_file);
1271
fputs(line_end, xml_file);
1277
Print xml tag with for a field that is null
1280
print_xml_null_tag()
1281
xml_file - output file
1282
sbeg - line beginning
1283
stag_atr - tag and attribute
1284
sval - value of attribute
1285
line_end - line ending
1288
Print tag with one attribute to the xml_file. Format is:
1289
<stag_atr="sval" xsi:nil="true"/>
1291
sval MUST be a NULL terminated string.
1292
sval string will be qouted before output.
1295
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1296
const char* stag_atr, const char* sval,
1297
const char* line_end)
1299
fputs(sbeg, xml_file);
1300
fputs("<", xml_file);
1301
fputs(stag_atr, xml_file);
1302
fputs("\"", xml_file);
1303
print_quoted_xml(xml_file, sval, strlen(sval));
1304
fputs("\" xsi:nil=\"true\" />", xml_file);
1305
fputs(line_end, xml_file);
1311
Print xml tag with many attributes.
1315
xml_file - output file
1316
row_name - xml tag name
1317
tableRes - query result
1321
Print tag with many attribute to the xml_file. Format is:
1322
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
1324
All atributes and values will be quoted before output.
1327
static void print_xml_row(FILE *xml_file, const char *row_name,
1328
DRIZZLE_RES *tableRes, DRIZZLE_ROW *row)
1331
DRIZZLE_FIELD *field;
1332
uint32_t *lengths= drizzle_fetch_lengths(tableRes);
1334
fprintf(xml_file, "\t\t<%s", row_name);
1336
drizzle_field_seek(tableRes, 0);
1337
for (i= 0; (field= drizzle_fetch_field(tableRes)); i++)
1341
fputc(' ', xml_file);
1342
print_quoted_xml(xml_file, field->name, field->name_length);
1343
fputs("=\"", xml_file);
1344
print_quoted_xml(xml_file, (*row)[i], lengths[i]);
1345
fputc('"', xml_file);
1349
fputs(" />\n", xml_file);
1355
Print hex value for blob data.
1359
output_file - output file
1360
str - string to print
1364
Print hex value for blob data.
1367
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
1369
/* sakaik got the idea to to provide blob's in hex notation. */
1370
const char *ptr= str, *end= ptr + len;
1371
for (; ptr < end ; ptr++)
1372
fprintf(output_file, "%02X", *((unsigned char *)ptr));
1373
check_io(output_file);
1377
get_table_structure -- retrievs database structure, prints out corresponding
1378
CREATE statement and fills out insert_pat if the table is the type we will
1384
table_type - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1385
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1388
number of fields in table, 0 if error
1391
static uint get_table_structure(char *table, char *db, char *table_type,
1394
bool init=0, delayed, write_data, complete_insert;
1395
uint64_t num_fields;
1396
char *result_table, *opt_quoted_table;
1397
const char *insert_option;
1398
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
1399
char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
1400
FILE *sql_file= md_result_file;
1402
DRIZZLE_RES *result;
1405
*ignore_flag= check_if_ignore_table(table, table_type);
1407
delayed= opt_delayed;
1408
if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
1411
verbose_msg("-- Warning: Unable to use delayed inserts for table '%s' "
1412
"because it's of type %s\n", table, table_type);
1416
if ((write_data= !(*ignore_flag & IGNORE_DATA)))
1418
complete_insert= opt_complete_insert;
1422
insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
1423
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : "");
1425
verbose_msg("-- Retrieving table structure for table %s...\n", table);
1427
len= snprintf(query_buff, sizeof(query_buff),
1428
"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
1429
(opt_quoted || opt_keywords));
1431
result_table= quote_name(table, table_buff, 1);
1432
opt_quoted_table= quote_name(table, table_buff2, 0);
1434
if (opt_order_by_primary)
1437
order_by= primary_key_fields(result_table);
1440
if (!opt_xml && !drizzle_query_with_error_report(drizzle, 0, query_buff))
1442
/* using SHOW CREATE statement */
1443
if (!opt_no_create_info)
1445
/* Make an sql-file, if path was given iow. option -T was given */
1446
char buff[20+FN_REFLEN];
1447
const DRIZZLE_FIELD *field;
1449
snprintf(buff, sizeof(buff), "show create table %s", result_table);
1451
if (switch_character_set_results(drizzle, "binary") ||
1452
drizzle_query_with_error_report(drizzle, &result, buff) ||
1453
switch_character_set_results(drizzle, default_charset))
1458
if (!(sql_file= open_sql_file_for_table(table)))
1461
write_header(sql_file, db);
1463
if (!opt_xml && opt_comments)
1465
if (strcmp (table_type, "VIEW") == 0) /* view */
1466
fprintf(sql_file, "\n--\n-- Temporary table structure for view %s\n--\n\n",
1469
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1476
Even if the "table" is a view, we do a DROP TABLE here. The
1477
view-specific code below fills in the DROP VIEW.
1479
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",
1484
field= drizzle_fetch_field_direct(result, 0);
1485
if (strcmp(field->name, "View") == 0)
1487
char *scv_buff= NULL;
1489
verbose_msg("-- It's a view, create dummy table for view\n");
1491
/* save "show create" statement for later */
1492
if ((row= drizzle_fetch_row(result)) && (scv_buff=row[1]))
1493
scv_buff= my_strdup(scv_buff, MYF(0));
1495
drizzle_free_result(result);
1498
Create a table with the same name as the view and with columns of
1499
the same name in order to satisfy views that depend on this view.
1500
The table will be removed when the actual view is created.
1502
The properties of each column, aside from the data type, are not
1503
preserved in this temporary table, because they are not necessary.
1505
This will not be necessary once we can determine dependencies
1506
between views and can simply dump them in the appropriate order.
1508
snprintf(query_buff, sizeof(query_buff),
1509
"SHOW FIELDS FROM %s", result_table);
1510
if (switch_character_set_results(drizzle, "binary") ||
1511
drizzle_query_with_error_report(drizzle, &result, query_buff) ||
1512
switch_character_set_results(drizzle, default_charset))
1515
View references invalid or privileged table/col/fun (err 1356),
1516
so we cannot create a stand-in table. Be defensive and dump
1517
a comment with the view's 'show create' statement. (Bug #17371)
1520
if (drizzle_errno(drizzle) == ER_VIEW_INVALID)
1521
fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
1530
if (drizzle_num_rows(result))
1535
We have already dropped any table of the same name above, so
1536
here we just drop the view.
1539
fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
1545
"/*!50001 CREATE TABLE %s (\n",
1549
Get first row, following loop will prepend comma - keeps from
1550
having to know if the row being printed is last to determine if
1551
there should be a _trailing_ comma.
1554
row= drizzle_fetch_row(result);
1556
fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0),
1559
while((row= drizzle_fetch_row(result)))
1561
/* col name, col type */
1562
fprintf(sql_file, ",\n %s %s",
1563
quote_name(row[0], name_buff, 0), row[1]);
1565
fprintf(sql_file, "\n) */;\n");
1569
drizzle_free_result(result);
1572
my_fclose(sql_file, MYF(MY_WME));
1578
row= drizzle_fetch_row(result);
1580
fprintf(sql_file, "%s;\n", row[1]);
1583
drizzle_free_result(result);
1585
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1587
if (drizzle_query_with_error_report(drizzle, &result, query_buff))
1590
my_fclose(sql_file, MYF(MY_WME));
1595
If write_data is true, then we build up insert statements for
1596
the table's data. Note: in subsequent lines of code, this test
1597
will have to be performed each time we are appending to
1602
if (opt_replace_into)
1603
insert_pat.append("REPLACE ");
1605
insert_pat.append("INSERT ");
1606
insert_pat.append(insert_option);
1607
insert_pat.append("INTO ");
1608
insert_pat.append(opt_quoted_table);
1609
if (complete_insert)
1611
insert_pat.append(" (");
1615
insert_pat.append(" VALUES ");
1616
if (!extended_insert)
1617
insert_pat.append("(");
1621
while ((row= drizzle_fetch_row(result)))
1623
if (complete_insert)
1627
insert_pat.append(", ");
1630
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1633
num_fields= drizzle_num_rows(result);
1634
drizzle_free_result(result);
1638
verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
1639
my_progname, drizzle_error(drizzle));
1641
snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1643
if (drizzle_query_with_error_report(drizzle, &result, query_buff))
1646
/* Make an sql-file, if path was given iow. option -T was given */
1647
if (!opt_no_create_info)
1651
if (!(sql_file= open_sql_file_for_table(table)))
1653
write_header(sql_file, db);
1655
if (!opt_xml && opt_comments)
1656
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
1659
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
1661
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1663
print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1670
if (opt_replace_into)
1671
insert_pat.append("REPLACE ");
1673
insert_pat.append("INSERT ");
1674
insert_pat.append(insert_option);
1675
insert_pat.append("INTO ");
1676
insert_pat.append(result_table);
1677
if (complete_insert)
1678
insert_pat.append(" (");
1681
insert_pat.append(" VALUES ");
1682
if (!extended_insert)
1683
insert_pat.append("(");
1687
while ((row= drizzle_fetch_row(result)))
1689
uint32_t *lengths= drizzle_fetch_lengths(result);
1692
if (!opt_xml && !opt_no_create_info)
1694
fputs(",\n",sql_file);
1697
if (complete_insert)
1698
insert_pat.append(", ");
1701
if (complete_insert)
1702
insert_pat.append(quote_name(row[SHOW_FIELDNAME], name_buff, 0));
1703
if (!opt_no_create_info)
1707
print_xml_row(sql_file, "field", result, &row);
1712
fprintf(sql_file, " %s.%s %s", result_table,
1713
quote_name(row[SHOW_FIELDNAME],name_buff, 0),
1716
fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
1719
if (row[SHOW_DEFAULT])
1721
fputs(" DEFAULT ", sql_file);
1722
unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
1724
if (!row[SHOW_NULL][0])
1725
fputs(" NOT NULL", sql_file);
1726
if (row[SHOW_EXTRA][0])
1727
fprintf(sql_file, " %s",row[SHOW_EXTRA]);
1731
num_fields= drizzle_num_rows(result);
1732
drizzle_free_result(result);
1733
if (!opt_no_create_info)
1735
/* Make an sql-file, if path was given iow. option -T was given */
1736
char buff[20+FN_REFLEN];
1737
uint keynr,primary_key;
1738
snprintf(buff, sizeof(buff), "show keys from %s", result_table);
1739
if (drizzle_query_with_error_report(drizzle, &result, buff))
1741
if (drizzle_errno(drizzle) == ER_WRONG_OBJECT)
1744
fputs("\t\t<options Comment=\"view\" />\n", sql_file);
1747
fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
1748
my_progname, result_table, drizzle_error(drizzle));
1750
my_fclose(sql_file, MYF(MY_WME));
1754
/* Find first which key is primary key */
1756
primary_key=INT_MAX;
1757
while ((row= drizzle_fetch_row(result)))
1759
if (atoi(row[3]) == 1)
1762
#ifdef FORCE_PRIMARY_KEY
1763
if (atoi(row[1]) == 0 && primary_key == INT_MAX)
1766
if (!strcmp(row[2],"PRIMARY"))
1773
drizzle_data_seek(result,0);
1775
while ((row= drizzle_fetch_row(result)))
1779
print_xml_row(sql_file, "key", result, &row);
1783
if (atoi(row[3]) == 1)
1786
putc(')', sql_file);
1787
if (atoi(row[1])) /* Test if duplicate key */
1788
/* Duplicate allowed */
1789
fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
1790
else if (keynr == primary_key)
1791
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
1793
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
1797
putc(',', sql_file);
1798
fputs(quote_name(row[4], name_buff, 0), sql_file);
1800
fprintf(sql_file, " (%s)",row[7]); /* Sub key */
1803
drizzle_free_result(result);
1807
putc(')', sql_file);
1808
fputs("\n)",sql_file);
1812
/* Get DRIZZLE specific create options */
1815
char show_name_buff[NAME_LEN*2+2+24];
1817
/* Check memory for quote_for_like() */
1818
snprintf(buff, sizeof(buff), "show table status like %s",
1819
quote_for_like(table, show_name_buff));
1821
if (drizzle_query_with_error_report(drizzle, &result, buff))
1823
if (drizzle_errno(drizzle) != ER_PARSE_ERROR)
1824
{ /* If old DRIZZLE version */
1825
verbose_msg("-- Warning: Couldn't get status information for " \
1826
"table %s (%s)\n", result_table,drizzle_error(drizzle));
1829
else if (!(row= drizzle_fetch_row(result)))
1832
"Error: Couldn't read status information for table %s (%s)\n",
1833
result_table,drizzle_error(drizzle));
1838
print_xml_row(sql_file, "options", result, &row);
1841
fputs("/*!",sql_file);
1842
print_value(sql_file,result,row,"engine=","Engine",0);
1843
print_value(sql_file,result,row,"","Create_options",0);
1844
print_value(sql_file,result,row,"comment=","Comment",1);
1845
fputs(" */",sql_file);
1849
drizzle_free_result(result); /* Is always safe to free */
1853
fputs(";\n", sql_file);
1855
fputs("\t</table_structure>\n", sql_file);
1859
if (complete_insert)
1861
insert_pat.append(") VALUES ");
1862
if (!extended_insert)
1863
insert_pat.append("(");
1865
if (sql_file != md_result_file)
1867
fputs("\n", sql_file);
1868
write_footer(sql_file);
1869
my_fclose(sql_file, MYF(MY_WME));
1871
return((uint) num_fields);
1872
} /* get_table_structure */
1874
static void add_load_option(string &str, const char *option,
1875
const char *option_value)
1879
/* Null value means we don't add this option. */
1885
if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
1887
/* It's a hex constant, don't escape */
1888
str.append(option_value);
1892
/* char constant; escape */
1893
field_escape(str, option_value);
1899
Allow the user to specify field terminator strings like:
1900
"'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
1901
This is done by doubling ' and add a end -\ if needed to avoid
1902
syntax errors from the SQL parser.
1905
static void field_escape(string &in, const char *from)
1907
uint end_backslashes= 0;
1916
end_backslashes^=1; /* find odd number of backslashes */
1919
if (*from == '\'' && !end_backslashes)
1921
/* We want a duplicate of "'" for DRIZZLE */
1928
/* Add missing backslashes if user has specified odd number of backs.*/
1929
if (end_backslashes)
1942
dump_table saves database contents as a series of INSERT statements.
1953
static void dump_table(char *table, char *db)
1956
char buf[200], table_buff[NAME_LEN+3];
1957
string query_string;
1958
char table_type[NAME_LEN];
1959
char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
1961
uint32_t rownr, row_break, total_length, init_length;
1964
DRIZZLE_FIELD *field;
1969
Make sure you get the create table info before the following check for
1970
--no-data flag below. Otherwise, the create table info won't be printed.
1972
num_fields= get_table_structure(table, db, table_type, &ignore_flag);
1975
The "table" could be a view. If so, we don't do anything here.
1977
if (strcmp(table_type, "VIEW") == 0)
1980
/* Check --no-data flag */
1983
verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n",
1989
If the table type is a merge table or any type that has to be
1990
_completely_ ignored and no data dumped
1992
if (ignore_flag & IGNORE_DATA)
1994
verbose_msg("-- Warning: Skipping data for table '%s' because " \
1995
"it's of type %s\n", table, table_type);
1998
/* Check that there are any fields in the table */
1999
if (num_fields == 0)
2001
verbose_msg("-- Skipping dump data for table '%s', it has no fields\n",
2007
Check --skip-events flag: it is not enough to skip creation of events
2008
discarding SHOW CREATE EVENT statements generation. The myslq.event
2009
table data should be skipped too.
2011
if (!opt_events && !my_strcasecmp(&my_charset_utf8_general_ci, db, "mysql") &&
2012
!my_strcasecmp(&my_charset_utf8_general_ci, table, "event"))
2014
verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n");
2018
result_table= quote_name(table,table_buff, 1);
2019
opt_quoted_table= quote_name(table, table_buff2, 0);
2021
verbose_msg("-- Sending SELECT query...\n");
2023
query_string.clear();
2024
query_string.reserve(1024);
2028
char filename[FN_REFLEN], tmp_path[FN_REFLEN];
2031
Convert the path to native os format
2032
and resolve to the full filepath.
2034
convert_dirname(tmp_path,path,NULL);
2035
my_load_path(tmp_path, tmp_path, NULL);
2036
fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
2038
/* Must delete the file that 'INTO OUTFILE' will write to */
2039
my_delete(filename, MYF(0));
2041
/* convert to a unix path name to stick into the query */
2042
to_unix_path(filename);
2044
/* now build the query string */
2046
query_string.append( "SELECT * INTO OUTFILE '");
2047
query_string.append( filename);
2048
query_string.append( "'");
2050
if (fields_terminated || enclosed || opt_enclosed || escaped)
2051
query_string.append( " FIELDS");
2053
add_load_option(query_string, " TERMINATED BY ", fields_terminated);
2054
add_load_option(query_string, " ENCLOSED BY ", enclosed);
2055
add_load_option(query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
2056
add_load_option(query_string, " ESCAPED BY ", escaped);
2057
add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
2059
query_string.append( " FROM ");
2060
query_string.append( result_table);
2064
query_string.append( " WHERE ");
2065
query_string.append( where);
2070
query_string.append( " ORDER BY ");
2071
query_string.append( order_by);
2074
if (drizzle_real_query(drizzle, query_string.c_str(), query_string.length()))
2076
DB_error(drizzle, "when executing 'SELECT INTO OUTFILE'");
2082
if (!opt_xml && opt_comments)
2084
fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
2086
check_io(md_result_file);
2089
query_string.append( "SELECT * FROM ");
2090
query_string.append( result_table);
2094
if (!opt_xml && opt_comments)
2096
fprintf(md_result_file, "-- WHERE: %s\n", where);
2097
check_io(md_result_file);
2100
query_string.append( " WHERE ");
2101
query_string.append( where);
2105
if (!opt_xml && opt_comments)
2107
fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
2108
check_io(md_result_file);
2110
query_string.append( " ORDER BY ");
2111
query_string.append( order_by);
2114
if (!opt_xml && !opt_compact)
2116
fputs("\n", md_result_file);
2117
check_io(md_result_file);
2119
if (drizzle_query_with_error_report(drizzle, 0, query_string.c_str()))
2121
DB_error(drizzle, "when retrieving data from server");
2125
res=drizzle_use_result(drizzle);
2127
res=drizzle_store_result(drizzle);
2130
DB_error(drizzle, "when retrieving data from server");
2134
verbose_msg("-- Retrieving rows...\n");
2135
if (drizzle_num_fields(res) != num_fields)
2137
fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
2138
my_progname, result_table);
2139
error= EX_CONSCHECK;
2145
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
2146
check_io(md_result_file);
2148
/* Moved disable keys to after lock per bug 15977 */
2149
if (opt_disable_keys)
2151
fprintf(md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
2153
check_io(md_result_file);
2156
total_length= opt_net_buffer_length; /* Force row break */
2159
init_length=(uint) insert_pat.length()+4;
2161
print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
2165
fprintf(md_result_file, "set autocommit=0;\n");
2166
check_io(md_result_file);
2169
while ((row= drizzle_fetch_row(res)))
2172
uint32_t *lengths= drizzle_fetch_lengths(res);
2174
if (!extended_insert && !opt_xml)
2176
fputs(insert_pat.c_str(),md_result_file);
2177
check_io(md_result_file);
2179
drizzle_field_seek(res,0);
2183
fputs("\t<row>\n", md_result_file);
2184
check_io(md_result_file);
2187
for (i= 0; i < drizzle_num_fields(res); i++)
2190
uint32_t length= lengths[i];
2192
if (!(field= drizzle_fetch_field(res)))
2194
"Not enough fields from table %s! Aborting.\n",
2198
63 is my_charset_bin. If charsetnr is not 63,
2199
we have not a BLOB but a TEXT column.
2200
we'll dump in hex only BLOB columns.
2202
is_blob= (opt_hex_blob && field->charsetnr == 63 &&
2203
(field->type == DRIZZLE_TYPE_VARCHAR ||
2204
field->type == DRIZZLE_TYPE_BLOB)) ? 1 : 0;
2205
if (extended_insert && !opt_xml)
2210
extended_row.append(",");
2216
if (!(field->type & NUM_FLAG))
2219
"length * 2 + 2" is OK for both HEX and non-HEX modes:
2220
- In HEX mode we need exactly 2 bytes per character
2221
plus 2 bytes for '0x' prefix.
2222
- In non-HEX mode we need up to 2 bytes per character,
2223
plus 2 bytes for leading and trailing '\'' characters.
2224
Also we need to reserve 1 byte for terminating '\0'.
2226
char * tmp_str= (char *)malloc(length * 2 + 2 + 1);
2227
memset(tmp_str, '\0', length * 2 + 2 + 1);
2228
if (opt_hex_blob && is_blob)
2230
extended_row.append("0x");
2231
drizzle_hex_string(tmp_str, row[i], length);
2232
extended_row.append(tmp_str);
2236
extended_row.append("'");
2237
drizzle_escape_string(tmp_str,
2239
extended_row.append(tmp_str);
2240
extended_row.append("'");
2246
/* change any strings ("inf", "-inf", "nan") into NULL */
2248
if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2249
my_isalpha(charset_info, ptr[1])))
2250
extended_row.append( "NULL");
2253
extended_row.append( ptr);
2258
extended_row.append("''");
2261
extended_row.append("NULL");
2267
fputc(',', md_result_file);
2268
check_io(md_result_file);
2272
if (!(field->type & NUM_FLAG))
2276
if (opt_hex_blob && is_blob && length)
2278
/* Define xsi:type="xs:hexBinary" for hex encoded data */
2279
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2280
field->name, "xsi:type=", "xs:hexBinary", NULL);
2281
print_blob_as_hex(md_result_file, row[i], length);
2285
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2287
print_quoted_xml(md_result_file, row[i], length);
2289
fputs("</field>\n", md_result_file);
2291
else if (opt_hex_blob && is_blob && length)
2293
fputs("0x", md_result_file);
2294
print_blob_as_hex(md_result_file, row[i], length);
2297
unescape(md_result_file, row[i], length);
2301
/* change any strings ("inf", "-inf", "nan") into NULL */
2305
print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2307
fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2309
fputs("</field>\n", md_result_file);
2311
else if (my_isalpha(charset_info, *ptr) ||
2312
(*ptr == '-' && my_isalpha(charset_info, ptr[1])))
2313
fputs("NULL", md_result_file);
2315
fputs(ptr, md_result_file);
2320
/* The field value is NULL */
2322
fputs("NULL", md_result_file);
2324
print_xml_null_tag(md_result_file, "\t\t", "field name=",
2327
check_io(md_result_file);
2333
fputs("\t</row>\n", md_result_file);
2334
check_io(md_result_file);
2337
if (extended_insert)
2339
uint32_t row_length;
2340
extended_row.append(")");
2341
row_length= 2 + extended_row.length();
2342
if (total_length + row_length < opt_net_buffer_length)
2344
total_length+= row_length;
2345
fputc(',',md_result_file); /* Always row break */
2346
fputs(extended_row.c_str(),md_result_file);
2351
fputs(";\n", md_result_file);
2352
row_break=1; /* This is first row */
2354
fputs(insert_pat.c_str(),md_result_file);
2355
fputs(extended_row.c_str(),md_result_file);
2356
total_length= row_length+init_length;
2358
check_io(md_result_file);
2362
fputs(");\n", md_result_file);
2363
check_io(md_result_file);
2367
/* XML - close table tag and supress regular output */
2369
fputs("\t</table_data>\n", md_result_file);
2370
else if (extended_insert && row_break)
2371
fputs(";\n", md_result_file); /* If not empty table */
2372
fflush(md_result_file);
2373
check_io(md_result_file);
2374
if (drizzle_errno(drizzle))
2376
snprintf(buf, sizeof(buf),
2377
"%s: Error %d: %s when dumping table %s at row: %d\n",
2379
drizzle_errno(drizzle),
2380
drizzle_error(drizzle),
2384
error= EX_CONSCHECK;
2388
/* Moved enable keys to before unlock per bug 15977 */
2389
if (opt_disable_keys)
2391
fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
2393
check_io(md_result_file);
2397
fputs("UNLOCK TABLES;\n", md_result_file);
2398
check_io(md_result_file);
2402
fprintf(md_result_file, "commit;\n");
2403
check_io(md_result_file);
2405
drizzle_free_result(res);
2415
static char *getTableName(int reset)
2417
static DRIZZLE_RES *res= NULL;
2422
if (!(res= drizzle_list_tables(drizzle,NULL)))
2425
if ((row= drizzle_fetch_row(res)))
2426
return((char*) row[0]);
2429
drizzle_data_seek(res,0); /* We want to read again */
2432
drizzle_free_result(res);
2436
} /* getTableName */
364
2439
static int dump_all_databases()
367
drizzle_result_st *tableres;
2442
DRIZZLE_RES *tableres;
370
DrizzleDumpDatabase *database;
373
std::cerr << _("-- Retrieving database structures...") << std::endl;
375
/* Blocking the MySQL privilege tables too because we can't import them due to bug#646187 */
376
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
377
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
379
query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
381
tableres= db_connection->query(query);
382
while ((row= drizzle_row_next(tableres)))
2445
if (drizzle_query_with_error_report(drizzle, &tableres, "SHOW DATABASES"))
2447
while ((row= drizzle_fetch_row(tableres)))
384
std::string database_name(row[0]);
385
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
386
database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
388
database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
390
database->setCollate(row[1]);
391
database_store.push_back(database);
2449
if (dump_all_tables_in_db(row[0]))
393
db_connection->freeResult(tableres);
396
2454
/* dump_all_databases */
399
static int dump_databases(const vector<string> &db_names)
2457
static int dump_databases(char **db_names)
403
DrizzleDumpDatabase *database;
405
for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
2463
for (db= db_names ; *db ; db++)
408
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
409
database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
411
database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
412
database_store.push_back(database);
2465
if (dump_all_tables_in_db(*db))
415
2469
} /* dump_databases */
417
static int dump_selected_tables(const string &db, const vector<string> &table_names)
419
DrizzleDumpDatabase *database;
421
if (db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND)
422
database= new DrizzleDumpDatabaseMySQL(db, db_connection);
424
database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
426
if (not database->populateTables(table_names))
429
if (not ignore_errors)
430
maybe_exit(EX_DRIZZLEERR);
433
database_store.push_back(database);
2473
Table Specific database initalization.
2477
qdatabase quoted name of the database
2484
int init_dumping_tables(char *qdatabase)
2492
DRIZZLE_RES *dbinfo;
2494
snprintf(qbuf, sizeof(qbuf),
2495
"SHOW CREATE DATABASE IF NOT EXISTS %s",
2498
if (drizzle_query(drizzle, qbuf) || !(dbinfo = drizzle_store_result(drizzle)))
2500
/* Old server version, dump generic CREATE DATABASE */
2501
if (opt_drop_database)
2502
fprintf(md_result_file,
2503
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
2505
fprintf(md_result_file,
2506
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
2511
if (opt_drop_database)
2512
fprintf(md_result_file,
2513
"\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
2515
row = drizzle_fetch_row(dbinfo);
2518
fprintf(md_result_file,"\n%s;\n",row[1]);
2520
drizzle_free_result(dbinfo);
2524
} /* init_dumping_tables */
2527
static int init_dumping(char *database, int init_func(char*))
2529
if (drizzle_get_server_version(drizzle) >= 50003 &&
2530
!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
2533
if (drizzle_select_db(drizzle, database))
2535
DB_error(drizzle, "when selecting the database");
2536
return 1; /* If --force */
2538
if (!path && !opt_xml)
2540
if (opt_databases || opt_alldbs)
2543
length of table name * 2 (if name contains quotes), 2 quotes and 0
2545
char quoted_database_buf[NAME_LEN*2+3];
2546
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
2549
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
2550
check_io(md_result_file);
2553
/* Call the view or table specific function */
2554
init_func(qdatabase);
2556
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
2557
check_io(md_result_file);
2560
if (extended_insert)
2561
extended_row.clear();
2563
} /* init_dumping */
2566
/* Return 1 if we should copy the table */
2568
static bool include_table(const unsigned char *hash_key, size_t len)
2570
return !hash_search(&ignore_table, hash_key, len);
2574
static int dump_all_tables_in_db(char *database)
2578
char table_buff[NAME_LEN*2+3];
2579
char hash_key[2*NAME_LEN+2]; /* "db.tablename" */
2581
int using_mysql_db= my_strcasecmp(&my_charset_utf8_general_ci, database, "mysql");
2584
afterdot= my_stpcpy(hash_key, database);
2587
if (init_dumping(database, init_dumping_tables))
2590
print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
2594
query= "LOCK TABLES ";
2595
for (numrows= 0 ; (table= getTableName(1)) ; )
2597
char *end= my_stpcpy(afterdot, table);
2598
if (include_table((unsigned char*) hash_key,end - hash_key))
2601
query.append( quote_name(table, table_buff, 1));
2602
query.append( " READ /*!32311 LOCAL */,");
2605
if (numrows && drizzle_real_query(drizzle, query.c_str(), query.length()-1))
2606
DB_error(drizzle, "when using LOCK TABLES");
2607
/* We shall continue here, if --force was given */
2612
if (drizzle_refresh(drizzle, REFRESH_LOG))
2613
DB_error(drizzle, "when doing refresh");
2614
/* We shall continue here, if --force was given */
2616
while ((table= getTableName(0)))
2618
char *end= my_stpcpy(afterdot, table);
2619
if (include_table((unsigned char*) hash_key, end - hash_key))
2621
dump_table(table,database);
2628
fputs("</database>\n", md_result_file);
2629
check_io(md_result_file);
2632
drizzle_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
2633
if (flush_privileges && using_mysql_db == 0)
2635
fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
2636
fprintf(md_result_file,"\n/*! FLUSH PRIVILEGES */;\n");
2639
} /* dump_all_tables_in_db */
2643
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
2644
table name from the server for the table name given on the command line.
2645
we do this because the table name given on the command line may be a
2646
different case (e.g. T1 vs t1)
2649
pointer to the table name
2653
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2656
DRIZZLE_RES *table_res;
2658
char query[50 + 2*NAME_LEN];
2659
char show_name_buff[FN_REFLEN];
2662
/* Check memory for quote_for_like() */
2663
assert(2*sizeof(old_table_name) < sizeof(show_name_buff));
2664
snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
2665
quote_for_like(old_table_name, show_name_buff));
2667
if (drizzle_query_with_error_report(drizzle, 0, query))
2670
if ((table_res= drizzle_store_result(drizzle)))
2672
uint64_t num_rows= drizzle_num_rows(table_res);
2678
TODO: Return all matching rows
2680
row= drizzle_fetch_row(table_res);
2681
lengths= drizzle_fetch_lengths(table_res);
2682
name= strmake_root(root, row[0], lengths[0]);
2684
drizzle_free_result(table_res);
2690
static int dump_selected_tables(char *db, char **table_names, int tables)
2692
char table_buff[NAME_LEN*2+3];
2693
string lock_tables_query;
2695
char **dump_tables, **pos, **end;
2698
if (init_dumping(db, init_dumping_tables))
2701
init_alloc_root(&root, 8192, 0);
2702
if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2703
die(EX_EOM, "alloc_root failure.");
2705
lock_tables_query= "LOCK TABLES ";
2706
for (; tables > 0 ; tables-- , table_names++)
2708
/* the table name passed on commandline may be wrong case */
2709
if ((*pos= get_actual_table_name(*table_names, &root)))
2711
/* Add found table name to lock_tables_query */
2714
lock_tables_query.append( quote_name(*pos, table_buff, 1));
2715
lock_tables_query.append( " READ /*!32311 LOCAL */,");
2723
free_root(&root, MYF(0));
2725
maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names);
2726
/* We shall countinue here, if --force was given */
2733
if (drizzle_real_query(drizzle, lock_tables_query.c_str(),
2734
lock_tables_query.length()-1))
2738
free_root(&root, MYF(0));
2740
DB_error(drizzle, "when doing LOCK TABLES");
2741
/* We shall countinue here, if --force was given */
2746
if (drizzle_refresh(drizzle, REFRESH_LOG))
2749
free_root(&root, MYF(0));
2750
DB_error(drizzle, "when doing refresh");
2752
/* We shall countinue here, if --force was given */
2755
print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NULL);
2757
/* Dump each selected table */
2758
for (pos= dump_tables; pos < end; pos++)
2759
dump_table(*pos, db);
2761
free_root(&root, MYF(0));
2766
fputs("</database>\n", md_result_file);
2767
check_io(md_result_file);
2770
drizzle_query_with_error_report(drizzle, 0, "UNLOCK TABLES");
436
2772
} /* dump_selected_tables */
438
static int do_flush_tables_read_lock()
2775
static int do_show_master_status(DRIZZLE *drizzle_con)
2778
DRIZZLE_RES *master;
2779
const char *comment_prefix=
2780
(opt_master_data == DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
2781
if (drizzle_query_with_error_report(drizzle_con, &master, "SHOW MASTER STATUS"))
2787
row= drizzle_fetch_row(master);
2788
if (row && row[0] && row[1])
2790
/* SHOW MASTER STATUS reports file and position */
2792
fprintf(md_result_file,
2793
"\n--\n-- Position to start replication or point-in-time "
2794
"recovery from\n--\n\n");
2795
fprintf(md_result_file,
2796
"%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
2797
comment_prefix, row[0], row[1]);
2798
check_io(md_result_file);
2800
else if (!ignore_errors)
2802
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2803
my_printf_error(0, "Error: Binlogging on server not active",
2805
drizzle_free_result(master);
2806
maybe_exit(EX_DRIZZLEERR);
2809
drizzle_free_result(master);
2814
static int do_stop_slave_sql(DRIZZLE *drizzle_con)
2817
/* We need to check if the slave sql is running in the first place */
2818
if (drizzle_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2822
DRIZZLE_ROW row= drizzle_fetch_row(slave);
2825
/* if SLAVE SQL is not running, we don't stop it */
2826
if (!strcmp(row[11],"No"))
2828
drizzle_free_result(slave);
2829
/* Silently assume that they don't have the slave running */
2834
drizzle_free_result(slave);
2836
/* now, stop slave if running */
2837
if (drizzle_query_with_error_report(drizzle_con, 0, "STOP SLAVE SQL_THREAD"))
2843
static int add_stop_slave(void)
2846
fprintf(md_result_file,
2847
"\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
2848
fprintf(md_result_file, "STOP SLAVE;\n");
2852
static int add_slave_statements(void)
2855
fprintf(md_result_file,
2856
"\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
2857
fprintf(md_result_file, "START SLAVE;\n");
2861
static int do_show_slave_status(DRIZZLE *drizzle_con)
2864
const char *comment_prefix=
2865
(opt_slave_data == DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
2866
if (drizzle_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2870
/* SHOW SLAVE STATUS reports nothing and --force is not enabled */
2871
my_printf_error(0, "Error: Slave not set up", MYF(0));
2877
DRIZZLE_ROW row= drizzle_fetch_row(slave);
2878
if (row && row[9] && row[21])
2880
/* SHOW MASTER STATUS reports file and position */
2882
fprintf(md_result_file,
2883
"\n--\n-- Position to start replication or point-in-time "
2884
"recovery from (the master of this slave)\n--\n\n");
2886
fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
2888
if (opt_include_master_host_port)
2891
fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
2893
fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
2895
fprintf(md_result_file,
2896
"MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
2898
check_io(md_result_file);
2900
drizzle_free_result(slave);
2905
static int do_start_slave_sql(DRIZZLE *drizzle_con)
2908
/* We need to check if the slave sql is stopped in the first place */
2909
if (drizzle_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS"))
2913
DRIZZLE_ROW row= drizzle_fetch_row(slave);
2916
/* if SLAVE SQL is not running, we don't start it */
2917
if (!strcmp(row[11],"Yes"))
2919
drizzle_free_result(slave);
2920
/* Silently assume that they don't have the slave running */
2925
drizzle_free_result(slave);
2927
/* now, start slave if stopped */
2928
if (drizzle_query_with_error_report(drizzle_con, 0, "START SLAVE"))
2930
my_printf_error(0, "Error: Unable to start slave", MYF(0));
2938
static int do_flush_tables_read_lock(DRIZZLE *drizzle_con)
441
2941
We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
442
2942
will wait but will not stall the whole mysqld, and when the long update is
443
2943
done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
444
FLUSH TABLES is to lower the probability of a stage where both drizzled
2944
FLUSH TABLES is to lower the probability of a stage where both mysqldump
445
2945
and most client connections are stalled. Of course, if a second long
446
2946
update starts between the two FLUSHes, we have that bad stall.
449
db_connection->queryNoResult("FLUSH TABLES");
450
db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
455
static int do_unlock_tables()
457
db_connection->queryNoResult("UNLOCK TABLES");
461
static int start_transaction()
463
db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
464
db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
2949
( drizzle_query_with_error_report(drizzle_con, 0, "FLUSH TABLES") ||
2950
drizzle_query_with_error_report(drizzle_con, 0,
2951
"FLUSH TABLES WITH READ LOCK") );
2955
static int do_unlock_tables(DRIZZLE *drizzle_con)
2957
return drizzle_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES");
2960
static int get_bin_log_name(DRIZZLE *drizzle_con,
2961
char* buff_log_name, uint buff_len)
2966
if (drizzle_query(drizzle_con, "SHOW MASTER STATUS") ||
2967
!(res= drizzle_store_result(drizzle)))
2970
if (!(row= drizzle_fetch_row(res)))
2972
drizzle_free_result(res);
2976
Only one row is returned, and the first column is the name of the
2979
strmake(buff_log_name, row[0], buff_len - 1);
2981
drizzle_free_result(res);
2985
static int purge_bin_logs_to(DRIZZLE *drizzle_con, char* log_name)
2988
string str= "PURGE BINARY LOGS TO '";
2989
str.append(log_name);
2991
err = drizzle_query_with_error_report(drizzle_con, 0, str.c_str());
2996
static int start_transaction(DRIZZLE *drizzle_con)
2999
We use BEGIN for old servers. --single-transaction --master-data will fail
3000
on old servers, but that's ok as it was already silently broken (it didn't
3001
do a consistent read, so better tell people frankly, with the error).
3003
We want the first consistent read to be used for all tables to dump so we
3004
need the REPEATABLE READ level (not anything lower, for example READ
3005
COMMITTED would give one new consistent read per dumped table).
3007
if ((drizzle_get_server_version(drizzle_con) < 40100) && opt_master_data)
3009
fprintf(stderr, "-- %s: the combination of --single-transaction and "
3010
"--master-data requires a DRIZZLE server version of at least 4.1 "
3011
"(current server's version is %s). %s\n",
3012
ignore_errors ? "Warning" : "Error",
3013
drizzle_con->server_version ? drizzle_con->server_version : "unknown",
3014
ignore_errors ? "Continuing due to --force, backup may not be consistent across all tables!" : "Aborting.");
3016
exit(EX_DRIZZLEERR);
3019
return (drizzle_query_with_error_report(drizzle_con, 0,
3020
"SET SESSION TRANSACTION ISOLATION "
3021
"LEVEL REPEATABLE READ") ||
3022
drizzle_query_with_error_report(drizzle_con, 0,
3023
"START TRANSACTION "
3024
"/*!40100 WITH CONSISTENT SNAPSHOT */"));
3028
static uint32_t find_set(TYPELIB *lib, const char *x, uint length,
3029
char **err_pos, uint *err_len)
3031
const char *end= x + length;
3036
*err_pos= 0; /* No error yet */
3037
while (end > x && my_isspace(charset_info, end[-1]))
3043
const char *start= x;
3046
const char *pos= start;
3049
for (; pos != end && *pos != ','; pos++) ;
3050
var_len= (uint32_t) (pos - start);
3051
strmake(buff, start, min((uint32_t)sizeof(buff), var_len));
3052
find= find_type(buff, lib, var_len);
3055
*err_pos= (char*) start;
3059
found|= ((int64_t) 1 << (find - 1));
3069
/* Print a value with a prefix on file */
3070
static void print_value(FILE *file, DRIZZLE_RES *result, DRIZZLE_ROW row,
3071
const char *prefix, const char *name,
3074
DRIZZLE_FIELD *field;
3075
drizzle_field_seek(result, 0);
3077
for ( ; (field= drizzle_fetch_field(result)) ; row++)
3079
if (!strcmp(field->name,name))
3081
if (row[0] && row[0][0] && strcmp(row[0],"0")) /* Skip default */
3084
fputs(prefix, file);
3086
unescape(file,row[0],(uint) strlen(row[0]));
3088
fputs(row[0], file);
3094
return; /* This shouldn't happen */
3101
Check if we the table is one of the table types that should be ignored:
3102
MRG_ISAM, MRG_MYISAM, if opt_delayed, if that table supports delayed inserts.
3103
If the table should be altogether ignored, it returns a true, false if it
3104
should not be ignored. If the user has selected to use INSERT DELAYED, it
3105
sets the value of the bool pointer supports_delayed_inserts to 0 if not
3106
supported, 1 if it is supported.
3110
check_if_ignore_table()
3111
table_name Table name to check
3112
table_type Type of table
3115
drizzle Drizzle connection
3116
verbose Write warning messages
3119
char (bit value) See IGNORE_ values at top
3122
char check_if_ignore_table(const char *table_name, char *table_type)
3124
char result= IGNORE_NONE;
3125
char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
3126
DRIZZLE_RES *res= NULL;
3130
/* Check memory for quote_for_like() */
3131
assert(2*sizeof(table_name) < sizeof(show_name_buff));
3132
snprintf(buff, sizeof(buff), "show table status like %s",
3133
quote_for_like(table_name, show_name_buff));
3134
if (drizzle_query_with_error_report(drizzle, &res, buff))
3136
if (drizzle_errno(drizzle) != ER_PARSE_ERROR)
3137
{ /* If old DRIZZLE version */
3138
verbose_msg("-- Warning: Couldn't get status information for "
3139
"table %s (%s)\n", table_name, drizzle_error(drizzle));
3140
return(result); /* assume table is ok */
3143
if (!(row= drizzle_fetch_row(res)))
3146
"Error: Couldn't read status information for table %s (%s)\n",
3147
table_name, drizzle_error(drizzle));
3148
drizzle_free_result(res);
3149
return(result); /* assume table is ok */
3152
strmake(table_type, "VIEW", NAME_LEN-1);
3156
If the table type matches any of these, we do support delayed inserts.
3157
Note: we do not want to skip dumping this table if if is not one of
3158
these types, but we do want to use delayed inserts in the dump if
3159
the table type is _NOT_ one of these types
3161
strmake(table_type, row[1], NAME_LEN-1);
3164
if (strcmp(table_type,"MyISAM") &&
3165
strcmp(table_type,"ISAM") &&
3166
strcmp(table_type,"ARCHIVE") &&
3167
strcmp(table_type,"HEAP") &&
3168
strcmp(table_type,"MEMORY"))
3169
result= IGNORE_INSERT_DELAYED;
3173
If these two types, we do want to skip dumping the table
3176
(!my_strcasecmp(&my_charset_utf8_general_ci, table_type, "MRG_MyISAM") ||
3177
!strcmp(table_type,"MRG_ISAM")))
3178
result= IGNORE_DATA;
3180
drizzle_free_result(res);
3186
Get string of comma-separated primary key field names
3189
char *primary_key_fields(const char *table_name)
3190
RETURNS pointer to allocated buffer (must be freed by caller)
3191
table_name quoted table name
3194
Use SHOW KEYS FROM table_name, allocate a buffer to hold the
3195
field names, and then build that string and return the pointer
3198
Returns NULL if there is no PRIMARY or UNIQUE key on the table,
3199
or if there is some failure. It is better to continue to dump
3200
the table unsorted, rather than exit without dumping the data.
3203
static char *primary_key_fields(const char *table_name)
3205
DRIZZLE_RES *res= NULL;
3207
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
3208
char show_keys_buff[15 + NAME_LEN * 2 + 3];
3209
uint result_length= 0;
3211
char buff[NAME_LEN * 2 + 3];
3214
snprintf(show_keys_buff, sizeof(show_keys_buff),
3215
"SHOW KEYS FROM %s", table_name);
3216
if (drizzle_query(drizzle, show_keys_buff) ||
3217
!(res= drizzle_store_result(drizzle)))
3219
fprintf(stderr, "Warning: Couldn't read keys from table %s;"
3220
" records are NOT sorted (%s)\n",
3221
table_name, drizzle_error(drizzle));
3222
/* Don't exit, because it's better to print out unsorted records */
3227
* Figure out the length of the ORDER BY clause result.
3228
* Note that SHOW KEYS is ordered: a PRIMARY key is always the first
3229
* row, and UNIQUE keys come before others. So we only need to check
3230
* the first key, not all keys.
3232
if ((row= drizzle_fetch_row(res)) && atoi(row[1]) == 0)
3237
quoted_field= quote_name(row[4], buff, 0);
3238
result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */
3239
} while ((row= drizzle_fetch_row(res)) && atoi(row[3]) > 1);
3242
/* Build the ORDER BY clause result */
3246
/* result (terminating \0 is already in result_length) */
3247
result= (char *)my_malloc(result_length + 10, MYF(MY_WME));
3250
fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
3253
drizzle_data_seek(res, 0);
3254
row= drizzle_fetch_row(res);
3255
quoted_field= quote_name(row[4], buff, 0);
3256
end= my_stpcpy(result, quoted_field);
3257
while ((row= drizzle_fetch_row(res)) && atoi(row[3]) > 1)
3259
quoted_field= quote_name(row[4], buff, 0);
3260
end= strxmov(end, ",", quoted_field, NULL);
3266
drizzle_free_result(res);
468
3272
int main(int argc, char **argv)
3274
char bin_log_name[FN_REFLEN];
474
#if defined(ENABLE_NLS)
475
# if defined(HAVE_LOCALE_H)
476
setlocale(LC_ALL, "");
478
bindtextdomain("drizzle7", LOCALEDIR);
479
textdomain("drizzle7");
482
po::options_description commandline_options(_("Options used only in command line"));
483
commandline_options.add_options()
484
("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
485
_("Dump all the databases. This will be same as --databases with all databases selected."))
486
("all-tablespaces,Y", po::value<bool>(&opt_alltspcs)->default_value(false)->zero_tokens(),
487
_("Dump all the tablespaces."))
488
("complete-insert,c", po::value<bool>(&opt_complete_insert)->default_value(false)->zero_tokens(),
489
_("Use complete insert statements."))
490
("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
491
_("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"))
492
("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
493
_("Continue even if we get an sql-error."))
494
("help,?", _("Display this help message and exit."))
495
("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
496
_("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."))
497
("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
498
_("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."))
500
_("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, ---extended-insert and --disable-keys."))
501
("tables", _("Overrides option --databases (-B)."))
502
("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
503
_("Number of rows before each output progress report (requires --verbose)."))
504
("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
505
_("Print info about the various stages."))
506
("version,V", _("Output version information and exit."))
507
("skip-comments", _("Turn off Comments"))
508
("skip-create", _("Turn off create-options"))
509
("skip-extended-insert", _("Turn off extended-insert"))
510
("skip-dump-date", _( "Turn off dump date at the end of the output"))
511
("no-defaults", _("Do not read from the configuration files"))
514
po::options_description dump_options(_("Options specific to the drizzle client"));
515
dump_options.add_options()
516
("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
517
_("Add a 'DROP DATABASE' before each create."))
518
("skip-drop-table", _("Do not add a 'drop table' before each create."))
519
("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
520
_("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"))
521
("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
522
_("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."))
523
("skip-disable-keys,K",
524
_("'ALTER TABLE tb_name DISABLE KEYS;' and 'ALTER TABLE tb_name ENABLE KEYS;' will not be put in the output."))
525
("ignore-table", po::value<string>(),
526
_("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"))
527
("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
528
_("Insert rows with INSERT IGNORE."))
529
("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
530
_("Wrap a table's data in START TRANSACTION/COMMIT statements."))
531
("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
532
_("'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."))
533
("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
534
_("No row information."))
535
("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
536
_("Use REPLACE INTO instead of INSERT INTO."))
537
("destination-type", po::value<string>()->default_value("stdout"),
538
_("Where to send output to (stdout|database"))
539
("destination-host", po::value<string>(&opt_destination_host)->default_value("localhost"),
540
_("Hostname for destination db server (requires --destination-type=database)"))
541
("destination-port", po::value<uint16_t>(&opt_destination_port)->default_value(4427),
542
_("Port number for destination db server (requires --destination-type=database)"))
543
("destination-user", po::value<string>(&opt_destination_user),
544
_("User name for destination db server (resquires --destination-type=database)"))
545
("destination-password", po::value<string>(&opt_destination_password),
546
_("Password for destination db server (requires --destination-type=database)"))
547
("destination-database", po::value<string>(&opt_destination_database),
548
_("The database in the destination db server (requires --destination-type=database, not for use with --all-databases)"))
549
("my-data-is-mangled", po::value<bool>(&opt_data_is_mangled)->default_value(false)->zero_tokens(),
550
_("Do not make a UTF8 connection to MySQL, use if you have UTF8 data in a non-UTF8 table"))
553
po::options_description client_options(_("Options specific to the client"));
554
client_options.add_options()
555
("host,h", po::value<string>(¤t_host)->default_value("localhost"),
556
_("Connect to host."))
557
("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
558
_("Password to use when connecting to server. If password is not given it's solicited on the tty."))
559
("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
560
_("Port number to use for connection."))
561
("user,u", po::value<string>(¤t_user)->default_value(""),
562
_("User for login if not current user."))
563
("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
564
_("The protocol of connection (mysql or drizzle)."))
567
po::options_description hidden_options(_("Hidden Options"));
568
hidden_options.add_options()
569
("database-used", po::value<vector<string> >(), _("Used to select the database"))
570
("Table-used", po::value<vector<string> >(), _("Used to select the tables"))
573
po::options_description all_options(_("Allowed Options + Hidden Options"));
574
all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
576
po::options_description long_options(_("Allowed Options"));
577
long_options.add(commandline_options).add(dump_options).add(client_options);
579
std::string system_config_dir_dump(SYSCONFDIR);
580
system_config_dir_dump.append("/drizzle/drizzledump.cnf");
582
std::string system_config_dir_client(SYSCONFDIR);
583
system_config_dir_client.append("/drizzle/client.cnf");
585
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
587
if (user_config_dir.compare(0, 2, "~/") == 0)
590
homedir= getenv("HOME");
592
user_config_dir.replace(0, 1, homedir);
595
po::positional_options_description p;
596
p.add("database-used", 1);
597
p.add("Table-used",-1);
599
md_result_file= stdout;
601
po::variables_map vm;
603
// Disable allow_guessing
604
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
606
po::store(po::command_line_parser(argc, argv).style(style).
607
options(all_options).positional(p).
608
extra_parser(parse_password_arg).run(), vm);
610
if (! vm.count("no-defaults"))
612
std::string user_config_dir_dump(user_config_dir);
613
user_config_dir_dump.append("/drizzle/drizzledump.cnf");
615
std::string user_config_dir_client(user_config_dir);
616
user_config_dir_client.append("/drizzle/client.cnf");
618
ifstream user_dump_ifs(user_config_dir_dump.c_str());
619
po::store(parse_config_file(user_dump_ifs, dump_options), vm);
621
ifstream user_client_ifs(user_config_dir_client.c_str());
622
po::store(parse_config_file(user_client_ifs, client_options), vm);
624
ifstream system_dump_ifs(system_config_dir_dump.c_str());
625
po::store(parse_config_file(system_dump_ifs, dump_options), vm);
627
ifstream system_client_ifs(system_config_dir_client.c_str());
628
po::store(parse_config_file(system_client_ifs, client_options), vm);
633
if ((not vm.count("database-used") && not vm.count("Table-used")
634
&& not opt_alldbs && path.empty())
635
|| (vm.count("help")) || vm.count("version"))
637
printf(_("Drizzledump %s build %s, for %s-%s (%s)\n"),
638
drizzle_version(), VERSION, HOST_VENDOR, HOST_OS, HOST_CPU);
639
if (vm.count("version"))
642
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"));
643
puts(_("Dumps definitions and data from a Drizzle database server"));
644
printf(_("Usage: %s [OPTIONS] database [tables]\n"), progname.c_str());
645
printf(_("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
647
printf(_("OR %s [OPTIONS] --all-databases [OPTIONS]\n"), progname.c_str());
648
cout << long_options;
649
if (vm.count("help"))
655
/* Inverted Booleans */
657
opt_drop= (vm.count("skip-drop-table")) ? false : true;
658
opt_comments= (vm.count("skip-comments")) ? false : true;
659
extended_insert= (vm.count("skip-extended-insert")) ? false : true;
660
opt_dump_date= (vm.count("skip-dump-date")) ? false : true;
661
opt_disable_keys= (vm.count("skip-disable-keys")) ? false : true;
662
opt_quoted= (vm.count("skip-quote-names")) ? false : true;
664
if (vm.count("protocol"))
666
std::transform(opt_protocol.begin(), opt_protocol.end(),
667
opt_protocol.begin(), ::tolower);
669
if (not opt_protocol.compare("mysql"))
670
use_drizzle_protocol=false;
671
else if (not opt_protocol.compare("drizzle"))
672
use_drizzle_protocol=true;
675
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
680
if (vm.count("port"))
682
/* If the port number is > 65535 it is not a valid port
683
* This also helps with potential data loss casting unsigned long to a
686
if (opt_drizzle_port > 65535)
688
fprintf(stderr, _("Value supplied for port is not valid.\n"));
693
if(vm.count("password"))
695
if (!opt_password.empty())
696
opt_password.erase();
697
if (password == PASSWORD_SENTINEL)
703
opt_password= password;
717
if (vm.count("skip-opt"))
719
extended_insert= opt_drop= create_options= 0;
725
opt_comments= opt_drop= opt_disable_keys= 0;
730
extended_insert= opt_drop= create_options= 1;
734
if (vm.count("tables"))
736
opt_databases= false;
739
if (vm.count("ignore-table"))
741
if (!strchr(vm["ignore-table"].as<string>().c_str(), '.'))
743
fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
744
exit(EXIT_ARGUMENT_INVALID);
746
string tmpptr(vm["ignore-table"].as<string>());
747
ignore_table.insert(tmpptr);
750
if (vm.count("skip-create"))
752
opt_create_db= opt_no_create_info= create_options= false;
755
exit_code= get_options();
3276
MY_INIT("mysqldump");
3278
compatible_mode_normal_str[0]= 0;
3279
default_charset= (char *)drizzle_universal_client_charset;
3280
memset(&ignore_table, 0, sizeof(ignore_table));
3282
exit_code= get_options(&argc, &argv);
758
3285
free_resources();
759
3286
exit(exit_code);
763
db_connection = new DrizzleDumpConnection(current_host, opt_drizzle_port,
764
current_user, opt_password, use_drizzle_protocol);
766
catch (std::exception&)
768
maybe_exit(EX_DRIZZLEERR);
771
if ((db_connection->getServerType() == DrizzleDumpConnection::SERVER_MYSQL_FOUND) and (not opt_data_is_mangled))
772
db_connection->queryNoResult("SET NAMES 'utf8'");
774
if (vm.count("destination-type"))
776
string tmp_destination(vm["destination-type"].as<string>());
777
if (tmp_destination.compare("database") == 0)
778
opt_destination= DESTINATION_DB;
779
else if (tmp_destination.compare("stdout") == 0)
780
opt_destination= DESTINATION_STDOUT;
782
exit(EXIT_ARGUMENT_INVALID);
786
if (path.empty() && vm.count("database-used"))
788
string database_used= *vm["database-used"].as< vector<string> >().begin();
789
write_header((char *)database_used.c_str());
792
if ((opt_lock_all_tables) && do_flush_tables_read_lock())
794
if (opt_single_transaction && start_transaction())
796
if (opt_lock_all_tables)
797
db_connection->queryNoResult("FLUSH LOGS");
798
if (opt_single_transaction && do_unlock_tables()) /* unlock but no commit! */
3291
if(!(stderror_file= freopen(log_error_file, "a+", stderr)))
3294
exit(EX_DRIZZLEERR);
3298
if (connect_to_db(current_host, current_user, opt_password))
3301
exit(EX_DRIZZLEERR);
3304
write_header(md_result_file, *argv);
3306
if (opt_slave_data && do_stop_slave_sql(drizzle))
3309
if ((opt_lock_all_tables || opt_master_data) &&
3310
do_flush_tables_read_lock(drizzle))
3312
if (opt_single_transaction && start_transaction(drizzle))
3314
if (opt_delete_master_logs)
3316
if (drizzle_refresh(drizzle, REFRESH_LOG) ||
3317
get_bin_log_name(drizzle, bin_log_name, sizeof(bin_log_name)))
3321
if (opt_lock_all_tables || opt_master_data)
3323
if (flush_logs && drizzle_refresh(drizzle, REFRESH_LOG))
3325
flush_logs= 0; /* not anymore; that would not be sensible */
3327
/* Add 'STOP SLAVE to beginning of dump */
3328
if (opt_slave_apply && add_stop_slave())
3330
if (opt_master_data && do_show_master_status(drizzle))
3332
if (opt_slave_data && do_show_slave_status(drizzle))
3334
if (opt_single_transaction && do_unlock_tables(drizzle)) /* unlock but no commit! */
803
3339
dump_all_databases();
806
if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
3341
else if (argc > 1 && !opt_databases)
808
string database_used= *vm["database-used"].as< vector<string> >().begin();
809
3343
/* Only one database and selected table(s) */
810
dump_selected_tables(database_used, vm["Table-used"].as< vector<string> >());
813
if (vm.count("Table-used") and opt_databases)
815
vector<string> database_used= vm["database-used"].as< vector<string> >();
816
vector<string> table_used= vm["Table-used"].as< vector<string> >();
818
for (vector<string>::iterator it= table_used.begin();
819
it != table_used.end();
822
database_used.insert(database_used.end(), *it);
825
dump_databases(database_used);
829
if (vm.count("database-used") && ! vm.count("Table-used"))
831
dump_databases(vm["database-used"].as< vector<string> >());
835
if (opt_destination == DESTINATION_STDOUT)
3344
dump_selected_tables(*argv, (argv + 1), (argc - 1));
3348
dump_databases(argv);
3351
/* if --dump-slave , start the slave sql thread */
3352
if (opt_slave_data && do_start_slave_sql(drizzle))
3355
/* add 'START SLAVE' to end of dump */
3356
if (opt_slave_apply && add_slave_statements())
840
3359
/* ensure dumped data flushed */
841
3360
if (md_result_file && fflush(md_result_file))