~linuxjedi/drizzle/drizzle-bug-597905

« back to all changes in this revision

Viewing changes to client/drizzledump.cc

  • Committer: Monty Taylor
  • Date: 2010-06-26 03:52:47 UTC
  • mfrom: (1637.1.5 staging)
  • Revision ID: mordred@inaugust.com-20100626035247-i0iq4sd6wqzfisyy
Merged in staging changes: Mark's syslog patch and vijay's program_options.

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