~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzledump.cc

  • Committer: Brian Aker
  • Date: 2010-08-18 16:12:58 UTC
  • mto: This revision was merged to the branch mainline in revision 1720.
  • Revision ID: brian@tangent.org-20100818161258-1vm71da888dfvwsx
Remove the code surrounding stack trace.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
#include "client_priv.h"
33
33
#include <string>
34
 
 
 
34
#include <iostream>
35
35
#include "drizzled/internal/my_sys.h"
36
36
#include "drizzled/internal/m_string.h"
37
37
#include "drizzled/charset_info.h"
38
 
#include "drizzled/hash.h"
39
38
#include <stdarg.h>
 
39
#include <boost/unordered_set.hpp>
40
40
#include <algorithm>
41
 
 
 
41
#include <fstream>
42
42
#include <drizzled/gettext.h>
43
 
 
 
43
#include <drizzled/configmake.h>
44
44
#include <drizzled/error.h>
 
45
#include <boost/program_options.hpp>
45
46
 
46
47
using namespace std;
47
48
using namespace drizzled;
 
49
namespace po= boost::program_options;
48
50
 
49
51
/* Exit codes */
50
52
 
74
76
#define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
75
77
 
76
78
static void add_load_option(string &str, const char *option,
77
 
                            const char *option_value);
 
79
                            const string &option_value);
78
80
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
79
81
                         char **err_pos, uint32_t *err_len);
80
82
 
81
 
static void field_escape(string &in, const char *from);
 
83
static void field_escape(string &in, const string &from);
82
84
static bool  verbose= false;
83
 
static bool opt_no_create_info= false;
 
85
static bool opt_no_create_info;
84
86
static bool opt_no_data= false;
85
87
static bool opt_mysql= false;
86
88
static bool quick= true;
101
103
static bool opt_dump_date= true;
102
104
static bool opt_autocommit= false; 
103
105
static bool opt_disable_keys= true;
104
 
static bool opt_xml= false;
105
 
static bool tty_password= false;
 
106
static bool opt_xml;
106
107
static bool opt_single_transaction= false; 
107
 
static bool opt_comments= false;
108
 
static bool opt_compact= false;
 
108
static bool opt_comments;
 
109
static bool opt_compact;
109
110
static bool opt_hex_blob= false;
110
111
static bool opt_order_by_primary=false; 
111
112
static bool opt_ignore= false;
112
113
static bool opt_complete_insert= false;
113
 
static bool opt_drop_database= false;
 
114
static bool opt_drop_database;
114
115
static bool opt_replace_into= false;
115
116
static bool opt_routines= false;
116
117
static bool opt_alltspcs= false;
119
120
static drizzle_st drizzle;
120
121
static drizzle_con_st dcon;
121
122
static string insert_pat;
122
 
static char  *opt_password= NULL;
123
 
static char *current_user= NULL;
124
 
static char  *current_host= NULL;
125
 
static char *path= NULL;
126
 
static char *fields_terminated= NULL;
127
 
static char *lines_terminated= NULL; 
128
 
static char *enclosed= NULL;
129
 
static char *opt_enclosed= NULL;
130
 
static char *escaped= NULL;
131
 
static char *where= NULL; 
132
123
static char *order_by= NULL;
133
 
static char *opt_compatible_mode_str= NULL;
134
124
static char *err_ptr= NULL;
135
 
static char **defaults_argv= NULL;
136
125
static char compatible_mode_normal_str[255];
137
126
static uint32_t opt_compatible_mode= 0;
138
127
static uint32_t opt_drizzle_port= 0;
141
130
FILE *md_result_file= 0;
142
131
FILE *stderror_file= 0;
143
132
 
 
133
string password,
 
134
  opt_compatible_mode_str,
 
135
  enclosed,
 
136
  escaped,
 
137
  current_host,
 
138
  opt_enclosed,
 
139
  fields_terminated,
 
140
  path,
 
141
  lines_terminated,
 
142
  current_user,
 
143
  opt_password,
 
144
  where;
 
145
 
144
146
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
145
147
 
146
148
static const char *compatible_mode_names[]=
153
155
static TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
154
156
  "", compatible_mode_names, NULL};
155
157
 
156
 
drizzled::hash_set<string> ignore_table;
157
 
 
158
 
static struct option my_long_options[] =
159
 
