52
54
static char *add_load_option(char *ptr,const char *object,
53
55
const char *statement);
55
static bool verbose= false, ignore_errors= false,
57
static bool verbose= false, lock_tables= false, ignore_errors= false,
56
58
opt_delete= false, opt_replace= false, silent= false,
57
59
ignore_unique= false, opt_low_priority= false,
58
use_drizzle_protocol= false, opt_local_file;
60
tty_password= false, opt_mysql= false;
60
static uint32_t opt_use_threads;
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;
61
67
static uint32_t opt_drizzle_port= 0;
62
68
static int64_t opt_ignore_lines= -1;
64
std::string opt_columns,
78
static int get_options(void)
81
if (! enclosed.empty() && ! opt_enclosed.empty())
70
static struct my_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, 0, 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 bool get_one_option(int optid, const struct my_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"));
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"));
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. "
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)
83
249
fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
349
558
int main(int argc, char **argv)
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
if (user_config_dir.compare(0, 2, "~/") == 0)
428
homedir= getenv("HOME");
430
user_config_dir.replace(0, 1, homedir);
433
po::variables_map vm;
435
// Disable allow_guessing
436
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
438
po::store(po::command_line_parser(argc, argv).options(long_options).
439
style(style).extra_parser(parse_password_arg).run(), vm);
441
std::string user_config_dir_import(user_config_dir);
442
user_config_dir_import.append("/drizzle/drizzleimport.cnf");
444
std::string user_config_dir_client(user_config_dir);
445
user_config_dir_client.append("/drizzle/client.cnf");
447
ifstream user_import_ifs(user_config_dir_import.c_str());
448
po::store(parse_config_file(user_import_ifs, import_options), vm);
450
ifstream user_client_ifs(user_config_dir_client.c_str());
451
po::store(parse_config_file(user_client_ifs, client_options), vm);
453
ifstream system_import_ifs(system_config_dir_import.c_str());
454
store(parse_config_file(system_import_ifs, import_options), vm);
456
ifstream system_client_ifs(system_config_dir_client.c_str());
457
po::store(parse_config_file(system_client_ifs, client_options), vm);
460
if (vm.count("protocol"))
462
std::transform(opt_protocol.begin(), opt_protocol.end(),
463
opt_protocol.begin(), ::tolower);
465
if (not opt_protocol.compare("mysql"))
466
use_drizzle_protocol=false;
467
else if (not opt_protocol.compare("drizzle"))
468
use_drizzle_protocol=true;
471
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
476
if (vm.count("port"))
479
/* If the port number is > 65535 it is not a valid port
480
This also helps with potential data loss casting unsigned long to a
482
if (opt_drizzle_port > 65535)
484
fprintf(stderr, _("Value supplied for port is not valid.\n"));
485
exit(EXIT_ARGUMENT_INVALID);
489
if( vm.count("password") )
491
if (!opt_password.empty())
492
opt_password.erase();
493
if (password == PASSWORD_SENTINEL)
499
opt_password= password;
509
if (vm.count("version"))
511
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
512
IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
515
if (vm.count("help") || argc < 2)
517
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
518
IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
519
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");
521
Loads tables from text files in various formats. The base name of the\n\
522
text file must be the name of the table that should be used.\n\
523
If one uses sockets to connect to the Drizzle server, the server will open and\n\
524
read the text file directly. In other cases the client will open the text\n\
525
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
527
printf("\nUsage: %s [OPTIONS] database textfile...", program_name);
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);
538
current_db= (*argv)++;
573
#ifdef HAVE_LIBPTHREAD
574
if (opt_use_threads && !lock_tables)
543
576
pthread_t mainthread; /* Thread descriptor */
544
577
pthread_attr_t attr; /* Thread attributes */