2
Copyright (C) 2010 Vijay Samuel
3
Copyright (C) 2010 Brian Aker
4
Copyright (C) 2000-2006 MySQL AB
5
Copyright (C) 2008-2009 Sun Microsystems, Inc.
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; version 2 of the License.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20
#define IMPORT_VERSION "4.0"
1
/* Copyright (C) 2008 Drizzle Open Source Development Team
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
** drizzleimport.c - Imports all given files
20
** *************************
22
** * AUTHOR: Monty & Jani *
23
** * DATE: June 24, 1997 *
25
** *************************
27
#define IMPORT_VERSION "3.7"
22
29
#include "client_priv.h"
27
#include <boost/program_options.hpp>
30
/* Added this for string translation. */
31
#include <drizzled/gettext.h>
32
#include <drizzled/configmake.h>
34
namespace po= boost::program_options;
36
using namespace drizzled;
38
extern "C" void * worker_thread(void *arg);
42
const char *program_name= "drizzleimport";
30
#include "drizzle_version.h"
31
#include <my_pthread.h>
44
34
/* Global Thread counter */
46
36
pthread_mutex_t counter_mutex;
47
37
pthread_cond_t count_threshhold;
49
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
50
drizzle_return_t ret, char *table);
51
static char *field_escape(char *to,const char *from,uint32_t length);
39
static void db_error_with_table(DRIZZLE *drizzle, char *table);
40
static void db_error(DRIZZLE *drizzle);
41
static char *field_escape(char *to,const char *from,uint length);
52
42
static char *add_load_option(char *ptr,const char *object,
53
43
const char *statement);
55
static bool verbose= false, ignore_errors= false,
56
opt_delete= false, opt_replace= false, silent= false,
57
ignore_unique= false, opt_low_priority= false,
58
use_drizzle_protocol= false, opt_local_file;
60
static uint32_t opt_use_threads;
61
static uint32_t opt_drizzle_port= 0;
45
static bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
46
replace=0,silent=0,ignore=0,opt_compress=0,
47
opt_low_priority= 0, tty_password= 0;
48
static bool debug_info_flag= 0, debug_check_flag= 0;
49
static uint opt_use_threads=0, opt_local_file=0, my_end_arg= 0;
50
static char *opt_password=0, *current_user=0,
51
*current_host=0, *current_db=0, *fields_terminated=0,
52
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
53
*escaped=0, *opt_columns=0,
54
*default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
55
static uint opt_drizzle_port= 0, opt_protocol= 0;
56
static char * opt_drizzle_unix_port=0;
62
57
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())
58
static CHARSET_INFO *charset_info= &my_charset_latin1;
60
static struct my_option my_long_options[] =
62
{"character-sets-dir", OPT_CHARSETS_DIR,
63
"Directory where character sets are.", (char**) &charsets_dir,
64
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
65
{"default-character-set", OPT_DEFAULT_CHARSET,
66
"Set the default character set.", (char**) &default_charset,
67
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
69
"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.",
70
(char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
72
{"compress", 'C', "Use compression in server/client protocol.",
73
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
75
{"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
76
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
77
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
78
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
79
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
80
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
81
(char**) &debug_info_flag, (char**) &debug_info_flag,
82
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
83
{"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
84
(char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
85
{"fields-terminated-by", OPT_FTB,
86
"Fields in the textfile are terminated by ...", (char**) &fields_terminated,
87
(char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
88
{"fields-enclosed-by", OPT_ENC,
89
"Fields in the importfile are enclosed by ...", (char**) &enclosed,
90
(char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
91
{"fields-optionally-enclosed-by", OPT_O_ENC,
92
"Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
93
(char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
94
{"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
95
(char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
97
{"force", 'f', "Continue even if we get an sql-error.",
98
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
100
{"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
102
{"host", 'h', "Connect to host.", (char**) ¤t_host,
103
(char**) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
104
{"ignore", 'i', "If duplicate unique key was found, keep old row.",
105
(char**) &ignore, (char**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
106
{"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
107
(char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
108
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
109
{"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
110
(char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
111
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
112
{"local", 'L', "Read all files through the client.", (char**) &opt_local_file,
113
(char**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
114
{"lock-tables", 'l', "Lock all tables for write (this disables threads).",
115
(char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG,
117
{"low-priority", OPT_LOW_PRIORITY,
118
"Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
119
(char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
121
"Password to use when connecting to server. If password is not given it's asked from the tty.",
122
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
123
{"port", 'P', "Port number to use for connection or 0 for default to, in "
124
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
125
#if MYSQL_PORT_DEFAULT == 0
128
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
129
(char**) &opt_drizzle_port,
130
(char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
132
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
133
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
134
{"replace", 'r', "If duplicate unique key was found, replace old row.",
135
(char**) &replace, (char**) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
136
{"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
137
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
138
{"socket", 'S', "Socket file to use for connection.",
139
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
140
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
141
{"use-threads", OPT_USE_THREADS,
142
"Load files in parallel. The argument is the number "
143
"of threads to use for loading data.",
144
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
145
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
146
#ifndef DONT_ALLOW_USER_CHANGE
147
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
148
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
150
{"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
151
(char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
152
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
153
NO_ARG, 0, 0, 0, 0, 0, 0},
154
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
158
static const char *load_default_groups[]= { "drizzleimport","client",0 };
160
#include <help_start.h>
162
static void print_version(void)
164
printf("%s Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
165
IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
169
static void usage(void)
172
puts("Copyright (C) 2008 Drizzle Open Source Development Team");
173
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");
175
Loads tables from text files in various formats. The base name of the\n\
176
text file must be the name of the table that should be used.\n\
177
If one uses sockets to connect to the Drizzle server, the server will open and\n\
178
read the text file directly. In other cases the client will open the text\n\
179
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
181
printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
182
print_defaults("my",load_default_groups);
183
my_print_help(my_long_options);
184
my_print_variables(my_long_options);
187
#include <help_end.h>
190
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
197
char *start=argument;
198
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
199
opt_password=my_strdup(argument,MYF(MY_FAE));
200
while (*argument) *argument++= 'x'; /* Destroy argument */
202
start[1]=0; /* Cut length of argument */
208
case OPT_DRIZZLE_PROTOCOL:
209
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
212
case 'V': print_version(); exit(0);
222
static int get_options(int *argc, char ***argv)
226
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
229
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
230
if (debug_check_flag)
231
my_end_arg= MY_CHECK_ERROR;
233
if (enclosed && opt_enclosed)
83
235
fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
86
if (opt_replace && ignore_unique)
238
if (replace && ignore)
88
fprintf(stderr, "You can't use --ignore_unique (-i) and --replace (-r) at the same time.\n");
240
fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
243
if (strcmp(default_charset, charset_info->csname) &&
244
!(charset_info= get_charset_by_csname(default_charset,
245
MY_CS_PRIMARY, MYF(MY_WME))))
252
current_db= *((*argv)++);
93
opt_password=client_get_tty_password(NULL);
255
opt_password=get_tty_password(NullS);
99
static int write_to_table(char *filename, drizzle_con_st *con)
261
static int write_to_table(char *filename, DRIZZLE *drizzle)
101
263
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
102
264
sql_statement[FN_REFLEN*16+256], *end;
103
drizzle_result_st result;
104
drizzle_return_t ret;
106
internal::fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
107
if (not opt_local_file)
108
strcpy(hard_path,filename);
266
fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
268
strmov(hard_path,filename);
110
internal::my_load_path(hard_path, filename, NULL); /* filename includes the path */
270
my_load_path(hard_path, filename, NULL); /* filename includes the path */
115
275
fprintf(stdout, "Deleting the old data from table %s\n", tablename);
116
276
#ifdef HAVE_SNPRINTF
117
snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
277
snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
119
snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
279
sprintf(sql_statement, "DELETE FROM %s", tablename);
121
if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
122
ret != DRIZZLE_RETURN_OK)
281
if (drizzle_query(drizzle, sql_statement))
124
db_error(con, &result, ret, tablename);
283
db_error_with_table(drizzle, tablename);
127
drizzle_result_free(&result);
287
to_unix_path(hard_path);
131
290
if (opt_local_file)
135
294
fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
136
295
hard_path, tablename);
138
snprintf(sql_statement, sizeof(sql_statement), "LOAD DATA %s %s INFILE '%s'",
297
sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
139
298
opt_low_priority ? "LOW_PRIORITY" : "",
140
299
opt_local_file ? "LOCAL" : "", hard_path);
141
end= strchr(sql_statement, '\0');
143
end= strcpy(end, " REPLACE")+8;
145
end= strcpy(end, " IGNORE")+7;
147
end+= sprintf(end, " INTO TABLE %s", tablename);
149
if (! fields_terminated.empty() || ! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty())
150
end= strcpy(end, " FIELDS")+7;
151
end= add_load_option(end, (char *)fields_terminated.c_str(), " TERMINATED BY");
152
end= add_load_option(end, (char *)enclosed.c_str(), " ENCLOSED BY");
153
end= add_load_option(end, (char *)opt_enclosed.c_str(),
300
end= strend(sql_statement);
302
end= strmov(end, " REPLACE");
304
end= strmov(end, " IGNORE");
305
end= strmov(strmov(end, " INTO TABLE "), tablename);
307
if (fields_terminated || enclosed || opt_enclosed || escaped)
308
end= strmov(end, " FIELDS");
309
end= add_load_option(end, fields_terminated, " TERMINATED BY");
310
end= add_load_option(end, enclosed, " ENCLOSED BY");
311
end= add_load_option(end, opt_enclosed,
154
312
" OPTIONALLY ENCLOSED BY");
155
end= add_load_option(end, (char *)escaped.c_str(), " ESCAPED BY");
156
end= add_load_option(end, (char *)lines_terminated.c_str(), " LINES TERMINATED BY");
313
end= add_load_option(end, escaped, " ESCAPED BY");
314
end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
157
315
if (opt_ignore_lines >= 0)
159
end= strcpy(end, " IGNORE ")+8;
160
ostringstream buffer;
161
buffer << opt_ignore_lines;
162
end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
163
end= strcpy(end, " LINES")+6;
165
if (! opt_columns.empty())
167
end= strcpy(end, " (")+2;
168
end= strcpy(end, (char *)opt_columns.c_str()+opt_columns.length());
169
end= strcpy(end, ")")+1;
316
end= strmov(int64_t10_to_str(opt_ignore_lines,
317
strmov(end, " IGNORE "),10), " LINES");
319
end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
173
if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
174
ret != DRIZZLE_RETURN_OK)
322
if (drizzle_query(drizzle, sql_statement))
176
db_error(con, &result, ret, tablename);
324
db_error_with_table(drizzle, tablename);
181
if (strcmp(drizzle_result_info(&result), ""))
329
if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
183
fprintf(stdout, "%s.%s: %s\n", current_db.c_str(), tablename,
184
drizzle_result_info(&result));
331
fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
332
drizzle_info(drizzle));
187
drizzle_result_free(&result);
192
static drizzle_con_st *db_connect(const string host, const string database,
193
const string user, const string passwd)
197
drizzle_return_t ret;
200
fprintf(stdout, "Connecting to %s, using protocol %s...\n", ! host.empty() ? host.c_str() : "localhost", opt_protocol.c_str());
340
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
342
DYNAMIC_STRING query;
344
char tablename[FN_REFLEN];
347
fprintf(stdout, "Locking tables for write\n");
348
init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
349
for (i=0 ; i < tablecount ; i++)
351
fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
352
dynstr_append(&query, tablename);
353
dynstr_append(&query, " WRITE,");
355
if (drizzle_real_query(drizzle, query.str, query.length-1))
356
db_error(drizzle); /* We shall countinue here, if --force was given */
362
static DRIZZLE *db_connect(char *host, char *database,
363
char *user, char *passwd)
367
fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
201
368
if (!(drizzle= drizzle_create(NULL)))
203
if (!(con= drizzle_con_add_tcp(drizzle,NULL,(char *)host.c_str(),opt_drizzle_port,(char *)user.c_str(),(char *)passwd.c_str(),
204
(char *)database.c_str(), use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL)))
209
if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
371
drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NullS);
373
drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
374
(char*) &opt_local_file);
376
drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
377
if (!(drizzle_connect(drizzle,host,user,passwd,
378
database,opt_drizzle_port,opt_drizzle_unix_port,
211
381
ignore_errors=0; /* NO RETURN FROM db_error */
212
db_error(con, NULL, ret, NULL);
384
drizzle->reconnect= 0;
216
fprintf(stdout, "Selecting database %s\n", database.c_str());
386
fprintf(stdout, "Selecting database %s\n", database);
387
if (drizzle_select_db(drizzle, database))
223
static void db_disconnect(const string host, drizzle_con_st *con)
397
static void db_disconnect(char *host, DRIZZLE *drizzle)
226
fprintf(stdout, "Disconnecting from %s\n", ! host.empty() ? host.c_str() : "localhost");
227
drizzle_free(drizzle_con_drizzle(con));
400
fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
401
drizzle_close(drizzle);
232
static void safe_exit(int error, drizzle_con_st *con)
406
static void safe_exit(int error, DRIZZLE *drizzle)
234
408
if (ignore_errors)
237
drizzle_free(drizzle_con_drizzle(con));
411
drizzle_close(drizzle);
243
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
244
drizzle_return_t ret, char *table)
246
if (ret == DRIZZLE_RETURN_ERROR_CODE)
248
fprintf(stdout, "Error: %d, %s%s%s",
249
drizzle_result_error_code(result),
250
drizzle_result_error(result),
251
table ? ", when using table: " : "", table ? table : "");
252
drizzle_result_free(result);
256
fprintf(stdout, "Error: %d, %s%s%s", ret, drizzle_con_error(con),
257
table ? ", when using table: " : "", table ? table : "");
417
static void db_error_with_table(DRIZZLE *drizzle, char *table)
419
my_printf_error(0,"Error: %d, %s, when using table: %s",
420
MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
421
safe_exit(1, drizzle);
426
static void db_error(DRIZZLE *drizzle)
428
my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
429
safe_exit(1, drizzle);
349
525
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);
531
load_defaults("my",load_default_groups,&argc,&argv);
532
/* argv is changed in the program */
534
if (get_options(&argc, &argv))
536
free_defaults(argv_to_free);
538
current_db= (*argv)++;
540
#ifdef HAVE_LIBPTHREAD
541
if (opt_use_threads && !lock_tables)
543
543
pthread_t mainthread; /* Thread descriptor */
544
544
pthread_attr_t attr; /* Thread attributes */