{
160
 
  {"all", 'a', "Deprecated. Use --create-options instead.",
161
 
    (char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
162
 
    0, 0, 0, 0, 0},
163
 
  {"all-databases", 'A',
164
 
    "Dump all the databases. This will be same as --databases with all databases selected.",
165
 
    (char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
166
 
    0, 0},
167
 
  {"all-tablespaces", 'Y',
168
 
    "Dump all the tablespaces.",
169
 
    (char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
170
 
    0, 0},
171
 
  {"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
172
 
    (char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
173
 
    0},
174
 
  {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
175
 
    (char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
176
 
    0},
177
 
  {"allow-keywords", OPT_KEYWORDS,
178
 
    "Allow creation of column names that are keywords.", (char**) &opt_keywords,
179
 
    (char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
180
 
  {"comments", 'i', "Write additional information.",
181
 
    (char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
182
 
    1, 0, 0, 0, 0, 0},
183
 
  {"compatible", OPT_COMPATIBLE,
184
 
    "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.",
185
 
    (char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
186
 
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
187
 
  {"compact", OPT_COMPACT,
188
 
    "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",
189
 
    (char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
190
 
    0, 0},
191
 
  {"complete-insert", 'c', "Use complete insert statements.",
192
 
    (char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
193
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
194
 
  {"compress", 'C', "Use compression in server/client protocol.",
195
 
    (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
196
 
    0, 0, 0},
197
 
  {"create-options", OPT_CREATE_OPTIONS,
198
 
    "Include all DRIZZLE specific create options.",
199
 
    (char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
200
 
    0, 0, 0, 0, 0},
201
 
  {"databases", 'B',
202
 
    "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.",
203
 
    (char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
204
 
    0, 0, 0, 0},
205
 
  {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
206
 
    (char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
207
 
    0, 0},
208
 
  {"disable-keys", 'K',
209
 
    "'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.", (char**) &opt_disable_keys,
210
 
    (char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
211
 
  {"extended-insert", 'e',
212
 
    "Allows utilization of the new, much faster INSERT syntax.",
213
 
    (char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
214
 
    1, 0, 0, 0, 0, 0},
215
 
  {"fields-terminated-by", OPT_FTB,
216
 
    "Fields in the textfile are terminated by ...", (char**) &fields_terminated,
217
 
    (char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
218
 
  {"fields-enclosed-by", OPT_ENC,
219
 
    "Fields in the importfile are enclosed by ...", (char**) &enclosed,
220
 
    (char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
221
 
  {"fields-optionally-enclosed-by", OPT_O_ENC,
222
 
    "Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
223
 
    (char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
224
 
  {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
225
 
    (char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
226
 
  {"flush-logs", 'F', "Flush logs file in server before starting dump. "
227
 
    "Note that if you dump many databases at once (using the option "
228
 
      "--databases= or --all-databases), the logs will be flushed for "
229
 
      "each database dumped. The exception is when using --lock-all-tables "
230
 
      "in this case the logs will be flushed only once, corresponding "
231
 
      "to the moment all tables are locked. So if you want your dump and "
232
 
      "the log flush to happen at the same exact moment you should use "
233
 
      "--lock-all-tables or --flush-logs",
234
 
    (char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
235
 
    0, 0},
236
 
  {"force", 'f', "Continue even if we get an sql-error.",
237
 
    (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
238
 
    0, 0, 0, 0, 0, 0},
239
 
  {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
240
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
241
 
  {"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
242
 
    "VARBINARY, BLOB) in hexadecimal format.",
243
 
    (char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
244
 
  {"host", 'h', "Connect to host.", (char**) &current_host,
245
 
    (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
246
 
  {"ignore-table", OPT_IGNORE_TABLE,
247
 
    "Do not dump the specified table. To specify more than one table to ignore, "
248
 
      "use the directive multiple times, once for each table.  Each table must "
249
 
      "be specified with both database and table names, e.g. --ignore-table=database.table",
250
 
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
251
 
  {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
252
 
    (char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
253
 
    0, 0},
254
 
  {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
255
 
    (char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
256
 
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
257
 
  {"lock-all-tables", 'x', "Locks all tables across all databases. This "
258
 
    "is achieved by taking a global read lock for the duration of the whole "
259
 
      "dump. Automatically turns --single-transaction and --lock-tables off.",
260
 
    (char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
261
 
    0, 0, 0, 0, 0, 0},
262
 
  {"mysql", 'm', N_("Use MySQL Protocol."),
263
 
    (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
264
 
    0, 0, 0},
265
 
  {"no-autocommit", OPT_AUTOCOMMIT,
266
 
    "Wrap tables with autocommit/commit statements.",
267
 
    (char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
268
 
    0, 0, 0, 0, 0, 0},
269
 
  {"no-create-db", 'n',
270
 
    "'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.}.",
271
 
    (char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
272
 
    0, 0, 0, 0},
273
 
  {"no-create-info", 't', "Don't write table creation info.",
274
 
    (char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
275
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
276
 
  {"no-data", 'd', "No row information.", (char**) &opt_no_data,
277
 
    (char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
278
 
  {"no-set-names", 'N',
279
 
    "Deprecated. Use --skip-set-charset instead.",
280
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
281
 
  {"opt", OPT_OPTIMIZE,
282
 
    "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.",
283
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
284
 
  {"order-by-primary", OPT_ORDER_BY_PRIMARY,
285
 
    "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.",
286
 
    (char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
287
 
  {"password", 'P',
288
 
    "Password to use when connecting to server. If password is not given it's solicited on the tty.",
289
 
    0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
290
 
  {"port", 'p', "Port number to use for connection.", 
291
 
    0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
292
 
  {"quick", 'q', "Don't buffer query, dump directly to stdout.",
293
 
    (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
294
 
  {"quote-names",'Q', "Quote table and column names with backticks (`).",
295
 
    (char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
296
 
    0, 0},
297
 
  {"replace", OPT_DRIZZLE_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
298
 
    (char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
299
 
    0, 0},
300
 
  {"result-file", 'r',
301
 
    "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).",
302
 
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
303
 
  {"routines", 'R', "Dump stored routines (functions and procedures).",
304
 
    (char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
305
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
306
 
  {"single-transaction", OPT_TRANSACTION,
307
 
    "Creates a consistent snapshot by dumping all tables in a single "
308
 
      "transaction. Works ONLY for tables stored in storage engines which "
309
 
      "support multiversioning (currently only InnoDB does); the dump is NOT "
310
 
      "guaranteed to be consistent for other storage engines. "
311
 
      "While a --single-transaction dump is in process, to ensure a valid "
312
 
      "dump file (correct table contents), no other "
313
 
      "connection should use the following statements: ALTER TABLE, DROP "
314
 
      "TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
315
 
      "isolated from them. Option automatically turns off --lock-tables.",
316
 
    (char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
317
 
    GET_BOOL, NO_ARG,  0, 0, 0, 0, 0, 0},
318
 
  {"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
319
 
    (char**) &opt_dump_date, (char**) &opt_dump_date, 0,
320
 
    GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
321
 
  {"skip-opt", OPT_SKIP_OPTIMIZATION,
322
 
    "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
323
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
324
 
  {"tab",'T',
325
 
    "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if drizzledump is run on the same machine as the drizzled daemon.",
326
 
    (char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
327
 
  {"tables", OPT_TABLES, "Overrides option --databases (-B).",
328
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
329
 
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of rows before each output progress report (requires --verbose)."),
330
 
    (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
331
 
    10000, 0, 0, 0, 0, 0},
332
 
  {"user", 'u', "User for login if not current user.",
333
 
    (char**) &current_user, (char**) &current_user, 0, GET_STR, REQUIRED_ARG,
334
 
    0, 0, 0, 0, 0, 0},
335
 
  {"verbose", 'v', "Print info about the various stages.",
336
 
    (char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
337
 
  {"version",'V', "Output version information and exit.", 0, 0, 0,
338
 
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
339
 
  {"where", 'w', "Dump only selected records; QUOTES mandatory!",
340
 
    (char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
341
 
  {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
342
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
343
 
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
344
 
};
345
 
 
346
 
static const char *load_default_groups[]= { "drizzledump","client",0 };
 
158
boost::unordered_set<string> ignore_table;
347
159
 
348
160
static void maybe_exit(int error);
349
161
static void die(int error, const char* reason, ...);
354
166
                        int string_value);
355
167
static const char* fetch_named_row(drizzle_result_st *result, drizzle_row_t row,
356
168
                                   const char* name);
357
 
static int dump_selected_tables(char *db, char **table_names, int tables);
 
169
static int dump_selected_tables(const string &db, const vector<string> &table_names);
358
170
static int dump_all_tables_in_db(char *db);
359
171
static int init_dumping_tables(char *);
360
172
static int init_dumping(char *, int init_func(char*));
361
 
static int dump_databases(char **);
 
173
static int dump_databases(const vector<string> &db_names);
362
174
static int dump_all_databases(void);
363
175
static char *quote_name(const char *name, char *buff, bool force);
364
176
char check_if_ignore_table(const char *table_name, char *table_type);
372
184
  fmt   format specifier
373
185
  ...   variable number of parameters
374
186
*/
 
187
 
375
188
static void verbose_msg(const char *fmt, ...)
376
189
{
377
190
  va_list args;
399
212
    die(EX_EOF, _("Got errno %d on write"), errno);
400
213
}
401
214
 
402
 
static void print_version(void)
403
 
{
404
 
  printf(_("%s  Drizzle %s libdrizzle %s, for %s-%s (%s)\n"), internal::my_progname,
405
 
         VERSION, drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
406
 
} /* print_version */
407
 
 
408
 
 
409
 
static void short_usage_sub(void)
410
 
{
411
 
  printf(_("Usage: %s [OPTIONS] database [tables]\n"), internal::my_progname);
412
 
  printf(_("OR     %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
413
 
         internal::my_progname);
414
 
  printf(_("OR     %s [OPTIONS] --all-databases [OPTIONS]\n"), internal::my_progname);
415
 
}
416
 
 
417
 
 
418
 
static void usage(void)
419
 
{
420
 
  print_version();
421
 
  puts("");
422
 
  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"));
423
 
  puts(_("Dumps definitions and data from a Drizzle database server"));
424
 
  short_usage_sub();
425
 
  internal::print_defaults("drizzle",load_default_groups);
426
 
  my_print_help(my_long_options);
427
 
  my_print_variables(my_long_options);
428
 
} /* usage */
429
 
 
430
 
 
431
 
static void short_usage(void)
432
 
{
433
 
  short_usage_sub();
434
 
  printf(_("For more options, use %s --help\n"), internal::my_progname);
435
 
}
436
 
 
437
215
static void write_header(FILE *sql_file, char *db_name)
438
216
{
439
217
  if (opt_xml)
449
227
    fputs(">\n", sql_file);
450
228
    check_io(sql_file);
451
229
  }
452
 
  else if (!opt_compact)
453
 
  {
 
230
  else if (! opt_compact)
 
231
  { 
454
232
    if (opt_comments)
455
233
    {
456
234
      fprintf(sql_file,
457
235
              "-- drizzledump %s libdrizzle %s, for %s-%s (%s)\n--\n",
458
236
              VERSION, drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
459
237
      fprintf(sql_file, "-- Host: %s    Database: %s\n",
460
 
              current_host ? current_host : "localhost", db_name ? db_name :
 
238
              ! current_host.empty() ? current_host.c_str() : "localhost", db_name ? db_name :
461
239
              "");
462
240
      fputs("-- ------------------------------------------------------\n",
463
241
            sql_file);
468
246
      fprintf(sql_file,
469
247
              "\nSET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;\n");
470
248
 
471
 
    if (path == NULL)
 
249
    if (path.empty())
472
250
    {
473
251
      fprintf(md_result_file,"SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;\nSET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;\n");
474
252
    }
484
262
    fputs("</drizzledump>\n", sql_file);
485
263
    check_io(sql_file);
486
264
  }
487
 
  else if (opt_compact == false)
 
265
  else if (! opt_compact)
488
266
  {
489
 
    if (path == NULL)
 
267
    if (path.empty())
490
268
    {
491
269
      fprintf(md_result_file,"SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;\nSET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;\n");
492
270
    }
508
286
  }
509
287
} /* write_footer */
510
288
 
511
 
 
512
 
static int get_one_option(int optid, const struct option *, char *argument)
513
 
{
514
 
  char *endchar= NULL;
515
 
  uint64_t temp_drizzle_port= 0;
516
 
 
517
 
  switch (optid) {
518
 
  case 'p':
519
 
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
520
 
    /* if there is an alpha character this is not a valid port */
521
 
    if (strlen(endchar) != 0)
522
 
    {
523
 
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
524
 
      return EXIT_ARGUMENT_INVALID;
525
 
    }
526
 
    /* If the port number is > 65535 it is not a valid port
527
 
     *        This also helps with potential data loss casting unsigned long to a
528
 
     *               uint32_t. */
529
 
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
530
 
    {
531
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
532
 
      return EXIT_ARGUMENT_INVALID;
533
 
    }
534
 
    else
535
 
    {
536
 
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
537
 
    }
538
 
    break;
539
 
  case 'P':
540
 
    if (argument)
541
 
    {
542
 
      char *start= argument;
543
 
      if (opt_password)
544
 
        free(opt_password);
545
 
      opt_password= strdup(argument);
546
 
      if (opt_password == NULL)
547
 
      {
548
 
        fprintf(stderr, _("Memory allocation error while copying password. "
549
 
                          "Aborting.\n"));
550
 
        return EXIT_OUT_OF_MEMORY;
551
 
      }
552
 
      while (*argument)
553
 
      {
554
 
        /* Overwriting password with 'x' */
555
 
        *argument++= 'x';
556
 
      }
557
 
      if (*start)
558
 
      {
559
 
        /* Cut length of argument */
560
 
        start[1]= 0;
561
 
      }
562
 
      tty_password= 0;
563
 
    }
564
 
    else
565
 
    {
566
 
      tty_password= 1;
567
 
    }
568
 
    break;
569
 
  case 'r':
570
 
    if (!(md_result_file= fopen(argument, "w")))
571
 
      exit(1);
572
 
    break;
573
 
  case 'N':
574
 
    opt_set_charset= 0;
575
 
    break;
576
 
  case 'T':
577
 
    opt_disable_keys=0;
578
 
 
579
 
    if (strlen(argument) >= FN_REFLEN)
580
 
    {
581
 
      /*
582
 
        This check is made because the some the file functions below
583
 
        have FN_REFLEN sized stack allocated buffers and will cause
584
 
        a crash even if the input destination buffer is large enough
585
 
        to hold the output.
586
 
      */
587
 
      fprintf(stderr, _("Input filename too long: %s"), argument);
588
 
      return EXIT_ARGUMENT_INVALID;
589
 
    }
590
 
 
591
 
    break;
592
 
  case 'V': print_version(); exit(0);
593
 
  case 'X':
594
 
            opt_xml= 1;
595
 
            extended_insert= opt_drop=
596
 
              opt_disable_keys= opt_autocommit= opt_create_db= 0;
597
 
            break;
598
 
  case 'I':
599
 
  case '?':
600
 
            usage();
601
 
            exit(0);
602
 
  case (int) OPT_OPTIMIZE:
603
 
            extended_insert= opt_drop= quick= create_options=
604
 
              opt_disable_keys= opt_set_charset= 1;
605
 
            break;
606
 
  case (int) OPT_SKIP_OPTIMIZATION:
607
 
            extended_insert= opt_drop= quick= create_options=
608
 
              opt_disable_keys= opt_set_charset= 0;
609
 
            break;
610
 
  case (int) OPT_COMPACT:
611
 
            if (opt_compact)
612
 
            {
613
 
              opt_comments= opt_drop= opt_disable_keys= 0;
614
 
              opt_set_charset= 0;
615
 
            }
616
 
  case (int) OPT_TABLES:
617
 
            opt_databases=0;
618
 
            break;
619
 
  case (int) OPT_IGNORE_TABLE:
620
 
            {
621
 
              if (!strchr(argument, '.'))
622
 
              {
623
 
                fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
624
 
                return EXIT_ARGUMENT_INVALID;
625
 
              }
626
 
              string tmpptr(argument);
627
 
              ignore_table.insert(tmpptr); 
628
 
              break;
629
 
            }
630
 
  case (int) OPT_COMPATIBLE:
631
 
            {
632
 
              char buff[255];
633
 
              char *end= compatible_mode_normal_str;
634
 
              uint32_t i;
635
 
              uint32_t mode;
636
 
              uint32_t error_len;
637
 
 
638
 
              opt_quoted= 1;
639
 
              opt_set_charset= 0;
640
 
              opt_compatible_mode_str= argument;
641
 
              opt_compatible_mode= find_set(&compatible_mode_typelib,
642
 
                                            argument, strlen(argument),
643
 
                                            &err_ptr, &error_len);
644
 
              if (error_len)
645
 
              {
646
 
                strncpy(buff, err_ptr, min((uint32_t)sizeof(buff), error_len+1));
647
 
                fprintf(stderr, _("Invalid mode to --compatible: %s\n"), buff);
648
 
                return EXIT_ARGUMENT_INVALID;
649
 
              }
650
 
              mode= opt_compatible_mode;
651
 
              for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
652
 
              {
653
 
                if (mode & 1)
654
 
                {
655
 
                  uint32_t len = strlen(compatible_mode_names[i]);
656
 
                  end= strcpy(end, compatible_mode_names[i]) + len;
657
 
                  end= strcpy(end, ",")+1;
658
 
                }
659
 
              }
660
 
              if (end!=compatible_mode_normal_str)
661
 
                end[-1]= 0;
662
 
            }
663
 
  }
664
 
  return 0;
665
 
}
666
 
 
667
 
static int get_options(int *argc, char ***argv)
668
 
{
669
 
  int ho_error;
670
 
 
671
 
  md_result_file= stdout;
672
 
  internal::load_defaults("drizzle",load_default_groups,argc,argv);
673
 
  defaults_argv= *argv;
674
 
 
675
 
  if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
676
 
    return(ho_error);
677
 
 
678
 
  if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
679
 
                fields_terminated))
 
289
static int get_options(void)
 
290
{
 
291
 
 
292
  if (path.empty() && (! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty() || ! lines_terminated.empty() ||
 
293
                ! fields_terminated.empty()))
680
294
  {
681
295
    fprintf(stderr,
682
296
            _("%s: You must use option --tab with --fields-...\n"), internal::my_progname);
689
303
                      "--lock-all-tables at the same time.\n"), internal::my_progname);
690
304
    return(EX_USAGE);
691
305
  }
692
 
  if (enclosed && opt_enclosed)
 
306
  if (! enclosed.empty() && ! opt_enclosed.empty())
693
307
  {
694
308
    fprintf(stderr, _("%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n"), internal::my_progname);
695
309
    return(EX_USAGE);
696
310
  }
697
 
  if ((opt_databases || opt_alldbs) && path)
 
311
  if ((opt_databases || opt_alldbs) && ! path.empty())
698
312
  {
699
313
    fprintf(stderr,
700
314
            _("%s: --databases or --all-databases can't be used with --tab.\n"),
701
315
            internal::my_progname);
702
316
    return(EX_USAGE);
703
317
  }
704
 
  if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
705
 
  {
706
 
    short_usage();
707
 
    return EX_USAGE;
708
 
  }
 
318
 
709
319
  if (tty_password)
710
320
    opt_password=client_get_tty_password(NULL);
711
321
  return(0);
868
478
{
869
479
  FILE* res;
870
480
  char filename[FN_REFLEN], tmp_path[FN_REFLEN];
871
 
  internal::convert_dirname(tmp_path,path,NULL);
 
481
  internal::convert_dirname(tmp_path,(char *)path.c_str(),NULL);
872
482
  res= fopen(internal::fn_format(filename, table, tmp_path, ".sql", 4), "w");
873
483
 
874
484
  return res;
879
489
{
880
490
  if (md_result_file && md_result_file != stdout)
881
491
    fclose(md_result_file);
882
 
  free(opt_password);
883
 
  if (defaults_argv)
884
 
    internal::free_defaults(defaults_argv);
 
492
  opt_password.erase();
885
493
  internal::my_end();
886
494
}
887
495
 
903
511
  db_connect -- connects to the host and selects DB.
904
512
*/
905
513
 
906
 
static int connect_to_db(char *host, char *user,char *passwd)
 
514
static int connect_to_db(string host, string user,string passwd)
907
515
{
908
516
  drizzle_return_t ret;
909
517
 
910
 
  verbose_msg(_("-- Connecting to %s...\n"), host ? host : "localhost");
 
518
  verbose_msg(_("-- Connecting to %s...\n"), ! host.empty() ? (char *)host.c_str() : "localhost");
911
519
  drizzle_create(&drizzle);
912
520
  drizzle_con_create(&drizzle, &dcon);
913
 
  drizzle_con_set_tcp(&dcon, host, opt_drizzle_port);
914
 
  drizzle_con_set_auth(&dcon, user, passwd);
 
521
  drizzle_con_set_tcp(&dcon, (char *)host.c_str(), opt_drizzle_port);
 
522
  drizzle_con_set_auth(&dcon, (char *)user.c_str(), (char *)passwd.c_str());
915
523
  if (opt_mysql)
916
524
    drizzle_con_add_options(&dcon, DRIZZLE_CON_MYSQL);
917
525
  ret= drizzle_con_connect(&dcon);
928
536
/*
929
537
 ** dbDisconnect -- disconnects from the host.
930
538
*/
931
 
static void dbDisconnect(char *host)
 
539
static void dbDisconnect(string &host)
932
540
{
933
 
  verbose_msg(_("-- Disconnecting from %s...\n"), host ? host : "localhost");
 
541
  verbose_msg(_("-- Disconnecting from %s...\n"), ! host.empty() ? host.c_str() : "localhost");
934
542
  drizzle_con_free(&dcon);
935
543
  drizzle_free(&drizzle);
936
544
} /* dbDisconnect */
1310
918
    order_by= primary_key_fields(result_table);
1311
919
  }
1312
920
 
1313
 
  if (!opt_xml)
1314
 
  {
 
921
  if (! opt_xml)
 
922
  { 
1315
923
    /* using SHOW CREATE statement */
1316
 
    if (!opt_no_create_info)
1317
 
    {
 
924
    if (! opt_no_create_info)
 
925
    { 
1318
926
      /* Make an sql-file, if path was given iow. option -T was given */
1319
927
      char buff[20+FN_REFLEN];
1320
928
      const drizzle_column_st *column;
1324
932
      if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1325
933
        return false;
1326
934
 
1327
 
      if (path)
 
935
      if (! path.empty())
1328
936
      {
1329
937
        if (!(sql_file= open_sql_file_for_table(table)))
1330
938
        {
1341
949
        check_io(sql_file);
1342
950
      }
1343
951
      if (opt_drop)
1344
 
      {
 
952
      { 
1345
953
        /*
1346
954
          Even if the "table" is a view, we do a DROP TABLE here.
1347
955
        */
1364
972
 
1365
973
    if (drizzleclient_query_with_error_report(&dcon, &result, query_buff, false))
1366
974
    {
1367
 
      if (path)
 
975
      if (! path.empty())
1368
976
        fclose(sql_file);
1369
977
      return false;
1370
978
    }
1422
1030
      return false;
1423
1031
 
1424
1032
    /* Make an sql-file, if path was given iow. option -T was given */
1425
 
    if (!opt_no_create_info)
 
1033
    if (! opt_no_create_info)
1426
1034
    {
1427
 
      if (path)
 
1035
      if (! path.empty())
1428
1036
      {
1429
1037
        if (!(sql_file= open_sql_file_for_table(table)))
1430
1038
        {
1522
1130
      {
1523
1131
        fprintf(stderr, _("%s: Can't get keys for table %s\n"),
1524
1132
                internal::my_progname, result_table);
1525
 
        if (path)
 
1133
        if (! path.empty())
1526
1134
          fclose(sql_file);
1527
1135
        return false;
1528
1136
      }
1641
1249
} /* get_table_structure */
1642
1250
 
1643
1251
static void add_load_option(string &str, const char *option,
1644
 
                            const char *option_value)
 
1252
                            const string &option_value)
1645
1253
{
1646
 
  if (!option_value)
 
1254
  if (option_value.empty())
1647
1255
  {
1648
1256
    /* Null value means we don't add this option. */
1649
1257
    return;
1651
1259
 
1652
1260
  str.append(option);
1653
1261
 
1654
 
  if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
 
1262
  if (option_value.compare(0, 2, "0x") == 0)
1655
1263
  {
1656
1264
    /* It's a hex constant, don't escape */
1657
1265
    str.append(option_value);
1671
1279
  syntax errors from the SQL parser.
1672
1280
*/
1673
1281
 
1674
 
static void field_escape(string &in, const char *from)
 
1282
static void field_escape(string &in, const string &from)
1675
1283
{
1676
1284
  uint32_t end_backslashes= 0;
1677
1285
 
1678
1286
  in.append("'");
1679
1287
 
1680
 
  while (*from)
 
1288
  string::const_iterator it= from.begin();
 
1289
  while (it != from.end())
1681
1290
  {
1682
 
    in.append(from, 1);
 
1291
    in.push_back(*it);
1683
1292
 
1684
 
    if (*from == '\\')
1685
 
      end_backslashes^=1;    /* find odd number of backslashes */
 
1293
    if (*it == '\\')
 
1294
      end_backslashes^= 1;    /* find odd number of backslashes */
1686
1295
    else
1687
1296
    {
1688
 
      if (*from == '\'' && !end_backslashes)
 
1297
      if (*it == '\'' && !end_backslashes)
1689
1298
      {
1690
1299
        /* We want a duplicate of "'" for DRIZZLE */
1691
 
        in.append("\'");
 
1300
        in.push_back('\'');
1692
1301
      }
1693
1302
      end_backslashes=0;
1694
1303
    }
1695
 
    from++;
 
1304
    ++it;
1696
1305
  }
1697
1306
  /* Add missing backslashes if user has specified odd number of backs.*/
1698
1307
  if (end_backslashes)
1779
1388
  query_string.clear();
1780
1389
  query_string.reserve(1024);
1781
1390
 
1782
 
  if (path)
 
1391
  if (! path.empty())
1783
1392
  {
1784
1393
    char filename[FN_REFLEN], tmp_path[FN_REFLEN];
1785
1394
 
1787
1396
      Convert the path to native os format
1788
1397
      and resolve to the full filepath.
1789
1398
    */
1790
 
    internal::convert_dirname(tmp_path,path,NULL);
 
1399
    internal::convert_dirname(tmp_path,(char *)path.c_str(),NULL);
1791
1400
    internal::my_load_path(tmp_path, tmp_path, NULL);
1792
1401
    internal::fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1793
1402
 
1800
1409
    query_string.append( filename);
1801
1410
    query_string.append( "'");
1802
1411
 
1803
 
    if (fields_terminated || enclosed || opt_enclosed || escaped)
 
1412
    if (! fields_terminated.empty() || ! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty())
1804
1413
      query_string.append( " FIELDS");
1805
1414
 
1806
1415
    add_load_option(query_string, " TERMINATED BY ", fields_terminated);
1809
1418
    add_load_option(query_string, " ESCAPED BY ", escaped);
1810
1419
    add_load_option(query_string, " LINES TERMINATED BY ", lines_terminated);
1811
1420
 
1812
 
    query_string.append( " FROM ");
1813
 
    query_string.append( result_table);
 
1421
    query_string.append(" FROM ");
 
1422
    query_string.append(result_table);
1814
1423
 
1815
 
    if (where)
 
1424
    if (! where.empty())
1816
1425
    {
1817
 
      query_string.append( " WHERE ");
1818
 
      query_string.append( where);
 
1426
      query_string.append(" WHERE ");
 
1427
      query_string.append(where);
1819
1428
    }
1820
1429
 
1821
1430
    if (order_by)
1822
1431
    {
1823
 
      query_string.append( " ORDER BY ");
1824
 
      query_string.append( order_by);
 
1432
      query_string.append(" ORDER BY ");
 
1433
      query_string.append(order_by);
1825
1434
    }
1826
1435
 
1827
1436
    if (drizzle_query(&dcon, &result, query_string.c_str(),
1834
1443
    }
1835
1444
    drizzle_result_free(&result);
1836
1445
  }
 
1446
 
1837
1447
  else
1838
1448
  {
1839
1449
    if (!opt_xml && opt_comments)
1846
1456
    query_string.append( "SELECT * FROM ");
1847
1457
    query_string.append( result_table);
1848
1458
 
1849
 
    if (where)
 
1459
    if (! where.empty())
1850
1460
    {
1851
1461
      if (!opt_xml && opt_comments)
1852
1462
      {
1853
 
        fprintf(md_result_file, "-- WHERE:  %s\n", where);
 
1463
        fprintf(md_result_file, "-- WHERE:  %s\n", where.c_str());
1854
1464
        check_io(md_result_file);
1855
1465
      }
1856
1466
 
1857
1467
      query_string.append( " WHERE ");
1858
 
      query_string.append( where);
 
1468
      query_string.append( (char *)where.c_str());
1859
1469
    }
1860
1470
    if (order_by)
1861
1471
    {
1896
1506
              opt_quoted_table);
1897
1507
      check_io(md_result_file);
1898
1508
    }
1899
 
 
 
1509
    
1900
1510
    total_length= DRIZZLE_MAX_LINE_LENGTH;                /* Force row break */
1901
1511
    row_break=0;
1902
1512
    rownr=0;
2216
1826
/* dump_all_databases */
2217
1827
 
2218
1828
 
2219
 
static int dump_databases(char **db_names)
 
1829
static int dump_databases(const vector<string> &db_names)
2220
1830
{
2221
1831
  int result=0;
2222
 
  char **db;
2223
 
 
2224
 
 
2225
 
  for (db= db_names ; *db ; db++)
 
1832
  string temp;
 
1833
  for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
2226
1834
  {
2227
 
    if (dump_all_tables_in_db(*db))
 
1835
    temp= *it;
 
1836
    if (dump_all_tables_in_db((char *)temp.c_str()))
2228
1837
      result=1;
2229
1838
  }
2230
1839
  return(result);
2296
1905
{
2297
1906
  drizzle_result_st result;
2298
1907
  drizzle_return_t ret;
2299
 
 
2300
 
  if (!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
2301
 
    return 1;
 
1908
  char qbuf[512];
 
1909
  
 
1910
  /* If this DB contains non-standard tables we don't want it */
 
1911
 
 
1912
  snprintf(qbuf, sizeof(qbuf), "SELECT TABLE_NAME FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='%s' AND TABLE_TYPE != 'STANDARD'", database);
 
1913
  
 
1914
  if (drizzle_query_str(&dcon, &result, qbuf, &ret) != NULL)
 
1915
  {
 
1916
    drizzle_result_buffer(&result);
 
1917
    if (drizzle_result_row_count(&result) > 0)
 
1918
    {
 
1919
      drizzle_result_free(&result);
 
1920
      return 1;
 
1921
    }
 
1922
  }
 
1923
 
 
1924
  drizzle_result_free(&result);
2302
1925
 
2303
1926
  if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
2304
1927
      ret != DRIZZLE_RETURN_OK)
2308
1931
  }
2309
1932
  drizzle_result_free(&result);
2310
1933
 
2311
 
  if (!path && !opt_xml)
 
1934
  if (path.empty() && !opt_xml)
2312
1935
  {
2313
1936
    if (opt_databases || opt_alldbs)
2314
1937
    {
2341
1964
static bool include_table(const char *hash_key, size_t key_size)
2342
1965
{
2343
1966
  string match(hash_key, key_size);
2344
 
  drizzled::hash_set<string>::iterator iter= ignore_table.find(match);
 
1967
  boost::unordered_set<string>::iterator iter= ignore_table.find(match);
2345
1968
  return (iter == ignore_table.end());
2346
1969
}
2347
1970
 
2433
2056
    */
2434
2057
    row= drizzle_row_next(&result);
2435
2058
    lengths= drizzle_row_field_sizes(&result);
2436
 
    name= strmake_root(root, row[0], lengths[0]);
 
2059
    name= root->strmake_root(row[0], lengths[0]);
2437
2060
  }
2438
2061
  drizzle_result_free(&result);
2439
2062
 
2441
2064
}
2442
2065
 
2443
2066
 
2444
 
static int dump_selected_tables(char *db, char **table_names, int tables)
 
2067
static int dump_selected_tables(const string &db, const vector<string> &table_names)
2445
2068
{
2446
2069
  drizzled::memory::Root root;
2447
2070
  char **dump_tables, **pos, **end;
2449
2072
  drizzle_return_t ret;
2450
2073
 
2451
2074
 
2452
 
  if (init_dumping(db, init_dumping_tables))
 
2075
  if (init_dumping((char *)db.c_str(), init_dumping_tables))
2453
2076
    return(1);
2454
2077
 
2455
 
  init_alloc_root(&root, 8192);
2456
 
  if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
 
2078
  root.init_alloc_root(8192);
 
2079
  if (!(dump_tables= pos= (char**) root.alloc_root(table_names.size() * sizeof(char *))))
2457
2080
    die(EX_EOM, _("alloc_root failure."));
2458
2081
 
2459
 
  for (; tables > 0 ; tables-- , table_names++)
 
2082
  for (vector<string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
2460
2083
  {
 
2084
    string temp= *it;
2461
2085
    /* the table name passed on commandline may be wrong case */
2462
 
    if ((*pos= get_actual_table_name(*table_names, &root)))
 
2086
    if ((*pos= get_actual_table_name(temp.c_str(), &root)))
2463
2087
    {
2464
2088
      pos++;
2465
2089
    }
2467
2091
    {
2468
2092
      if (!ignore_errors)
2469
2093
      {
2470
 
        free_root(&root, MYF(0));
 
2094
        root.free_root(MYF(0));
2471
2095
      }
2472
 
      maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""), *table_names);
 
2096
      maybe_die(EX_ILLEGAL_TABLE, _("Couldn't find table: \"%s\""),(char *) temp.c_str());
2473
2097
      /* We shall countinue here, if --force was given */
2474
2098
    }
2475
2099
  }
2481
2105
        ret != DRIZZLE_RETURN_OK)
2482
2106
    {
2483
2107
      if (!ignore_errors)
2484
 
        free_root(&root, MYF(0));
 
2108
        root.free_root(MYF(0));
2485
2109
      DB_error(&result, ret, _("when doing refresh"));
2486
2110
      /* We shall countinue here, if --force was given */
2487
2111
    }
2489
2113
      drizzle_result_free(&result);
2490
2114
  }
2491
2115
  if (opt_xml)
2492
 
    print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NULL);
 
2116
    print_xml_tag(md_result_file, "", "\n", "database", "name=", (char *)db.c_str(), NULL);
2493
2117
 
2494
2118
  /* Dump each selected table */
2495
2119
  for (pos= dump_tables; pos < end; pos++)
2496
 
    dump_table(*pos, db);
 
2120
    dump_table(*pos, (char *)db.c_str());
2497
2121
 
2498
 
  free_root(&root, MYF(0));
 
2122
  root.free_root(MYF(0));
2499
2123
  free(order_by);
2500
2124
  order_by= 0;
2501
2125
  if (opt_xml)
2817
2441
  return result;
2818
2442
}
2819
2443
 
2820
 
 
2821
2444
int main(int argc, char **argv)
2822
2445
{
 
2446
try
 
2447
{
2823
2448
  int exit_code;
2824
2449
  MY_INIT("drizzledump");
2825
2450
  drizzle_result_st result;
2826
2451
 
 
2452
  po::options_description commandline_options("Options used only in command line");
 
2453
  commandline_options.add_options()
 
2454
  ("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
 
2455
  "Dump all the databases. This will be same as --databases with all databases selected.")
 
2456
  ("all-tablespaces,Y", po::value<bool>(&opt_alltspcs)->default_value(false)->zero_tokens(),
 
2457
  "Dump all the tablespaces.")
 
2458
  ("complete-insert,c", po::value<bool>(&opt_complete_insert)->default_value(false)->zero_tokens(),
 
2459
  "Use complete insert statements.")
 
2460
  ("compress,C", po::value<bool>(&opt_compress)->default_value(false)->zero_tokens(),
 
2461
  "Use compression in server/client protocol.")
 
2462
  ("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
 
2463
  "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")
 
2464
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
 
2465
  "Continue even if we get an sql-error.")
 
2466
  ("help,?", "Display this help message and exit.")
 
2467
  ("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
 
2468
  "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 and --lock-tables off.")
 
2469
  ("order-by-primary", po::value<bool>(&opt_order_by_primary)->default_value(false)->zero_tokens(),
 
2470
  "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.")
 
2471
  ("routines,R", po::value<bool>(&opt_routines)->default_value(false)->zero_tokens(),
 
2472
  "Dump stored routines (functions and procedures).")
 
2473
  ("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
 
2474
  "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. Option automatically turns off --lock-tables.")
 
2475
  ("opt", "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.") 
 
2476
  ("skip-opt", 
 
2477
  "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.")    
 
2478
  ("tables", "Overrides option --databases (-B).")
 
2479
  ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
 
2480
  N_("Number of rows before each output progress report (requires --verbose)."))
 
2481
  ("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
 
2482
  "Print info about the various stages.")
 
2483
  ("version,V", "Output version information and exit.")
 
2484
  ("xml,X", "Dump a database as well formed XML.")
 
2485
  ("skip-comments", "Turn off Comments")
 
2486
  ("skip-create", "Turn off create-options")
 
2487
  ("skip-extended-insert", "Turn off extended-insert") 
 
2488
  ("skip-dump-date", "Turn off dump-date")
 
2489
  ("no-defaults", "Do not read from the configuration files")
 
2490
  ;
 
2491
 
 
2492
  po::options_description dump_options("Options specific to the drizzle client");
 
2493
  dump_options.add_options()
 
2494
  ("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
 
2495
  "Add a 'DROP DATABASE' before each create.")
 
2496
  ("add-drop-table", po::value<bool>(&opt_drop)->default_value(true)->zero_tokens(),
 
2497
  "Add a 'drop table' before each create.")
 
2498
  ("allow-keywords", po::value<bool>(&opt_keywords)->default_value(false)->zero_tokens(),
 
2499
  "Allow creation of column names that are keywords.")
 
2500
  ("comments,i", po::value<bool>(&opt_comments)->default_value(true)->zero_tokens(),
 
2501
  "Write additional information.")
 
2502
  ("compatible", po::value<string>(&opt_compatible_mode_str)->default_value(""),
 
2503
  "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.")
 
2504
  ("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
 
2505
  "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")
 
2506
  ("create-options", po::value<bool>(&create_options)->default_value(true)->zero_tokens(),
 
2507
  "Include all DRIZZLE specific create options.")
 
2508
  ("dump-date", po::value<bool>(&opt_dump_date)->default_value(true)->zero_tokens(),
 
2509
  "Put a dump date to the end of the output.")
 
2510
  ("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
 
2511
  "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.")
 
2512
  ("delayed-insert", po::value<bool>(&opt_delayed)->default_value(false)->zero_tokens(),
 
2513
  "Insert rows with INSERT DELAYED; ")
 
2514
  ("disable-keys,K", po::value<bool>(&opt_disable_keys)->default_value(true)->zero_tokens(),
 
2515
  "'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.")
 
2516
  ("extended-insert,e", po::value<bool>(&extended_insert)->default_value(true)->zero_tokens(),
 
2517
  "Allows utilization of the new, much faster INSERT syntax.")
 
2518
  ("fields-terminated-by", po::value<string>(&fields_terminated)->default_value(""),
 
2519
  "Fields in the textfile are terminated by ...")
 
2520
  ("fields-enclosed-by", po::value<string>(&enclosed)->default_value(""),
 
2521
  "Fields in the importfile are enclosed by ...")
 
2522
  ("fields-optionally-enclosed-by", po::value<string>(&opt_enclosed)->default_value(""),
 
2523
  "Fields in the i.file are opt. enclosed by ...")
 
2524
  ("fields-escaped-by", po::value<string>(&escaped)->default_value(""),
 
2525
  "Fields in the i.file are escaped by ...")
 
2526
  ("hex-blob", po::value<bool>(&opt_hex_blob)->default_value(false)->zero_tokens(),
 
2527
  "Dump binary strings (BINARY, VARBINARY, BLOB) in hexadecimal format.")
 
2528
  ("ignore-table", po::value<string>(),
 
2529
  "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")
 
2530
  ("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
 
2531
  "Insert rows with INSERT IGNORE.")
 
2532
  ("lines-terminated-by", po::value<string>(&lines_terminated)->default_value(""),
 
2533
  "Lines in the i.file are terminated by ...")
 
2534
  ("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
 
2535
  "Wrap tables with autocommit/commit statements.")
 
2536
  ("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
 
2537
  "'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.}.")
 
2538
  ("no-create-info,t", po::value<bool>(&opt_no_create_info)->default_value(false)->zero_tokens(),
 
2539
  "Don't write table creation info.")
 
2540
  ("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
 
2541
  "No row information.")
 
2542
  ("no-set-names,N", "Deprecated. Use --skip-set-charset instead.")
 
2543
  ("set-charset", po::value<bool>(&opt_set_charset)->default_value(false)->zero_tokens(),
 
2544
  "Enable set-name")
 
2545
  ("quick,q", po::value<bool>(&quick)->default_value(true)->zero_tokens(),
 
2546
  "Don't buffer query, dump directly to stdout.")
 
2547
  ("quote-names,Q", po::value<bool>(&opt_quoted)->default_value(true)->zero_tokens(),
 
2548
  "Quote table and column names with backticks (`).")
 
2549
  ("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
 
2550
  "Use REPLACE INTO instead of INSERT INTO.")
 
2551
  ("result-file,r", po::value<string>(),
 
2552
  "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).")  
 
2553
  ("tab,T", po::value<string>(&path)->default_value(""),
 
2554
  "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if drizzledump is run on the same machine as the drizzled daemon.")
 
2555
  ("where,w", po::value<string>(&where)->default_value(""),
 
2556
  "Dump only selected records; QUOTES mandatory!")
 
2557
  ;
 
2558
 
 
2559
  po::options_description client_options("Options specific to the client");
 
2560
  client_options.add_options()
 
2561
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
 
2562
  "Connect to host.")
 
2563
  ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
 
2564
  N_("Use MySQL Protocol."))
 
2565
  ("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
 
2566
  "Password to use when connecting to server. If password is not given it's solicited on the tty.")
 
2567
  ("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
 
2568
  "Port number to use for connection.")
 
2569
  ("user,u", po::value<string>(&current_user)->default_value(""),
 
2570
  "User for login if not current user.")
 
2571
  ("protocol",po::value<string>(),
 
2572
  "The protocol of connection (tcp,socket,pipe,memory).")
 
2573
  ;
 
2574
 
 
2575
  po::options_description hidden_options("Hidden Options");
 
2576
  hidden_options.add_options()
 
2577
  ("database-used", po::value<vector<string> >(), "Used to select the database")
 
2578
  ("Table-used", po::value<vector<string> >(), "Used to select the tables")
 
2579
  ;
 
2580
 
 
2581
  po::options_description all_options("Allowed Options + Hidden Options");
 
2582
  all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
 
2583
 
 
2584
  po::options_description long_options("Allowed Options");
 
2585
  long_options.add(commandline_options).add(dump_options).add(client_options);
 
2586
 
 
2587
  std::string system_config_dir_dump(SYSCONFDIR); 
 
2588
  system_config_dir_dump.append("/drizzle/drizzledump.cnf");
 
2589
 
 
2590
  std::string system_config_dir_client(SYSCONFDIR); 
 
2591
  system_config_dir_client.append("/drizzle/client.cnf");
 
2592
 
 
2593
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
 
2594
 
 
2595
  po::positional_options_description p;
 
2596
  p.add("database-used", 1);
 
2597
  p.add("Table-used",-1);
 
2598
 
2827
2599
  compatible_mode_normal_str[0]= 0;
2828
 
 
2829
 
  exit_code= get_options(&argc, &argv);
 
2600
  
 
2601
  md_result_file= stdout;
 
2602
 
 
2603
  po::variables_map vm;
 
2604
 
 
2605
  po::store(po::command_line_parser(argc, argv).options(all_options).
 
2606
            positional(p).extra_parser(parse_password_arg).run(), vm);
 
2607
 
 
2608
  if (! vm.count("no-defaults"))
 
2609
  {
 
2610
    std::string user_config_dir_dump(user_config_dir);
 
2611
    user_config_dir_dump.append("/drizzle/drizzledump.cnf"); 
 
2612
 
 
2613
    std::string user_config_dir_client(user_config_dir);
 
2614
    user_config_dir_client.append("/drizzle/client.cnf");
 
2615
 
 
2616
    ifstream user_dump_ifs(user_config_dir_dump.c_str());
 
2617
    po::store(parse_config_file(user_dump_ifs, dump_options), vm);
 
2618
 
 
2619
    ifstream user_client_ifs(user_config_dir_client.c_str());
 
2620
    po::store(parse_config_file(user_client_ifs, client_options), vm);
 
2621
 
 
2622
    ifstream system_dump_ifs(system_config_dir_dump.c_str());
 
2623
    po::store(parse_config_file(system_dump_ifs, dump_options), vm);
 
2624
 
 
2625
    ifstream system_client_ifs(system_config_dir_client.c_str());
 
2626
    po::store(parse_config_file(system_client_ifs, client_options), vm);
 
2627
  }
 
2628
 
 
2629
  po::notify(vm);  
 
2630
  
 
2631
  if ( ! vm.count("database-used") && ! vm.count("Table-used") && ! opt_alldbs && path.empty())
 
2632
  {
 
2633
    printf(_("Usage: %s [OPTIONS] database [tables]\n"), internal::my_progname);
 
2634
    printf(_("OR     %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
 
2635
          internal::my_progname);
 
2636
    printf(_("OR     %s [OPTIONS] --all-databases [OPTIONS]\n"), internal::my_progname);
 
2637
    exit(1);
 
2638
  }
 
2639
 
 
2640
  if (vm.count("port"))
 
2641
  {
 
2642
    /* If the port number is > 65535 it is not a valid port
 
2643
     *        This also helps with potential data loss casting unsigned long to a
 
2644
     *               uint32_t. 
 
2645
     */
 
2646
    if (opt_drizzle_port > 65535)
 
2647
    {
 
2648
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
 
2649
      exit(-1);
 
2650
    }
 
2651
  }
 
2652
 
 
2653
  if(vm.count("password"))
 
2654
  {
 
2655
    if (!opt_password.empty())
 
2656
      opt_password.erase();
 
2657
    if (password == PASSWORD_SENTINEL)
 
2658
    {
 
2659
      opt_password= "";
 
2660
    }
 
2661
    else
 
2662
    {
 
2663
      opt_password= password;
 
2664
      tty_password= false;
 
2665
    }
 
2666
  }
 
2667
  else
 
2668
  {
 
2669
      tty_password= true;
 
2670
  }
 
2671
 
 
2672
  if (vm.count("result-file"))
 
2673
  {
 
2674
    if (!(md_result_file= fopen(vm["result-file"].as<string>().c_str(), "w")))
 
2675
      exit(1);
 
2676
  }
 
2677
 
 
2678
  if (vm.count("no-set-names"))
 
2679
  {
 
2680
    opt_set_charset= 0;
 
2681
  }
 
2682
 
 
2683
  if (! path.empty())
 
2684
  { 
 
2685
    opt_disable_keys= 0;
 
2686
 
 
2687
    if (vm["tab"].as<string>().length() >= FN_REFLEN)
 
2688
    {
 
2689
      /*
 
2690
        This check is made because the some the file functions below
 
2691
        have FN_REFLEN sized stack allocated buffers and will cause
 
2692
        a crash even if the input destination buffer is large enough
 
2693
        to hold the output.
 
2694
      */
 
2695
      fprintf(stderr, _("Input filename too long: %s"), vm["tab"].as<string>().c_str());
 
2696
      exit(EXIT_ARGUMENT_INVALID);
 
2697
    }
 
2698
  }
 
2699
 
 
2700
  if (vm.count("version"))
 
2701
  {
 
2702
     printf(_("%s  Drizzle %s libdrizzle %s, for %s-%s (%s)\n"), internal::my_progname,
 
2703
       VERSION, drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
 
2704
  }
 
2705
 
 
2706
  if (vm.count("xml"))
 
2707
  { 
 
2708
    opt_xml= 1;
 
2709
    extended_insert= opt_drop= opt_disable_keys= opt_autocommit= opt_create_db= 0;
 
2710
  }
 
2711
 
 
2712
  if (vm.count("help"))
 
2713
  {
 
2714
    printf(_("%s  Drizzle %s libdrizzle %s, for %s-%s (%s)\n"), internal::my_progname,
 
2715
      VERSION, drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
 
2716
    puts("");
 
2717
    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"));
 
2718
    puts(_("Dumps definitions and data from a Drizzle database server"));
 
2719
    cout << long_options;
 
2720
    printf(_("Usage: %s [OPTIONS] database [tables]\n"), internal::my_progname);
 
2721
    printf(_("OR     %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
 
2722
          internal::my_progname);
 
2723
    printf(_("OR     %s [OPTIONS] --all-databases [OPTIONS]\n"), internal::my_progname);
 
2724
    exit(1);
 
2725
  }
 
2726
  
 
2727
  if (vm.count("skip-opt"))
 
2728
  {
 
2729
    extended_insert= opt_drop= quick= create_options= 0;
 
2730
    opt_disable_keys= opt_set_charset= 0;
 
2731
  }
 
2732
 
 
2733
  if (opt_compact)
 
2734
  { 
 
2735
    opt_comments= opt_drop= opt_disable_keys= 0;
 
2736
    opt_set_charset= 0;
 
2737
  }
 
2738
 
 
2739
  if (vm.count("opt"))
 
2740
  {
 
2741
    extended_insert= opt_drop= quick= create_options= 1;
 
2742
    opt_disable_keys= opt_set_charset= 1;
 
2743
  }
 
2744
 
 
2745
  if (vm.count("tables"))
 
2746
  { 
 
2747
    opt_databases= false;
 
2748
  }
 
2749
 
 
2750
  if (vm.count("ignore-table"))
 
2751
  {
 
2752
    if (!strchr(vm["ignore-table"].as<string>().c_str(), '.'))
 
2753
    {
 
2754
      fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
 
2755
      exit(EXIT_ARGUMENT_INVALID);
 
2756
    }
 
2757
    string tmpptr(vm["ignore-table"].as<string>());
 
2758
    ignore_table.insert(tmpptr); 
 
2759
  }
 
2760
  
 
2761
  if (vm.count("skip-create"))
 
2762
  {
 
2763
    opt_create_db= opt_no_create_info= create_options= false;
 
2764
  }
 
2765
 
 
2766
  if (vm.count("skip-comments"))
 
2767
  {
 
2768
    opt_comments= false; 
 
2769
  }
 
2770
 
 
2771
  if (vm.count("skip-extended-insert"))
 
2772
  {
 
2773
    extended_insert= false; 
 
2774
  }
 
2775
 
 
2776
  if (vm.count("skip-dump-date"))
 
2777
  {
 
2778
    opt_dump_date= false; 
 
2779
  } 
 
2780
 
 
2781
  if (! opt_compatible_mode_str.empty())
 
2782
  {
 
2783
    char buff[255];
 
2784
    char *end= compatible_mode_normal_str;
 
2785
    uint32_t i;
 
2786
    uint32_t mode;
 
2787
    uint32_t error_len;
 
2788
 
 
2789
    opt_quoted= 1;
 
2790
    opt_set_charset= 0;
 
2791
    opt_compatible_mode= find_set(&compatible_mode_typelib,
 
2792
                                            opt_compatible_mode_str.c_str(), opt_compatible_mode_str.length(),
 
2793
                                            &err_ptr, &error_len);
 
2794
    if (error_len)
 
2795
    {
 
2796
      strncpy(buff, err_ptr, min((uint32_t)sizeof(buff), error_len+1));
 
2797
      fprintf(stderr, _("Invalid mode to --compatible: %s\n"), buff);
 
2798
      exit(EXIT_ARGUMENT_INVALID);
 
2799
    }
 
2800
    mode= opt_compatible_mode;
 
2801
    for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
 
2802
    {
 
2803
      if (mode & 1)
 
2804
      {
 
2805
        uint32_t len = strlen(compatible_mode_names[i]);
 
2806
        end= strcpy(end, compatible_mode_names[i]) + len;
 
2807
        end= strcpy(end, ",")+1;
 
2808
      }
 
2809
    }
 
2810
    if (end!=compatible_mode_normal_str)
 
2811
      end[-1]= 0;
 
2812
  }
 
2813
 
 
2814
 
 
2815
  exit_code= get_options();
2830
2816
  if (exit_code)
2831
2817
  {
2832
2818
    free_resources();
2838
2824
    free_resources();
2839
2825
    exit(EX_DRIZZLEERR);
2840
2826
  }
2841
 
  if (!path)
2842
 
    write_header(md_result_file, *argv);
 
2827
  if (path.empty() && vm.count("database-used"))
 
2828
  {
 
2829
    string database_used= *vm["database-used"].as< vector<string> >().begin();
 
2830
    write_header(md_result_file, (char *)database_used.c_str());
 
2831
  }
2843
2832
 
2844
2833
  if ((opt_lock_all_tables) && do_flush_tables_read_lock(&dcon))
2845
2834
    goto err;
2859
2848
  {
2860
2849
    dump_all_databases();
2861
2850
  }
2862
 
  else if (argc > 1 && !opt_databases)
 
2851
  if (vm.count("database-used") && vm.count("Table-used") && ! opt_databases)
2863
2852
  {
 
2853
    string database_used= *vm["database-used"].as< vector<string> >().begin();
2864
2854
    /* Only one database and selected table(s) */
2865
 
    dump_selected_tables(*argv, (argv + 1), (argc - 1));
2866
 
  }
2867
 
  else
2868
 
  {
2869
 
    dump_databases(argv);
 
2855
    dump_selected_tables(database_used, vm["Table-used"].as< vector<string> >());
 
2856
  }
 
2857
 
 
2858
  if (vm.count("Table-used") && opt_databases)
 
2859
  {
 
2860
    vector<string> database_used= vm["database-used"].as< vector<string> >();
 
2861
    vector<string> table_used= vm["Table-used"].as< vector<string> >();
 
2862
 
 
2863
    for (vector<string>::iterator it= table_used.begin();
 
2864
       it != table_used.end();
 
2865
       ++it)
 
2866
    {
 
2867
      database_used.insert(database_used.end(), *it);
 
2868
    }
 
2869
    dump_databases(database_used);
 
2870
  }
 
2871
  
 
2872
  if (vm.count("database-used") && ! vm.count("Table-used"))
 
2873
  {
 
2874
    dump_databases(vm["database-used"].as< vector<string> >());
2870
2875
  }
2871
2876
 
2872
2877
  /* ensure dumped data flushed */
2885
2890
  */
2886
2891
err:
2887
2892
  dbDisconnect(current_host);
2888
 
  if (!path)
 
2893
  if (path.empty())
2889
2894
    write_footer(md_result_file);
2890
2895
  free_resources();
2891
2896
 
2892
2897
  if (stderror_file)
2893
2898
    fclose(stderror_file);
 
2899
}
2894
2900
 
 
2901
  catch(exception &err)
 
2902
  {
 
2903
    cerr << err.what() << endl;
 
2904
  }
 
2905
  
2895
2906
  return(first_error);
2896
2907
} /* main */