27
27
#define IMPORT_VERSION "3.7"
29
#include "client_priv.h"
32
#include "client_priv.h"
33
32
#include <pthread.h>
34
/* Added this for string translation. */
35
#include <drizzled/gettext.h>
35
37
using namespace std;
41
bool get_one_option(int optid, const struct my_option *, char *argument);
42
void * worker_thread(void *arg);
37
47
/* Global Thread counter */
39
49
pthread_mutex_t counter_mutex;
40
50
pthread_cond_t count_threshhold;
42
static void db_error_with_table(DRIZZLE *drizzle, char *table);
43
static void db_error(DRIZZLE *drizzle);
44
static char *field_escape(char *to,const char *from,uint length);
52
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
53
drizzle_return_t ret, char *table);
54
static char *field_escape(char *to,const char *from,uint32_t length);
45
55
static char *add_load_option(char *ptr,const char *object,
46
56
const char *statement);
48
static bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
49
opt_replace=0,silent=0,ignore=0,opt_compress=0,
50
opt_low_priority= 0, tty_password= 0;
51
static bool debug_info_flag= 0, debug_check_flag= 0;
52
static uint opt_use_threads=0, opt_local_file=0, my_end_arg= 0;
53
static char *opt_password=0, *current_user=0,
54
*current_host=0, *current_db=0, *fields_terminated=0,
55
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
56
*escaped=0, *opt_columns=0,
57
*default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
58
static uint opt_drizzle_port= 0, opt_protocol= 0;
59
static char * opt_drizzle_unix_port=0;
58
static bool verbose= false, lock_tables= false, ignore_errors= false,
59
opt_delete= false, opt_replace= false, silent= false,
60
ignore_unique= false, opt_compress= false, opt_low_priority= false,
62
static bool debug_info_flag= false, debug_check_flag= false;
63
static uint32_t opt_use_threads= 0, opt_local_file= 0, my_end_arg= 0;
64
static char *opt_password= NULL, *current_user= NULL,
65
*current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
66
*lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
67
*escaped= NULL, *opt_columns= NULL;
68
static uint32_t opt_drizzle_port= 0;
69
static char * opt_drizzle_unix_port= 0;
60
70
static int64_t opt_ignore_lines= -1;
61
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
63
72
static struct my_option my_long_options[] =
65
{"character-sets-dir", OPT_CHARSETS_DIR,
66
"Directory where character sets are.", (char**) &charsets_dir,
67
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
68
{"default-character-set", OPT_DEFAULT_CHARSET,
69
"Set the default character set.", (char**) &default_charset,
70
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
72
75
"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.",
73
76
(char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
105
108
{"host", 'h', "Connect to host.", (char**) ¤t_host,
106
109
(char**) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
107
110
{"ignore", 'i', "If duplicate unique key was found, keep old row.",
108
(char**) &ignore, (char**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
111
(char**) &ignore_unique, (char**) &ignore_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
109
112
{"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
110
113
(char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
111
114
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
120
123
{"low-priority", OPT_LOW_PRIORITY,
121
124
"Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
122
125
(char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
124
127
"Password to use when connecting to server. If password is not given it's asked from the tty.",
125
128
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
126
{"port", 'P', "Port number to use for connection or 0 for default to, in "
129
{"port", 'p', "Port number to use for connection or 0 for default to, in "
127
130
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
128
131
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
129
(char**) &opt_drizzle_port,
130
(char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
132
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
132
133
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
133
134
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
134
135
{"replace", 'r', "If duplicate unique key was found, replace old row.",
143
144
"of threads to use for loading data.",
144
145
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
145
146
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
146
#ifndef DONT_ALLOW_USER_CHANGE
147
147
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
148
148
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
150
149
{"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
151
150
(char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
152
151
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
182
181
my_print_variables(my_long_options);
186
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
184
bool get_one_option(int optid, const struct my_option *, char *argument)
187
uint64_t temp_drizzle_port= 0;
191
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
192
/* if there is an alpha character this is not a valid port */
193
if (strlen(endchar) != 0)
195
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
198
/* If the port number is > 65535 it is not a valid port
199
This also helps with potential data loss casting unsigned long to a
201
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
203
fprintf(stderr, _("Value supplied for port is not valid.\n"));
208
opt_drizzle_port= (uint32_t) temp_drizzle_port;
193
214
char *start=argument;
195
opt_password=my_strdup(argument,MYF(MY_FAE));
196
while (*argument) *argument++= 'x'; /* Destroy argument */
217
opt_password = strdup(argument);
218
if (opt_password == NULL)
220
fprintf(stderr, "Memory allocation error while copying password. "
226
/* Overwriting password with 'x' */
198
start[1]=0; /* Cut length of argument */
231
/* Cut length of argument */
246
277
current_db= *((*argv)++);
248
279
if (tty_password)
249
opt_password=get_tty_password(NULL);
280
opt_password=client_get_tty_password(NULL);
255
static int write_to_table(char *filename, DRIZZLE *drizzle)
286
static int write_to_table(char *filename, drizzle_con_st *con)
257
288
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
258
289
sql_statement[FN_REFLEN*16+256], *end;
290
drizzle_result_st result;
291
drizzle_return_t ret;
260
293
fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
261
294
if (!opt_local_file)
262
my_stpcpy(hard_path,filename);
295
strcpy(hard_path,filename);
264
297
my_load_path(hard_path, filename, NULL); /* filename includes the path */
293
327
opt_local_file ? "LOCAL" : "", hard_path);
294
328
end= strchr(sql_statement, '\0');
296
end= my_stpcpy(end, " REPLACE");
298
end= my_stpcpy(end, " IGNORE");
299
end= my_stpcpy(my_stpcpy(end, " INTO TABLE "), tablename);
330
end= strcpy(end, " REPLACE")+8;
332
end= strcpy(end, " IGNORE")+7;
334
end+= sprintf(end, " INTO TABLE %s", tablename);
301
336
if (fields_terminated || enclosed || opt_enclosed || escaped)
302
end= my_stpcpy(end, " FIELDS");
337
end= strcpy(end, " FIELDS")+7;
303
338
end= add_load_option(end, fields_terminated, " TERMINATED BY");
304
339
end= add_load_option(end, enclosed, " ENCLOSED BY");
305
340
end= add_load_option(end, opt_enclosed,
307
342
end= add_load_option(end, escaped, " ESCAPED BY");
308
343
end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
309
344
if (opt_ignore_lines >= 0)
310
end= my_stpcpy(int64_t10_to_str(opt_ignore_lines,
311
my_stpcpy(end, " IGNORE "),10), " LINES");
346
end= strcpy(end, " IGNORE ")+8;
347
ostringstream buffer;
348
buffer << opt_ignore_lines;
349
end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
350
end= strcpy(end, " LINES")+6;
313
end= my_stpcpy(my_stpcpy(my_stpcpy(end, " ("), opt_columns), ")");
354
end= strcpy(end, " (")+2;
355
end= strcpy(end, opt_columns)+strlen(opt_columns);
356
end= strcpy(end, ")")+1;
316
if (drizzle_query(drizzle, sql_statement))
360
if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
361
ret != DRIZZLE_RETURN_OK)
318
db_error_with_table(drizzle, tablename);
363
db_error(con, &result, ret, tablename);
323
if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
368
if (strcmp(drizzle_result_info(&result), ""))
325
370
fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
326
drizzle_info(drizzle));
371
drizzle_result_info(&result));
374
drizzle_result_free(&result);
334
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
379
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
338
383
char tablename[FN_REFLEN];
384
drizzle_result_st result;
385
drizzle_return_t ret;
341
388
fprintf(stdout, "Locking tables for write\n");
346
393
query.append(tablename);
347
394
query.append(" WRITE,");
349
if (drizzle_real_query(drizzle, query.c_str(), query.length()-1))
350
db_error(drizzle); /* We shall countinue here, if --force was given */
396
if (drizzle_query(con, &result, query.c_str(), query.length()-1,
398
ret != DRIZZLE_RETURN_OK)
400
db_error(con, &result, ret, NULL);
401
/* We shall countinue here, if --force was given */
404
drizzle_result_free(&result);
356
static DRIZZLE *db_connect(char *host, char *database,
357
char *user, char *passwd)
408
static drizzle_con_st *db_connect(char *host, char *database,
409
char *user, char *passwd)
413
drizzle_return_t ret;
361
416
fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
362
417
if (!(drizzle= drizzle_create(NULL)))
365
drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NULL);
367
drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
368
(char*) &opt_local_file);
370
drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
371
if (!(drizzle_connect(drizzle,host,user,passwd,
372
database,opt_drizzle_port,opt_drizzle_unix_port,
419
if (!(con= drizzle_con_add_tcp(drizzle,NULL,host,opt_drizzle_port,user,passwd,
420
database, DRIZZLE_CON_NONE)))
425
if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
375
427
ignore_errors=0; /* NO RETURN FROM db_error */
428
db_error(con, NULL, ret, NULL);
378
drizzle->reconnect= 0;
380
432
fprintf(stdout, "Selecting database %s\n", database);
381
if (drizzle_select_db(drizzle, database))
391
static void db_disconnect(char *host, DRIZZLE *drizzle)
439
static void db_disconnect(char *host, drizzle_con_st *con)
394
442
fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
395
drizzle_close(drizzle);
443
drizzle_free(drizzle_con_drizzle(con));
400
static void safe_exit(int error, DRIZZLE *drizzle)
448
static void safe_exit(int error, drizzle_con_st *con)
402
450
if (ignore_errors)
405
drizzle_close(drizzle);
453
drizzle_free(drizzle_con_drizzle(con));
411
static void db_error_with_table(DRIZZLE *drizzle, char *table)
413
my_printf_error(0,"Error: %d, %s, when using table: %s",
414
MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
415
safe_exit(1, drizzle);
420
static void db_error(DRIZZLE *drizzle)
422
my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
423
safe_exit(1, drizzle);
459
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
460
drizzle_return_t ret, char *table)
462
if (ret == DRIZZLE_RETURN_ERROR_CODE)
464
my_printf_error(0,"Error: %d, %s%s%s", MYF(0),
465
drizzle_result_error_code(result),
466
drizzle_result_error(result),
467
table ? ", when using table: " : "", table ? table : "");
468
drizzle_result_free(result);
472
my_printf_error(0,"Error: %d, %s%s%s", MYF(0), ret, drizzle_con_error(con),
473
table ? ", when using table: " : "", table ? table : "");
432
485
/* Don't escape hex constants */
433
486
if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
434
ptr= strxmov(ptr," ",statement," ",object,NULL);
487
ptr+= sprintf(ptr, " %s %s", statement, object);
437
490
/* char constant; escape */
438
ptr= strxmov(ptr," ",statement," '",NULL);
439
ptr= field_escape(ptr,object,(uint) strlen(object));
491
ptr+= sprintf(ptr, " %s '", statement);
492
ptr= field_escape(ptr,object,(uint32_t) strlen(object));
470
523
/* Add missing backslashes if user has specified odd number of backs.*/
471
524
if (end_backslashes)
478
static void * worker_thread(void *arg)
529
void * worker_thread(void *arg)
481
532
char *raw_table_name= (char *)arg;
533
drizzle_con_st *con= NULL;
534
drizzle_result_st result;
535
drizzle_return_t ret;
484
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
537
if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
489
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
542
if (drizzle_query_str(con, &result,
543
"/*!40101 set @@character_set_database=binary */;",
545
ret != DRIZZLE_RETURN_OK)
491
db_error(drizzle); /* We shall countinue here, if --force was given */
547
db_error(con, &result, ret, NULL);
548
/* We shall countinue here, if --force was given */
496
553
We are not currently catching the error here.
498
if((error= write_to_table(raw_table_name, drizzle)))
555
if((error= write_to_table(raw_table_name, con)))
499
556
if (exitcode == 0)
504
db_disconnect(current_host, drizzle);
561
db_disconnect(current_host, con);
506
563
pthread_mutex_lock(&counter_mutex);
588
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
644
drizzle_con_st *con= 0;
645
drizzle_result_st result;
646
drizzle_return_t ret;
647
if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
590
649
free_defaults(argv_to_free);
591
return(1); /* purecov: deadcode */
594
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
653
if (drizzle_query_str(con, &result,
654
"/*!40101 set @@character_set_database=binary */;",
656
ret != DRIZZLE_RETURN_OK)
596
db_error(drizzle); /* We shall countinue here, if --force was given */
658
db_error(con, &result, ret, NULL);
659
/* We shall countinue here, if --force was given */
663
drizzle_result_free(&result);
601
lock_table(drizzle, argc, argv);
666
lock_table(con, argc, argv);
602
667
for (; *argv != NULL; argv++)
603
if ((error= write_to_table(*argv, drizzle)))
668
if ((error= write_to_table(*argv, con)))
604
669
if (exitcode == 0)
606
db_disconnect(current_host, drizzle);
671
db_disconnect(current_host, con);
608
673
free(opt_password);
609
674
free_defaults(argv_to_free);