27
28
#define IMPORT_VERSION "3.7"
29
30
#include "client_priv.h"
30
#include "drizzle_version.h"
31
#include <my_pthread.h>
36
/* Added this for string translation. */
37
#include <drizzled/gettext.h>
43
bool get_one_option(int optid, const struct my_option *, char *argument);
44
void * worker_thread(void *arg);
34
49
/* Global Thread counter */
36
51
pthread_mutex_t counter_mutex;
37
52
pthread_cond_t count_threshhold;
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);
54
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
55
drizzle_return_t ret, char *table);
56
static char *field_escape(char *to,const char *from,uint32_t length);
42
57
static char *add_load_option(char *ptr,const char *object,
43
58
const char *statement);
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;
60
static bool verbose= false, lock_tables= false, ignore_errors= false,
61
opt_delete= false, opt_replace= false, silent= false,
62
ignore_unique= false, opt_low_priority= false,
65
static uint32_t opt_use_threads= 0, opt_local_file= 0;
66
static char *opt_password= NULL, *current_user= NULL,
67
*current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
68
*lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
69
*escaped= NULL, *opt_columns= NULL;
70
static uint32_t opt_drizzle_port= 0;
71
static char * opt_drizzle_unix_port= 0;
57
72
static int64_t opt_ignore_lines= -1;
58
static CHARSET_INFO *charset_info= &my_charset_latin1;
60
74
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
77
"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
78
(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
80
{"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
76
81
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
82
{"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
84
83
(char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
85
84
{"fields-terminated-by", OPT_FTB,
102
101
{"host", 'h', "Connect to host.", (char**) ¤t_host,
103
102
(char**) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
104
103
{"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},
104
(char**) &ignore_unique, (char**) &ignore_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
106
105
{"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
107
106
(char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
108
107
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
117
116
{"low-priority", OPT_LOW_PRIORITY,
118
117
"Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
119
118
(char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
121
120
"Password to use when connecting to server. If password is not given it's asked from the tty.",
122
121
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,
122
{"port", 'p', "Port number to use for connection or 0 for default to, in "
123
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
124
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
125
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
132
126
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
133
127
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
134
128
{"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},
129
(char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
136
130
{"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
137
131
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
138
132
{"socket", 'S', "Socket file to use for connection.",
143
137
"of threads to use for loading data.",
144
138
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
145
139
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
146
#ifndef DONT_ALLOW_USER_CHANGE
147
140
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
148
141
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
150
142
{"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
151
143
(char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
152
144
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
177
169
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
179
171
printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
180
print_defaults("my",load_default_groups);
172
print_defaults("drizzle",load_default_groups);
181
173
my_print_help(my_long_options);
182
174
my_print_variables(my_long_options);
186
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
177
bool get_one_option(int optid, const struct my_option *, char *argument)
180
uint64_t temp_drizzle_port= 0;
184
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
185
/* if there is an alpha character this is not a valid port */
186
if (strlen(endchar) != 0)
188
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
191
/* If the port number is > 65535 it is not a valid port
192
This also helps with potential data loss casting unsigned long to a
194
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
196
fprintf(stderr, _("Value supplied for port is not valid.\n"));
201
opt_drizzle_port= (uint32_t) temp_drizzle_port;
193
207
char *start=argument;
194
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
195
opt_password=my_strdup(argument,MYF(MY_FAE));
196
while (*argument) *argument++= 'x'; /* Destroy argument */
210
opt_password = strdup(argument);
211
if (opt_password == NULL)
213
fprintf(stderr, "Memory allocation error while copying password. "
219
/* Overwriting password with 'x' */
198
start[1]=0; /* Cut length of argument */
224
/* Cut length of argument */
204
232
case OPT_DRIZZLE_PROTOCOL:
205
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
208
234
case 'V': print_version(); exit(0);
293
314
sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
294
315
opt_low_priority ? "LOW_PRIORITY" : "",
295
316
opt_local_file ? "LOCAL" : "", hard_path);
296
end= strend(sql_statement);
298
end= strmov(end, " REPLACE");
300
end= strmov(end, " IGNORE");
301
end= strmov(strmov(end, " INTO TABLE "), tablename);
317
end= strchr(sql_statement, '\0');
319
end= strcpy(end, " REPLACE")+8;
321
end= strcpy(end, " IGNORE")+7;
323
end+= sprintf(end, " INTO TABLE %s", tablename);
303
325
if (fields_terminated || enclosed || opt_enclosed || escaped)
304
end= strmov(end, " FIELDS");
326
end= strcpy(end, " FIELDS")+7;
305
327
end= add_load_option(end, fields_terminated, " TERMINATED BY");
306
328
end= add_load_option(end, enclosed, " ENCLOSED BY");
307
329
end= add_load_option(end, opt_enclosed,
309
331
end= add_load_option(end, escaped, " ESCAPED BY");
310
332
end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
311
333
if (opt_ignore_lines >= 0)
312
end= strmov(int64_t10_to_str(opt_ignore_lines,
313
strmov(end, " IGNORE "),10), " LINES");
335
end= strcpy(end, " IGNORE ")+8;
336
ostringstream buffer;
337
buffer << opt_ignore_lines;
338
end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
339
end= strcpy(end, " LINES")+6;
315
end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
343
end= strcpy(end, " (")+2;
344
end= strcpy(end, opt_columns)+strlen(opt_columns);
345
end= strcpy(end, ")")+1;
318
if (drizzle_query(drizzle, sql_statement))
349
if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
350
ret != DRIZZLE_RETURN_OK)
320
db_error_with_table(drizzle, tablename);
352
db_error(con, &result, ret, tablename);
325
if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
357
if (strcmp(drizzle_result_info(&result), ""))
327
359
fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
328
drizzle_info(drizzle));
360
drizzle_result_info(&result));
363
drizzle_result_free(&result);
336
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
368
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
338
DYNAMIC_STRING query;
340
372
char tablename[FN_REFLEN];
373
drizzle_result_st result;
374
drizzle_return_t ret;
343
377
fprintf(stdout, "Locking tables for write\n");
344
init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
378
query.append("LOCK TABLES ");
345
379
for (i=0 ; i < tablecount ; i++)
347
381
fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
348
dynstr_append(&query, tablename);
349
dynstr_append(&query, " WRITE,");
351
if (drizzle_real_query(drizzle, query.str, query.length-1))
352
db_error(drizzle); /* We shall countinue here, if --force was given */
382
query.append(tablename);
383
query.append(" WRITE,");
385
if (drizzle_query(con, &result, query.c_str(), query.length()-1,
387
ret != DRIZZLE_RETURN_OK)
389
db_error(con, &result, ret, NULL);
390
/* We shall countinue here, if --force was given */
393
drizzle_result_free(&result);
358
static DRIZZLE *db_connect(char *host, char *database,
359
char *user, char *passwd)
397
static drizzle_con_st *db_connect(char *host, char *database,
398
char *user, char *passwd)
402
drizzle_return_t ret;
363
405
fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
364
406
if (!(drizzle= drizzle_create(NULL)))
367
drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NullS);
369
drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
370
(char*) &opt_local_file);
372
drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
373
if (!(drizzle_connect(drizzle,host,user,passwd,
374
database,opt_drizzle_port,opt_drizzle_unix_port,
408
if (!(con= drizzle_con_add_tcp(drizzle,NULL,host,opt_drizzle_port,user,passwd,
409
database, DRIZZLE_CON_NONE)))
414
if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
377
416
ignore_errors=0; /* NO RETURN FROM db_error */
417
db_error(con, NULL, ret, NULL);
380
drizzle->reconnect= 0;
382
421
fprintf(stdout, "Selecting database %s\n", database);
383
if (drizzle_select_db(drizzle, database))
393
static void db_disconnect(char *host, DRIZZLE *drizzle)
428
static void db_disconnect(char *host, drizzle_con_st *con)
396
431
fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
397
drizzle_close(drizzle);
432
drizzle_free(drizzle_con_drizzle(con));
402
static void safe_exit(int error, DRIZZLE *drizzle)
437
static void safe_exit(int error, drizzle_con_st *con)
404
439
if (ignore_errors)
407
drizzle_close(drizzle);
442
drizzle_free(drizzle_con_drizzle(con));
413
static void db_error_with_table(DRIZZLE *drizzle, char *table)
415
my_printf_error(0,"Error: %d, %s, when using table: %s",
416
MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
417
safe_exit(1, drizzle);
422
static void db_error(DRIZZLE *drizzle)
424
my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
425
safe_exit(1, drizzle);
448
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
449
drizzle_return_t ret, char *table)
451
if (ret == DRIZZLE_RETURN_ERROR_CODE)
453
my_printf_error(0,"Error: %d, %s%s%s", MYF(0),
454
drizzle_result_error_code(result),
455
drizzle_result_error(result),
456
table ? ", when using table: " : "", table ? table : "");
457
drizzle_result_free(result);
461
my_printf_error(0,"Error: %d, %s%s%s", MYF(0), ret, drizzle_con_error(con),
462
table ? ", when using table: " : "", table ? table : "");
472
512
/* Add missing backslashes if user has specified odd number of backs.*/
473
513
if (end_backslashes)
480
static pthread_handler_t worker_thread(void *arg)
518
void * worker_thread(void *arg)
483
521
char *raw_table_name= (char *)arg;
522
drizzle_con_st *con= NULL;
523
drizzle_result_st result;
524
drizzle_return_t ret;
486
if (drizzle_thread_init())
489
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
526
if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
494
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
531
if (drizzle_query_str(con, &result,
532
"/*!40101 set @@character_set_database=binary */;",
534
ret != DRIZZLE_RETURN_OK)
496
db_error(drizzle); /* We shall countinue here, if --force was given */
536
db_error(con, &result, ret, NULL);
537
/* We shall countinue here, if --force was given */
501
542
We are not currently catching the error here.
503
if((error= write_to_table(raw_table_name, drizzle)))
544
if((error= write_to_table(raw_table_name, con)))
504
545
if (exitcode == 0)
509
db_disconnect(current_host, drizzle);
550
db_disconnect(current_host, con);
511
552
pthread_mutex_lock(&counter_mutex);
582
623
pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
584
625
pthread_mutex_unlock(&counter_mutex);
585
VOID(pthread_mutex_destroy(&counter_mutex));
586
VOID(pthread_cond_destroy(&count_threshhold));
626
pthread_mutex_destroy(&counter_mutex);
627
pthread_cond_destroy(&count_threshhold);
587
628
pthread_attr_destroy(&attr);
593
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
633
drizzle_con_st *con= 0;
634
drizzle_result_st result;
635
drizzle_return_t ret;
636
if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
595
638
free_defaults(argv_to_free);
596
return(1); /* purecov: deadcode */
599
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
642
if (drizzle_query_str(con, &result,
643
"/*!40101 set @@character_set_database=binary */;",
645
ret != DRIZZLE_RETURN_OK)
601
db_error(drizzle); /* We shall countinue here, if --force was given */
647
db_error(con, &result, ret, NULL);
648
/* We shall countinue here, if --force was given */
652
drizzle_result_free(&result);
606
lock_table(drizzle, argc, argv);
655
lock_table(con, argc, argv);
607
656
for (; *argv != NULL; argv++)
608
if ((error= write_to_table(*argv, drizzle)))
657
if ((error= write_to_table(*argv, con)))
609
658
if (exitcode == 0)
611
db_disconnect(current_host, drizzle);
660
db_disconnect(current_host, con);
613
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
614
663
free_defaults(argv_to_free);
616
665
return(exitcode);