37
35
#include <drizzled/gettext.h>
39
37
using namespace std;
40
using namespace drizzled;
42
extern "C" void * worker_thread(void *arg);
46
39
/* Global Thread counter */
48
41
pthread_mutex_t counter_mutex;
49
42
pthread_cond_t count_threshhold;
51
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
52
drizzle_return_t ret, char *table);
53
static char *field_escape(char *to,const char *from,uint32_t length);
44
static void db_error_with_table(DRIZZLE *drizzle, char *table);
45
static void db_error(DRIZZLE *drizzle);
46
static char *field_escape(char *to,const char *from,uint length);
54
47
static char *add_load_option(char *ptr,const char *object,
55
48
const char *statement);
57
50
static bool verbose= false, lock_tables= false, ignore_errors= false,
58
51
opt_delete= false, opt_replace= false, silent= false,
59
ignore_unique= false, opt_low_priority= false,
60
tty_password= false, opt_mysql= false;
62
static uint32_t opt_use_threads= 0, opt_local_file= 0;
52
ignore= false, opt_compress= false, opt_low_priority= false,
54
static bool debug_info_flag= false, debug_check_flag= false;
55
static uint opt_use_threads= 0, opt_local_file= 0, my_end_arg= 0;
63
56
static char *opt_password= NULL, *current_user= NULL,
64
57
*current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
65
58
*lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
66
*escaped= NULL, *opt_columns= NULL;
59
*escaped= NULL, *opt_columns= NULL,
60
*default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
61
static uint opt_protocol= 0;
67
62
static uint32_t opt_drizzle_port= 0;
63
static char * opt_drizzle_unix_port= 0;
68
64
static int64_t opt_ignore_lines= -1;
65
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
70
static struct option my_long_options[] =
67
static struct my_option my_long_options[] =
69
{"character-sets-dir", OPT_CHARSETS_DIR,
70
"Directory where character sets are.", (char**) &charsets_dir,
71
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
72
{"default-character-set", OPT_DEFAULT_CHARSET,
73
"Set the default character set.", (char**) &default_charset,
74
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
73
76
"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
77
(char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
79
{"compress", 'C', "Use compression in server/client protocol.",
80
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
76
82
{"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
77
83
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
84
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
85
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
86
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
87
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
88
(char**) &debug_info_flag, (char**) &debug_info_flag,
89
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
78
90
{"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
79
91
(char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
80
92
{"fields-terminated-by", OPT_FTB,
97
109
{"host", 'h', "Connect to host.", (char**) ¤t_host,
98
110
(char**) ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
99
111
{"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},
112
(char**) &ignore, (char**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
101
113
{"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
102
114
(char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
103
115
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
112
124
{"low-priority", OPT_LOW_PRIORITY,
113
125
"Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
114
126
(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,
118
127
{"password", 'P',
119
128
"Password to use when connecting to server. If password is not given it's asked from the tty.",
120
129
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
128
137
(char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
129
138
{"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
130
139
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
140
{"socket", 'S', "Socket file to use for connection.",
141
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
142
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
131
143
{"use-threads", OPT_USE_THREADS,
132
144
"Load files in parallel. The argument is the number "
133
145
"of threads to use for loading data.",
134
146
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
135
147
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
148
#ifndef DONT_ALLOW_USER_CHANGE
136
149
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
137
150
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
138
152
{"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
139
153
(char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
140
154
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
262
285
current_db= *((*argv)++);
264
287
if (tty_password)
265
opt_password=client_get_tty_password(NULL);
288
opt_password=get_tty_password(NULL);
271
static int write_to_table(char *filename, drizzle_con_st *con)
294
static int write_to_table(char *filename, DRIZZLE *drizzle)
273
296
char tablename[FN_REFLEN], hard_path[FN_REFLEN],
274
297
sql_statement[FN_REFLEN*16+256], *end;
275
drizzle_result_st result;
276
drizzle_return_t ret;
278
internal::fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
299
fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
279
300
if (!opt_local_file)
280
301
strcpy(hard_path,filename);
282
internal::my_load_path(hard_path, filename, NULL); /* filename includes the path */
303
my_load_path(hard_path, filename, NULL); /* filename includes the path */
287
308
fprintf(stdout, "Deleting the old data from table %s\n", tablename);
288
309
#ifdef HAVE_SNPRINTF
289
snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
310
snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
291
snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
312
sprintf(sql_statement, "DELETE FROM %s", tablename);
293
if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
294
ret != DRIZZLE_RETURN_OK)
314
if (drizzle_query(drizzle, sql_statement))
296
db_error(con, &result, ret, tablename);
316
db_error_with_table(drizzle, tablename);
299
drizzle_result_free(&result);
345
if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
346
ret != DRIZZLE_RETURN_OK)
362
if (drizzle_query(drizzle, sql_statement))
348
db_error(con, &result, ret, tablename);
364
db_error_with_table(drizzle, tablename);
353
if (strcmp(drizzle_result_info(&result), ""))
369
if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
355
371
fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
356
drizzle_result_info(&result));
372
drizzle_info(drizzle));
359
drizzle_result_free(&result);
364
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
380
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
368
384
char tablename[FN_REFLEN];
369
drizzle_result_st result;
370
drizzle_return_t ret;
373
387
fprintf(stdout, "Locking tables for write\n");
374
388
query.append("LOCK TABLES ");
375
389
for (i=0 ; i < tablecount ; i++)
377
internal::fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
391
fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
378
392
query.append(tablename);
379
393
query.append(" WRITE,");
381
if (drizzle_query(con, &result, query.c_str(), query.length()-1,
383
ret != DRIZZLE_RETURN_OK)
385
db_error(con, &result, ret, NULL);
386
/* We shall countinue here, if --force was given */
389
drizzle_result_free(&result);
395
if (drizzle_real_query(drizzle, query.c_str(), query.length()-1))
396
db_error(drizzle); /* We shall countinue here, if --force was given */
393
static drizzle_con_st *db_connect(char *host, char *database,
394
char *user, char *passwd)
402
static DRIZZLE *db_connect(char *host, char *database,
403
char *user, char *passwd)
398
drizzle_return_t ret;
401
407
fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
402
408
if (!(drizzle= drizzle_create(NULL)))
404
if (!(con= drizzle_con_add_tcp(drizzle,NULL,host,opt_drizzle_port,user,passwd,
405
database, opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE)))
410
if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
411
drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NULL);
413
drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
414
(char*) &opt_local_file);
416
drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
417
if (!(drizzle_connect(drizzle,host,user,passwd,
418
database,opt_drizzle_port,opt_drizzle_unix_port,
412
421
ignore_errors=0; /* NO RETURN FROM db_error */
413
db_error(con, NULL, ret, NULL);
424
drizzle->reconnect= 0;
417
426
fprintf(stdout, "Selecting database %s\n", database);
427
if (drizzle_select_db(drizzle, database))
424
static void db_disconnect(char *host, drizzle_con_st *con)
437
static void db_disconnect(char *host, DRIZZLE *drizzle)
427
440
fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
428
drizzle_free(drizzle_con_drizzle(con));
441
drizzle_close(drizzle);
433
static void safe_exit(int error, drizzle_con_st *con)
446
static void safe_exit(int error, DRIZZLE *drizzle)
435
448
if (ignore_errors)
438
drizzle_free(drizzle_con_drizzle(con));
451
drizzle_close(drizzle);
444
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
445
drizzle_return_t ret, char *table)
447
if (ret == DRIZZLE_RETURN_ERROR_CODE)
449
my_printf_error(0,"Error: %d, %s%s%s", MYF(0),
450
drizzle_result_error_code(result),
451
drizzle_result_error(result),
452
table ? ", when using table: " : "", table ? table : "");
453
drizzle_result_free(result);
457
my_printf_error(0,"Error: %d, %s%s%s", MYF(0), ret, drizzle_con_error(con),
458
table ? ", when using table: " : "", table ? table : "");
457
static void db_error_with_table(DRIZZLE *drizzle, char *table)
459
my_printf_error(0,"Error: %d, %s, when using table: %s",
460
MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
461
safe_exit(1, drizzle);
466
static void db_error(DRIZZLE *drizzle)
468
my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
469
safe_exit(1, drizzle);
514
525
void * worker_thread(void *arg)
517
528
char *raw_table_name= (char *)arg;
518
drizzle_con_st *con= NULL;
519
drizzle_result_st result;
520
drizzle_return_t ret;
522
if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
531
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
527
if (drizzle_query_str(con, &result,
528
"/*!40101 set @@character_set_database=binary */;",
530
ret != DRIZZLE_RETURN_OK)
536
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
532
db_error(con, &result, ret, NULL);
533
/* We shall countinue here, if --force was given */
538
db_error(drizzle); /* We shall countinue here, if --force was given */
538
543
We are not currently catching the error here.
540
if((error= write_to_table(raw_table_name, con)))
545
if((error= write_to_table(raw_table_name, drizzle)))
541
546
if (exitcode == 0)
546
db_disconnect(current_host, con);
551
db_disconnect(current_host, drizzle);
548
553
pthread_mutex_lock(&counter_mutex);
550
555
pthread_cond_signal(&count_threshhold);
551
556
pthread_mutex_unlock(&counter_mutex);
552
internal::my_thread_end();
629
drizzle_con_st *con= 0;
630
drizzle_result_st result;
631
drizzle_return_t ret;
632
if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
634
internal::free_defaults(argv_to_free);
638
if (drizzle_query_str(con, &result,
639
"/*!40101 set @@character_set_database=binary */;",
641
ret != DRIZZLE_RETURN_OK)
643
db_error(con, &result, ret, NULL);
644
/* We shall countinue here, if --force was given */
648
drizzle_result_free(&result);
635
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
637
free_defaults(argv_to_free);
638
return(1); /* purecov: deadcode */
641
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
643
db_error(drizzle); /* We shall countinue here, if --force was given */
651
lock_table(con, argc, argv);
648
lock_table(drizzle, argc, argv);
652
649
for (; *argv != NULL; argv++)
653
if ((error= write_to_table(*argv, con)))
650
if ((error= write_to_table(*argv, drizzle)))
654
651
if (exitcode == 0)
656
db_disconnect(current_host, con);
653
db_disconnect(current_host, drizzle);
658
655
free(opt_password);
659
internal::free_defaults(argv_to_free);
656
free_defaults(argv_to_free);
661
658
return(exitcode);