54
52
static char *add_load_option(char *ptr,const char *object,
55
53
const char *statement);
57
static bool verbose= false, lock_tables= false, ignore_errors= false,
55
static bool verbose= false, ignore_errors= false,
58
56
opt_delete= false, opt_replace= false, silent= false,
59
57
ignore_unique= false, opt_low_priority= false,
60
tty_password= false, opt_mysql= false;
58
use_drizzle_protocol= false, opt_local_file;
62
static uint32_t opt_use_threads= 0, opt_local_file= 0;
63
static char *opt_password= NULL, *current_user= NULL,
64
*current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
65
*lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
66
*escaped= NULL, *opt_columns= NULL;
60
static uint32_t opt_use_threads;
67
61
static uint32_t opt_drizzle_port= 0;
68
62
static int64_t opt_ignore_lines= -1;
70
static struct option my_long_options[] =
73
"Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to LOAD DATA INFILE.",
74
(char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
76
{"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
77
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
78
{"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
79
(char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
80
{"fields-terminated-by", OPT_FTB,
81
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
82
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
83
{"fields-enclosed-by", OPT_ENC,
84
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
85
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
86
{"fields-optionally-enclosed-by", OPT_O_ENC,
87
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
88
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
89
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
90
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
92
{"force", 'f', "Continue even if we get an sql-error.",
93
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
95
{"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
97
{"host", 'h', "Connect to host.", (char**) ¤t_host,
98
(char**) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
99
{"ignore", 'i', "If duplicate unique key was found, keep old row.",
100
(char**) &ignore_unique, (char**) &ignore_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
101
{"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
102
(char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
103
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
104
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
105
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
106
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
107
{"local", 'L', "Read all files through the client.", (char**) &opt_local_file,
108
(char**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
109
{"lock-tables", 'l', "Lock all tables for write (this disables threads).",
110
(char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG,
112
{"low-priority", OPT_LOW_PRIORITY,
113
"Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
114
(char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
115
{"mysql", 'm', N_("Use MySQL Protocol."),
116
(char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
119
"Password to use when connecting to server. If password is not given it's asked from the tty.",
120
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
121
{"port", 'p', "Port number to use for connection or 0 for default to, in "
122
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
123
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
124
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
125
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
126
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
127
{"replace", 'r', "If duplicate unique key was found, replace old row.",
128
(char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
129
{"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
130
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
131
{"use-threads", OPT_USE_THREADS,
132
"Load files in parallel. The argument is the number "
133
"of threads to use for loading data.",
134
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
135
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
136
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
137
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
138
{"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
139
(char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
140
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
141
NO_ARG, 0, 0, 0, 0, 0, 0},
142
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
146
static const char *load_default_groups[]= { "drizzleimport","client",0 };
148
static void print_version(void)
150
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n" ,internal::my_progname,
151
IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
155
static void usage(void)
158
puts("Copyright (C) 2008 Drizzle Open Source Development Team");
159
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");
161
Loads tables from text files in various formats. The base name of the\n\
162
text file must be the name of the table that should be used.\n\
163
If one uses sockets to connect to the Drizzle server, the server will open and\n\
164
read the text file directly. In other cases the client will open the text\n\
165
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
167
printf("\nUsage: %s [OPTIONS] database textfile...",internal::my_progname);
168
internal::print_defaults("drizzle",load_default_groups);
169
my_print_help(my_long_options);
170
my_print_variables(my_long_options);
173
static int get_one_option(int optid, const struct option *, char *argument)
176
uint64_t temp_drizzle_port= 0;
180
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
181
/* if there is an alpha character this is not a valid port */
182
if (strlen(endchar) != 0)
184
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
185
return EXIT_ARGUMENT_INVALID;
187
/* If the port number is > 65535 it is not a valid port
188
This also helps with potential data loss casting unsigned long to a
190
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
192
fprintf(stderr, _("Value supplied for port is not valid.\n"));
193
return EXIT_ARGUMENT_INVALID;
197
opt_drizzle_port= (uint32_t) temp_drizzle_port;
203
char *start=argument;
206
opt_password = strdup(argument);
207
if (opt_password == NULL)
209
fprintf(stderr, "Memory allocation error while copying password. "
211
return EXIT_OUT_OF_MEMORY;
215
/* Overwriting password with 'x' */
220
/* Cut length of argument */
228
case OPT_DRIZZLE_PROTOCOL:
230
case 'V': print_version(); exit(0);
240
static int get_options(int *argc, char ***argv)
244
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
247
if (enclosed && opt_enclosed)
64
std::string opt_columns,
78
static int get_options(void)
81
if (! enclosed.empty() && ! opt_enclosed.empty())
249
83
fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
558
349
int main(int argc, char **argv)
564
internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
565
/* argv is changed in the program */
567
if (get_options(&argc, &argv))
569
internal::free_defaults(argv_to_free);
355
po::options_description commandline_options("Options used only in command line");
356
commandline_options.add_options()
358
("debug,#", po::value<string>(),
359
"Output debug log. Often this is 'd:t:o,filename'.")
360
("delete,d", po::value<bool>(&opt_delete)->default_value(false)->zero_tokens(),
361
"First delete all rows from table.")
362
("help,?", "Displays this help and exits.")
363
("ignore,i", po::value<bool>(&ignore_unique)->default_value(false)->zero_tokens(),
364
"If duplicate unique key was found, keep old row.")
365
("low-priority", po::value<bool>(&opt_low_priority)->default_value(false)->zero_tokens(),
366
"Use LOW_PRIORITY when updating the table.")
367
("replace,r", po::value<bool>(&opt_replace)->default_value(false)->zero_tokens(),
368
"If duplicate unique key was found, replace old row.")
369
("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
370
"Print info about the various stages.")
371
("version,V", "Output version information and exit.")
374
po::options_description import_options("Options specific to the drizzleimport");
375
import_options.add_options()
376
("columns,C", po::value<string>(&opt_columns)->default_value(""),
377
"Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to LOAD DATA INFILE.")
378
("fields-terminated-by", po::value<string>(&fields_terminated)->default_value(""),
379
"Fields in the textfile are terminated by ...")
380
("fields-enclosed-by", po::value<string>(&enclosed)->default_value(""),
381
"Fields in the importfile are enclosed by ...")
382
("fields-optionally-enclosed-by", po::value<string>(&opt_enclosed)->default_value(""),
383
"Fields in the i.file are opt. enclosed by ...")
384
("fields-escaped-by", po::value<string>(&escaped)->default_value(""),
385
"Fields in the i.file are escaped by ...")
386
("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
387
"Continue even if we get an sql-error.")
388
("ignore-lines", po::value<int64_t>(&opt_ignore_lines)->default_value(0),
389
"Ignore first n lines of data infile.")
390
("lines-terminated-by", po::value<string>(&lines_terminated)->default_value(""),
391
"Lines in the i.file are terminated by ...")
392
("local,L", po::value<bool>(&opt_local_file)->default_value(false)->zero_tokens(),
393
"Read all files through the client.")
394
("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
396
("use-threads", po::value<uint32_t>(&opt_use_threads)->default_value(4),
397
"Load files in parallel. The argument is the number of threads to use for loading data (default is 4.")
400
po::options_description client_options("Options specific to the client");
401
client_options.add_options()
402
("host,h", po::value<string>(¤t_host)->default_value("localhost"),
404
("password,P", po::value<string>(&password),
405
"Password to use when connecting to server. If password is not given it's asked from the tty." )
406
("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
407
"Port number to use for connection")
408
("protocol", po::value<string>(&opt_protocol)->default_value("mysql"),
409
"The protocol of connection (mysql or drizzle).")
410
("user,u", po::value<string>(¤t_user)->default_value(""),
411
"User for login if not current user.")
414
po::options_description long_options("Allowed Options");
415
long_options.add(commandline_options).add(import_options).add(client_options);
417
std::string system_config_dir_import(SYSCONFDIR);
418
system_config_dir_import.append("/drizzle/drizzleimport.cnf");
420
std::string system_config_dir_client(SYSCONFDIR);
421
system_config_dir_client.append("/drizzle/client.cnf");
423
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
425
po::variables_map vm;
427
// Disable allow_guessing
428
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
430
po::store(po::command_line_parser(argc, argv).options(long_options).
431
style(style).extra_parser(parse_password_arg).run(), vm);
433
std::string user_config_dir_import(user_config_dir);
434
user_config_dir_import.append("/drizzle/drizzleimport.cnf");
436
std::string user_config_dir_client(user_config_dir);
437
user_config_dir_client.append("/drizzle/client.cnf");
439
ifstream user_import_ifs(user_config_dir_import.c_str());
440
po::store(parse_config_file(user_import_ifs, import_options), vm);
442
ifstream user_client_ifs(user_config_dir_client.c_str());
443
po::store(parse_config_file(user_client_ifs, client_options), vm);
445
ifstream system_import_ifs(system_config_dir_import.c_str());
446
store(parse_config_file(system_import_ifs, import_options), vm);
448
ifstream system_client_ifs(system_config_dir_client.c_str());
449
po::store(parse_config_file(system_client_ifs, client_options), vm);
452
if (vm.count("protocol"))
454
std::transform(opt_protocol.begin(), opt_protocol.end(),
455
opt_protocol.begin(), ::tolower);
457
if (not opt_protocol.compare("mysql"))
458
use_drizzle_protocol=false;
459
else if (not opt_protocol.compare("drizzle"))
460
use_drizzle_protocol=true;
463
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
468
if (vm.count("port"))
471
/* If the port number is > 65535 it is not a valid port
472
This also helps with potential data loss casting unsigned long to a
474
if (opt_drizzle_port > 65535)
476
fprintf(stderr, _("Value supplied for port is not valid.\n"));
477
exit(EXIT_ARGUMENT_INVALID);
481
if( vm.count("password") )
483
if (!opt_password.empty())
484
opt_password.erase();
485
if (password == PASSWORD_SENTINEL)
491
opt_password= password;
501
if (vm.count("version"))
503
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
504
IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
507
if (vm.count("help") || argc < 2)
509
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
510
IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
511
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");
513
Loads tables from text files in various formats. The base name of the\n\
514
text file must be the name of the table that should be used.\n\
515
If one uses sockets to connect to the Drizzle server, the server will open and\n\
516
read the text file directly. In other cases the client will open the text\n\
517
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
519
printf("\nUsage: %s [OPTIONS] database textfile...", program_name);
530
current_db= (*argv)++;
573
#ifdef HAVE_LIBPTHREAD
574
if (opt_use_threads && !lock_tables)
576
535
pthread_t mainthread; /* Thread descriptor */
577
536
pthread_attr_t attr; /* Thread attributes */