23 #define IMPORT_VERSION "3.7"
25 #include "client_priv.h"
26 #include "my_default.h"
27 #include "mysql_version.h"
28 #ifdef HAVE_LIBPTHREAD
29 #include <my_pthread.h>
32 #include <welcome_copyright_notice.h>
37 #ifdef HAVE_LIBPTHREAD
38 pthread_mutex_t counter_mutex;
39 pthread_cond_t count_threshhold;
42 static void db_error_with_table(
MYSQL *mysql,
char *
table);
43 static void db_error(
MYSQL *mysql);
44 static char *field_escape(
char *
to,
const char *from,uint length);
45 static char *add_load_option(
char *ptr,
const char *
object,
48 static my_bool verbose=0,
lock_tables=0,ignore_errors=0,opt_delete=0,
49 replace=0,silent=0,ignore=0,opt_compress=0,
50 opt_low_priority= 0, tty_password= 0;
51 static my_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*) MYSQL_AUTODETECT_CHARSET_NAME;
58 static uint opt_mysql_port= 0, opt_protocol= 0;
59 static char *opt_bind_addr = NULL;
60 static char * opt_mysql_unix_port=0;
61 static char *opt_plugin_dir= 0, *opt_default_auth= 0;
62 static longlong opt_ignore_lines= -1;
63 #include <sslopt-vars.h>
66 static char *shared_memory_base_name=0;
69 static struct my_option my_long_options[] =
71 {
"bind-address", 0,
"IP address to bind to.",
72 (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
73 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
74 {
"character-sets-dir", OPT_CHARSETS_DIR,
75 "Directory for character set files.", &charsets_dir,
76 &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
77 {
"default-character-set", OPT_DEFAULT_CHARSET,
78 "Set the default character set.", &default_charset,
79 &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
81 "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.",
82 &opt_columns, &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
84 {
"compress",
'C',
"Use compression in server/client protocol.",
85 &opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
87 {
"debug",
'#',
"Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
88 GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
89 {
"debug-check", OPT_DEBUG_CHECK,
"Check memory and open file usage at exit.",
90 &debug_check_flag, &debug_check_flag, 0,
91 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
92 {
"debug-info", OPT_DEBUG_INFO,
"Print some debug info at exit.",
93 &debug_info_flag, &debug_info_flag,
94 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
95 {
"default_auth", OPT_DEFAULT_AUTH,
96 "Default authentication client-side plugin to use.",
97 &opt_default_auth, &opt_default_auth, 0,
98 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
99 {
"delete",
'd',
"First delete all rows from table.", &opt_delete,
100 &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
101 {
"fields-terminated-by", OPT_FTB,
102 "Fields in the input file are terminated by the given string.",
103 &fields_terminated, &fields_terminated, 0,
104 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
105 {
"fields-enclosed-by", OPT_ENC,
106 "Fields in the import file are enclosed by the given character.",
107 &enclosed, &enclosed, 0,
108 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
109 {
"fields-optionally-enclosed-by", OPT_O_ENC,
110 "Fields in the input file are optionally enclosed by the given character.",
111 &opt_enclosed, &opt_enclosed, 0,
112 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
113 {
"fields-escaped-by", OPT_ESC,
114 "Fields in the input file are escaped by the given character.",
115 &escaped, &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
117 {
"force",
'f',
"Continue even if we get an SQL error.",
118 &ignore_errors, &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
120 {
"help",
'?',
"Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
122 {
"host",
'h',
"Connect to host.", ¤t_host,
123 ¤t_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
124 {
"ignore",
'i',
"If duplicate unique key was found, keep old row.",
125 &ignore, &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
126 {
"ignore-lines", OPT_IGN_LINES,
"Ignore first n lines of data infile.",
127 &opt_ignore_lines, &opt_ignore_lines, 0, GET_LL,
128 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
129 {
"lines-terminated-by", OPT_LTB,
130 "Lines in the input file are terminated by the given string.",
131 &lines_terminated, &lines_terminated, 0, GET_STR,
132 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
133 {
"local",
'L',
"Read all files through the client.", &opt_local_file,
134 &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
135 {
"lock-tables",
'l',
"Lock all tables for write (this disables threads).",
138 {
"low-priority", OPT_LOW_PRIORITY,
139 "Use LOW_PRIORITY when updating the table.", &opt_low_priority,
140 &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
142 "Password to use when connecting to server. If password is not given it's asked from the tty.",
143 0, 0, 0, GET_PASSWORD, OPT_ARG, 0, 0, 0, 0, 0, 0},
145 {
"pipe",
'W',
"Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
146 NO_ARG, 0, 0, 0, 0, 0, 0},
148 {
"plugin_dir", OPT_PLUGIN_DIR,
"Directory for client-side plugins.",
149 &opt_plugin_dir, &opt_plugin_dir, 0,
150 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
151 {
"port",
'P',
"Port number to use for connection or 0 for default to, in "
152 "order of preference, my.cnf, $MYSQL_TCP_PORT, "
153 #if MYSQL_PORT_DEFAULT == 0
156 "built-in default (" STRINGIFY_ARG(MYSQL_PORT)
").",
158 &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
160 {
"protocol", OPT_MYSQL_PROTOCOL,
"The protocol to use for connection (tcp, socket, pipe, memory).",
161 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
162 {
"replace",
'r',
"If duplicate unique key was found, replace old row.",
163 &
replace, &
replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
165 {
"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
166 "Base name of shared memory.", &shared_memory_base_name, &shared_memory_base_name,
167 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
169 {
"silent",
's',
"Be more silent.", &silent, &silent, 0,
170 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
171 {
"socket",
'S',
"The socket file to use for connection.",
172 &opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR,
173 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
174 #include <sslopt-longopts.h>
175 {
"use-threads", OPT_USE_THREADS,
176 "Load files in parallel. The argument is the number "
177 "of threads to use for loading data.",
178 &opt_use_threads, &opt_use_threads, 0,
179 GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
180 #ifndef DONT_ALLOW_USER_CHANGE
181 {
"user",
'u',
"User for login if not current user.", ¤t_user,
182 ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
184 {
"verbose",
'v',
"Print info about the various stages.", &verbose,
185 &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
186 {
"version",
'V',
"Output version information and exit.", 0, 0, 0, GET_NO_ARG,
187 NO_ARG, 0, 0, 0, 0, 0, 0},
188 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
192 static const char *load_default_groups[]= {
"mysqlimport",
"client",0 };
195 static void print_version(
void)
197 printf(
"%s Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
198 IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
202 static void usage(
void)
205 puts(ORACLE_WELCOME_COPYRIGHT_NOTICE(
"2000"));
207 Loads tables from text files in various formats. The base name of the\n\
208 text file must be the name of the table that should be used.\n\
209 If one uses sockets to connect to the MySQL server, the server will open and\n\
210 read the text file directly. In other cases the client will open the text\n\
211 file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
213 printf(
"\nUsage: %s [OPTIONS] database textfile...",my_progname);
214 print_defaults(
"my",load_default_groups);
215 my_print_help(my_long_options);
216 my_print_variables(my_long_options);
221 get_one_option(
int optid,
const struct my_option *opt __attribute__((unused)),
226 if (argument == disabled_my_option)
227 argument= (
char*)
"";
230 char *start=argument;
231 my_free(opt_password);
232 opt_password=my_strdup(argument,MYF(MY_FAE));
233 while (*argument) *argument++=
'x';
243 opt_protocol = MYSQL_PROTOCOL_PIPE;
247 case OPT_MYSQL_PROTOCOL:
248 opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
252 DBUG_PUSH(argument ? argument :
"d:t:o");
255 #include <sslopt-case.h>
256 case 'V': print_version(); exit(0);
266 static int get_options(
int *argc,
char ***argv)
270 if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
273 my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
274 if (debug_check_flag)
275 my_end_arg= MY_CHECK_ERROR;
277 if (enclosed && opt_enclosed)
279 fprintf(stderr,
"You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
284 fprintf(stderr,
"You can't use --ignore (-i) and --replace (-r) at the same time.\n");
292 current_db= *((*argv)++);
295 opt_password=get_tty_password(NullS);
301 static int write_to_table(
char *filename,
MYSQL *mysql)
303 char tablename[FN_REFLEN], hard_path[FN_REFLEN],
304 escaped_name[FN_REFLEN * 2 + 1],
305 sql_statement[FN_REFLEN*16+256], *end, *pos;
306 DBUG_ENTER(
"write_to_table");
307 DBUG_PRINT(
"enter",(
"filename: %s",filename));
309 fn_format(tablename, filename,
"",
"", 1 | 2);
311 strmov(hard_path,filename);
313 my_load_path(hard_path, filename, NULL);
318 fprintf(stdout,
"Deleting the old data from table %s\n", tablename);
320 snprintf(sql_statement, FN_REFLEN*16+256,
"DELETE FROM %s", tablename);
322 sprintf(sql_statement,
"DELETE FROM %s", tablename);
324 if (mysql_query(mysql, sql_statement))
326 db_error_with_table(mysql, tablename);
330 to_unix_path(hard_path);
334 fprintf(stdout,
"Loading data from LOCAL file: %s into %s\n",
335 hard_path, tablename);
337 fprintf(stdout,
"Loading data from SERVER file: %s into %s\n",
338 hard_path, tablename);
340 mysql_real_escape_string(mysql, escaped_name, hard_path,
341 (
unsigned long) strlen(hard_path));
342 sprintf(sql_statement,
"LOAD DATA %s %s INFILE '%s'",
343 opt_low_priority ?
"LOW_PRIORITY" :
"",
344 opt_local_file ?
"LOCAL" :
"", escaped_name);
345 end= strend(sql_statement);
347 end= strmov(end,
" REPLACE");
349 end= strmov(end,
" IGNORE");
350 end= strmov(end,
" INTO TABLE `");
352 for (pos= tablename; *pos; pos++)
358 end= strmov(end,
"`");
360 if (fields_terminated || enclosed || opt_enclosed || escaped)
361 end= strmov(end,
" FIELDS");
362 end= add_load_option(end, fields_terminated,
" TERMINATED BY");
363 end= add_load_option(end, enclosed,
" ENCLOSED BY");
364 end= add_load_option(end, opt_enclosed,
365 " OPTIONALLY ENCLOSED BY");
366 end= add_load_option(end, escaped,
" ESCAPED BY");
367 end= add_load_option(end, lines_terminated,
" LINES TERMINATED BY");
368 if (opt_ignore_lines >= 0)
369 end= strmov(longlong10_to_str(opt_ignore_lines,
370 strmov(end,
" IGNORE "),10),
" LINES");
372 end= strmov(strmov(strmov(end,
" ("), opt_columns),
")");
375 if (mysql_query(mysql, sql_statement))
377 db_error_with_table(mysql, tablename);
382 if (mysql_info(mysql))
384 fprintf(stdout,
"%s.%s: %s\n", current_db, tablename,
393 static void lock_table(
MYSQL *mysql,
int tablecount,
char **raw_tablename)
397 char tablename[FN_REFLEN];
400 fprintf(stdout,
"Locking tables for write\n");
401 init_dynamic_string(&query,
"LOCK TABLES ", 256, 1024);
402 for (i=0 ; i < tablecount ; i++)
404 fn_format(tablename, raw_tablename[i],
"",
"", 1 | 2);
405 dynstr_append(&query, tablename);
406 dynstr_append(&query,
" WRITE,");
408 if (mysql_real_query(mysql, query.str, query.length-1))
415 static MYSQL *db_connect(
char *host,
char *database,
416 char *user,
char *passwd)
420 fprintf(stdout,
"Connecting to %s\n", host ? host :
"localhost");
421 if (!(mysql= mysql_init(NULL)))
424 mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
426 mysql_options(mysql,MYSQL_OPT_LOCAL_INFILE,
427 (
char*) &opt_local_file);
431 mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
432 opt_ssl_capath, opt_ssl_cipher);
433 mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl);
434 mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath);
436 mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
437 (
char*)&opt_ssl_verify_server_cert);
440 mysql_options(mysql,MYSQL_OPT_PROTOCOL,(
char*)&opt_protocol);
442 mysql_options(mysql,MYSQL_OPT_BIND,opt_bind_addr);
444 if (shared_memory_base_name)
445 mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
448 if (opt_plugin_dir && *opt_plugin_dir)
449 mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
451 if (opt_default_auth && *opt_default_auth)
452 mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
454 mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset);
455 mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
456 mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
457 "program_name",
"mysqlimport");
458 if (!(mysql_real_connect(mysql,host,user,passwd,
459 database,opt_mysql_port,opt_mysql_unix_port,
467 fprintf(stdout,
"Selecting database %s\n", database);
468 if (mysql_select_db(mysql, database))
478 static void db_disconnect(
char *host,
MYSQL *mysql)
481 fprintf(stdout,
"Disconnecting from %s\n", host ? host :
"localhost");
487 static void safe_exit(
int error,
MYSQL *mysql)
498 static void db_error_with_table(
MYSQL *mysql,
char *
table)
500 my_printf_error(0,
"Error: %d, %s, when using table: %s",
501 MYF(0), mysql_errno(mysql), mysql_error(mysql), table);
507 static void db_error(
MYSQL *mysql)
509 my_printf_error(0,
"Error: %d %s", MYF(0), mysql_errno(mysql), mysql_error(mysql));
514 static char *add_load_option(
char *ptr,
const char *
object,
520 if (
object[0] ==
'0' && (
object[1] ==
'x' ||
object[1] ==
'X'))
521 ptr= strxmov(ptr,
" ",statement,
" ",
object,NullS);
525 ptr= strxmov(ptr,
" ",statement,
" '",NullS);
526 ptr= field_escape(ptr,
object,(uint) strlen(
object));
540 static char *field_escape(
char *
to,
const char *from,uint length)
543 uint end_backslashes=0;
545 for (end= from+length; from != end; from++)
552 if (*from ==
'\'' && !end_backslashes)
565 #ifdef HAVE_LIBPTHREAD
566 pthread_handler_t worker_thread(
void *arg)
569 char *raw_table_name= (
char *)arg;
572 if (mysql_thread_init())
575 if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
580 if (mysql_query(mysql,
"/*!40101 set @@character_set_database=binary */;"))
589 if((error= write_to_table(raw_table_name, mysql)))
595 db_disconnect(current_host, mysql);
597 pthread_mutex_lock(&counter_mutex);
599 pthread_cond_signal(&count_threshhold);
600 pthread_mutex_unlock(&counter_mutex);
608 int main(
int argc,
char **argv)
614 my_getopt_use_args_separator= TRUE;
615 if (load_defaults(
"my",load_default_groups,&argc,&argv))
617 my_getopt_use_args_separator= FALSE;
621 if (get_options(&argc, &argv))
623 free_defaults(argv_to_free);
627 #ifdef HAVE_LIBPTHREAD
630 pthread_t mainthread;
632 pthread_attr_init(&attr);
633 pthread_attr_setdetachstate(&attr,
634 PTHREAD_CREATE_DETACHED);
636 pthread_mutex_init(&counter_mutex, NULL);
637 pthread_cond_init(&count_threshhold, NULL);
639 for (counter= 0; *argv != NULL; argv++)
641 pthread_mutex_lock(&counter_mutex);
642 while (counter == opt_use_threads)
646 set_timespec(abstime, 3);
647 pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
651 pthread_mutex_unlock(&counter_mutex);
653 if (pthread_create(&mainthread, &attr, worker_thread,
656 pthread_mutex_lock(&counter_mutex);
658 pthread_mutex_unlock(&counter_mutex);
659 fprintf(stderr,
"%s: Could not create thread\n",
667 pthread_mutex_lock(&counter_mutex);
672 set_timespec(abstime, 3);
673 pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
675 pthread_mutex_unlock(&counter_mutex);
676 pthread_mutex_destroy(&counter_mutex);
677 pthread_cond_destroy(&count_threshhold);
678 pthread_attr_destroy(&attr);
684 if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
686 free_defaults(argv_to_free);
690 if (mysql_query(mysql,
"/*!40101 set @@character_set_database=binary */;"))
698 for (; *argv != NULL; argv++)
699 if ((error= write_to_table(*argv, mysql)))
702 db_disconnect(current_host, mysql);
704 my_free(opt_password);
706 my_free(shared_memory_base_name);
708 free_defaults(argv_to_free);