14
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
** drizzleimport.c - Imports all given files
17
** mysqlimport.c - Imports all given files
20
** *************************
22
** * AUTHOR: Monty & Jani *
23
** * DATE: June 24, 1997 *
25
** *************************
20
** *************************
22
** * AUTHOR: Monty & Jani *
23
** * DATE: June 24, 1997 *
25
** *************************
27
27
#define IMPORT_VERSION "3.7"
32
29
#include "client_priv.h"
30
#include "drizzle_version.h"
31
#ifdef HAVE_LIBPTHREAD
32
#include <my_pthread.h>
37
36
/* Global Thread counter */
38
#ifdef HAVE_LIBPTHREAD
39
39
pthread_mutex_t counter_mutex;
40
40
pthread_cond_t count_threshhold;
42
static void db_error_with_table(DRIZZLE *drizzle, char *table);
43
static void db_error(DRIZZLE *drizzle);
43
static void db_error_with_table(MYSQL *mysql, char *table);
44
static void db_error(MYSQL *mysql);
44
45
static char *field_escape(char *to,const char *from,uint length);
45
46
static char *add_load_option(char *ptr,const char *object,
46
const char *statement);
47
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;
49
static my_bool verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
50
replace=0,silent=0,ignore=0,opt_compress=0,
51
opt_low_priority= 0, tty_password= 0;
52
static my_bool debug_info_flag= 0, debug_check_flag= 0;
52
53
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;
60
static int64_t opt_ignore_lines= -1;
61
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
54
static char *opt_password=0, *current_user=0,
55
*current_host=0, *current_db=0, *fields_terminated=0,
56
*lines_terminated=0, *enclosed=0, *opt_enclosed=0,
57
*escaped=0, *opt_columns=0,
58
*default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
59
static uint opt_mysql_port= 0, opt_protocol= 0;
60
static char * opt_mysql_unix_port=0;
61
static longlong opt_ignore_lines= -1;
62
static CHARSET_INFO *charset_info= &my_charset_latin1;
65
static char *shared_memory_base_name=0;
63
68
static struct my_option my_long_options[] =
124
129
"Password to use when connecting to server. If password is not given it's asked from the tty.",
125
130
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
126
131
{"port", 'P', "Port number to use for connection or 0 for default to, in "
127
"order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
128
"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
"order of preference, my.cnf, $MYSQL_TCP_PORT, "
133
#if MYSQL_PORT_DEFAULT == 0
136
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
137
(char**) &opt_mysql_port,
138
(char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
132
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
140
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
133
141
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
134
142
{"replace", 'r', "If duplicate unique key was found, replace old row.",
135
(char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
143
(char**) &replace, (char**) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
145
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
146
"Base name of shared memory.", (char**) &shared_memory_base_name, (char**) &shared_memory_base_name,
147
0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
136
149
{"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
137
150
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
138
151
{"socket", 'S', "Socket file to use for connection.",
139
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
152
(char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
140
153
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
141
154
{"use-threads", OPT_USE_THREADS,
142
155
"Load files in parallel. The argument is the number "
143
156
"of threads to use for loading data.",
144
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
157
(char**) &opt_use_threads, (char**) &opt_use_threads, 0,
145
158
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
146
159
#ifndef DONT_ALLOW_USER_CHANGE
147
160
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
284
309
if (opt_local_file)
285
310
fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
286
hard_path, tablename);
311
hard_path, tablename);
288
313
fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
289
hard_path, tablename);
314
hard_path, tablename);
291
316
sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
292
opt_low_priority ? "LOW_PRIORITY" : "",
293
opt_local_file ? "LOCAL" : "", hard_path);
294
end= strchr(sql_statement, '\0');
296
end= my_stpcpy(end, " REPLACE");
317
opt_low_priority ? "LOW_PRIORITY" : "",
318
opt_local_file ? "LOCAL" : "", hard_path);
319
end= strend(sql_statement);
321
end= strmov(end, " REPLACE");
298
end= my_stpcpy(end, " IGNORE");
299
end= my_stpcpy(my_stpcpy(end, " INTO TABLE "), tablename);
323
end= strmov(end, " IGNORE");
324
end= strmov(strmov(end, " INTO TABLE "), tablename);
301
326
if (fields_terminated || enclosed || opt_enclosed || escaped)
302
end= my_stpcpy(end, " FIELDS");
327
end= strmov(end, " FIELDS");
303
328
end= add_load_option(end, fields_terminated, " TERMINATED BY");
304
329
end= add_load_option(end, enclosed, " ENCLOSED BY");
305
330
end= add_load_option(end, opt_enclosed,
306
" OPTIONALLY ENCLOSED BY");
331
" OPTIONALLY ENCLOSED BY");
307
332
end= add_load_option(end, escaped, " ESCAPED BY");
308
333
end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
309
334
if (opt_ignore_lines >= 0)
310
end= my_stpcpy(int64_t10_to_str(opt_ignore_lines,
311
my_stpcpy(end, " IGNORE "),10), " LINES");
335
end= strmov(longlong10_to_str(opt_ignore_lines,
336
strmov(end, " IGNORE "),10), " LINES");
313
end= my_stpcpy(my_stpcpy(my_stpcpy(end, " ("), opt_columns), ")");
338
end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
316
if (drizzle_query(drizzle, sql_statement))
341
if (mysql_query(mysql, sql_statement))
318
db_error_with_table(drizzle, tablename);
343
db_error_with_table(mysql, tablename);
323
if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
348
if (mysql_info(mysql)) /* If NULL-pointer, print nothing */
325
350
fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
326
drizzle_info(drizzle));
334
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
359
static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
361
DYNAMIC_STRING query;
338
363
char tablename[FN_REFLEN];
341
366
fprintf(stdout, "Locking tables for write\n");
342
query.append("LOCK TABLES ");
367
init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
343
368
for (i=0 ; i < tablecount ; i++)
345
370
fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
346
query.append(tablename);
347
query.append(" WRITE,");
371
dynstr_append(&query, tablename);
372
dynstr_append(&query, " 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 */
374
if (mysql_real_query(mysql, query.str, query.length-1))
375
db_error(mysql); /* We shall countinue here, if --force was given */
356
static DRIZZLE *db_connect(char *host, char *database,
381
static MYSQL *db_connect(char *host, char *database,
357
382
char *user, char *passwd)
361
386
fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
362
if (!(drizzle= drizzle_create(NULL)))
387
if (!(mysql= mysql_init(NULL)))
364
389
if (opt_compress)
365
drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NULL);
390
mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
366
391
if (opt_local_file)
367
drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
368
(char*) &opt_local_file);
392
mysql_options(mysql,MYSQL_OPT_LOCAL_INFILE,
393
(char*) &opt_local_file);
369
394
if (opt_protocol)
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,
395
mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
397
if (shared_memory_base_name)
398
mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
400
if (!(mysql_real_connect(mysql,host,user,passwd,
401
database,opt_mysql_port,opt_mysql_unix_port,
375
ignore_errors=0; /* NO RETURN FROM db_error */
404
ignore_errors=0; /* NO RETURN FROM db_error */
378
drizzle->reconnect= 0;
380
409
fprintf(stdout, "Selecting database %s\n", database);
381
if (drizzle_select_db(drizzle, database))
410
if (mysql_select_db(mysql, database))
391
static void db_disconnect(char *host, DRIZZLE *drizzle)
420
static void db_disconnect(char *host, MYSQL *mysql)
394
423
fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
395
drizzle_close(drizzle);
400
static void safe_exit(int error, DRIZZLE *drizzle)
429
static void safe_exit(int error, MYSQL *mysql)
402
431
if (ignore_errors)
405
drizzle_close(drizzle);
411
static void db_error_with_table(DRIZZLE *drizzle, char *table)
440
static void db_error_with_table(MYSQL *mysql, char *table)
413
442
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);
443
MYF(0), mysql_errno(mysql), mysql_error(mysql), table);
420
static void db_error(DRIZZLE *drizzle)
449
static void db_error(MYSQL *mysql)
422
my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
423
safe_exit(1, drizzle);
451
my_printf_error(0,"Error: %d %s", MYF(0), mysql_errno(mysql), mysql_error(mysql));
427
456
static char *add_load_option(char *ptr, const char *object,
428
const char *statement)
457
const char *statement)
432
461
/* Don't escape hex constants */
433
462
if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
434
ptr= strxmov(ptr," ",statement," ",object,NULL);
463
ptr= strxmov(ptr," ",statement," ",object,NullS);
437
466
/* char constant; escape */
438
ptr= strxmov(ptr," ",statement," '",NULL);
467
ptr= strxmov(ptr," ",statement," '",NullS);
439
468
ptr= field_escape(ptr,object,(uint) strlen(object));
448
477
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
449
478
** This is done by doubleing ' and add a end -\ if needed to avoid
450
479
** syntax errors from the SQL parser.
453
482
static char *field_escape(char *to,const char *from,uint length)
456
uint end_backslashes=0;
485
uint end_backslashes=0;
458
487
for (end= from+length; from != end; from++)
461
490
if (*from == '\\')
462
491
end_backslashes^=1; /* find odd number of backslashes */
465
494
if (*from == '\'' && !end_backslashes)
466
*to++= *from; /* We want a dublicate of "'" for DRIZZLE */
495
*to++= *from; /* We want a dublicate of "'" for MySQL */
467
496
end_backslashes=0;
470
499
/* Add missing backslashes if user has specified odd number of backs.*/
471
500
if (end_backslashes)
478
static void * worker_thread(void *arg)
507
#ifdef HAVE_LIBPTHREAD
508
static pthread_handler_t worker_thread(void *arg)
481
511
char *raw_table_name= (char *)arg;
484
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
514
if (mysql_thread_init())
517
if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
489
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
522
if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
491
db_error(drizzle); /* We shall countinue here, if --force was given */
524
db_error(mysql); /* We shall countinue here, if --force was given */
496
529
We are not currently catching the error here.
498
if((error= write_to_table(raw_table_name, drizzle)))
531
if((error= write_to_table(raw_table_name, mysql)))
499
532
if (exitcode == 0)
504
db_disconnect(current_host, drizzle);
537
db_disconnect(current_host, mysql);
506
539
pthread_mutex_lock(&counter_mutex);
577
611
pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
579
613
pthread_mutex_unlock(&counter_mutex);
580
pthread_mutex_destroy(&counter_mutex);
581
pthread_cond_destroy(&count_threshhold);
614
VOID(pthread_mutex_destroy(&counter_mutex));
615
VOID(pthread_cond_destroy(&count_threshhold));
582
616
pthread_attr_destroy(&attr);
588
if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
622
if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
590
624
free_defaults(argv_to_free);
591
625
return(1); /* purecov: deadcode */
594
if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
628
if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
596
db_error(drizzle); /* We shall countinue here, if --force was given */
630
db_error(mysql); /* We shall countinue here, if --force was given */
601
lock_table(drizzle, argc, argv);
635
lock_table(mysql, argc, argv);
602
636
for (; *argv != NULL; argv++)
603
if ((error= write_to_table(*argv, drizzle)))
637
if ((error= write_to_table(*argv, mysql)))
604
638
if (exitcode == 0)
606
db_disconnect(current_host, drizzle);
640
db_disconnect(current_host, mysql);
642
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
644
my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
609
646
free_defaults(argv_to_free);
610
647
my_end(my_end_arg);
611
648
return(exitcode);