~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlimport.c

  • Committer: Monty Taylor
  • Date: 2008-07-01 14:33:36 UTC
  • mto: (28.1.12 backport_patch)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: monty@inaugust.com-20080701143336-8uihm7dhpu92rt0q
Somehow missed moving password.c. Duh.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 Drizzle Open Source Development Team
 
1
/* Copyright (C) 2000-2006 MySQL AB
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
 
**     drizzleimport.c  - Imports all given files
18
 
**          into a table(s).
 
17
**         mysqlimport.c  - Imports all given files
 
18
**                          into a table(s).
19
19
**
20
 
**         *************************
21
 
**         *         *
22
 
**         * AUTHOR: Monty & Jani  *
23
 
**         * DATE:   June 24, 1997 *
24
 
**         *         *
25
 
**         *************************
 
20
**                         *************************
 
21
**                         *                       *
 
22
**                         * AUTHOR: Monty & Jani  *
 
23
**                         * DATE:   June 24, 1997 *
 
24
**                         *                       *
 
25
**                         *************************
26
26
*/
27
27
#define IMPORT_VERSION "3.7"
28
28
 
29
 
#include "config.h"
30
 
#include <string>
31
 
 
32
29
#include "client_priv.h"
33
 
#include <pthread.h>
 
30
#include "mysql_version.h"
 
31
#ifdef HAVE_LIBPTHREAD
 
32
#include <my_pthread.h>
 
33
#endif
34
34
 
35
 
using namespace std;
36
35
 
37
36
/* Global Thread counter */
38
37
uint counter;
 
38
#ifdef HAVE_LIBPTHREAD
39
39
pthread_mutex_t counter_mutex;
40
40
pthread_cond_t count_threshhold;
 
41
#endif
41
42
 
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);
47
48
 
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;
 
63
 
 
64
#ifdef HAVE_SMEM
 
65
static char *shared_memory_base_name=0;
 
66
#endif
62
67
 
63
68
static struct my_option my_long_options[] =
64
69
{
65
70
  {"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},
 
71
   "Directory where character sets are.", (uchar**) &charsets_dir,
 
72
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
68
73
  {"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},
 
74
   "Set the default character set.", (uchar**) &default_charset,
 
75
   (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
71
76
  {"columns", 'c',
72
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.",
73
 
   (char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
 
78
   (uchar**) &opt_columns, (uchar**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
74
79
   0, 0, 0},
75
80
  {"compress", 'C', "Use compression in server/client protocol.",
76
 
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
81
   (uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
77
82
   0, 0, 0},
78
83
  {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
79
84
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
80
85
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
81
 
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
86
   (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
82
87
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
83
88
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
84
 
   (char**) &debug_info_flag, (char**) &debug_info_flag,
 
89
   (uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
85
90
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
86
 
  {"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
87
 
   (char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
91
  {"delete", 'd', "First delete all rows from table.", (uchar**) &opt_delete,
 
92
   (uchar**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
88
93
  {"fields-terminated-by", OPT_FTB,
89
 
   "Fields in the textfile are terminated by ...", (char**) &fields_terminated,
90
 
   (char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
94
   "Fields in the textfile are terminated by ...", (uchar**) &fields_terminated,
 
95
   (uchar**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
91
96
  {"fields-enclosed-by", OPT_ENC,
92
 
   "Fields in the importfile are enclosed by ...", (char**) &enclosed,
93
 
   (char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
97
   "Fields in the importfile are enclosed by ...", (uchar**) &enclosed,
 
98
   (uchar**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
94
99
  {"fields-optionally-enclosed-by", OPT_O_ENC,
95
 
   "Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
96
 
   (char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
100
   "Fields in the i.file are opt. enclosed by ...", (uchar**) &opt_enclosed,
 
101
   (uchar**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
97
102
  {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
98
 
   (char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
 
103
   (uchar**) &escaped, (uchar**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
99
104
   0, 0},
100
105
  {"force", 'f', "Continue even if we get an sql-error.",
101
 
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
 
106
   (uchar**) &ignore_errors, (uchar**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
102
107
   0, 0, 0, 0},
103
108
  {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
104
109
   0, 0, 0, 0, 0, 0},
105
 
  {"host", 'h', "Connect to host.", (char**) &current_host,
106
 
   (char**) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
110
  {"host", 'h', "Connect to host.", (uchar**) &current_host,
 
111
   (uchar**) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
107
112
  {"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},
 
113
   (uchar**) &ignore, (uchar**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
109
114
  {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
110
 
   (char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
 
115
   (uchar**) &opt_ignore_lines, (uchar**) &opt_ignore_lines, 0, GET_LL,
111
116
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
112
117
  {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
113
 
   (char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
 
118
   (uchar**) &lines_terminated, (uchar**) &lines_terminated, 0, GET_STR,
114
119
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
115
 
  {"local", 'L', "Read all files through the client.", (char**) &opt_local_file,
116
 
   (char**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
120
  {"local", 'L', "Read all files through the client.", (uchar**) &opt_local_file,
 
121
   (uchar**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
117
122
  {"lock-tables", 'l', "Lock all tables for write (this disables threads).",
118
 
    (char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG,
 
123
    (uchar**) &lock_tables, (uchar**) &lock_tables, 0, GET_BOOL, NO_ARG, 
119
124
    0, 0, 0, 0, 0, 0},
120
125
  {"low-priority", OPT_LOW_PRIORITY,
121
 
   "Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
122
 
   (char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
126
   "Use LOW_PRIORITY when updating the table.", (uchar**) &opt_low_priority,
 
127
   (uchar**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
123
128
  {"password", 'p',
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
 
134
   "/etc/services, "
 
135
#endif
 
136
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
 
137
   (uchar**) &opt_mysql_port,
 
138
   (uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
131
139
   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},
136
 
  {"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
 
143
   (uchar**) &replace, (uchar**) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
144
#ifdef HAVE_SMEM
 
145
  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
 
146
   "Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
 
147
   0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
148
#endif
 
149
  {"silent", 's', "Be more silent.", (uchar**) &silent, (uchar**) &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
   (uchar**) &opt_mysql_unix_port, (uchar**) &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
   (uchar**) &opt_use_threads, (uchar**) &opt_use_threads, 0, 
145
158
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
146
159
#ifndef DONT_ALLOW_USER_CHANGE
147
 
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
148
 
   (char**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
160
  {"user", 'u', "User for login if not current user.", (uchar**) &current_user,
 
161
   (uchar**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
149
162
#endif
150
 
  {"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
151
 
   (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
163
  {"verbose", 'v', "Print info about the various stages.", (uchar**) &verbose,
 
164
   (uchar**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
152
165
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
153
166
   NO_ARG, 0, 0, 0, 0, 0, 0},
154
167
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
155
168
};
156
169
 
157
170
 
158
 
static const char *load_default_groups[]= { "drizzleimport","client",0 };
 
171
static const char *load_default_groups[]= { "mysqlimport","client",0 };
 
172
 
 
173
#include <help_start.h>
159
174
 
160
175
static void print_version(void)
161
176
{
162
177
  printf("%s  Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
163
 
    IMPORT_VERSION, drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
 
178
          IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
164
179
}
165
180
 
166
181
 
167
182
static void usage(void)
168
183
{
169
184
  print_version();
170
 
  puts("Copyright (C) 2008 Drizzle Open Source Development Team");
 
185
  puts("Copyright (C) 2000-2006 MySQL AB");
171
186
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
172
187
  printf("\
173
188
Loads tables from text files in various formats.  The base name of the\n\
174
189
text file must be the name of the table that should be used.\n\
175
 
If one uses sockets to connect to the Drizzle server, the server will open and\n\
 
190
If one uses sockets to connect to the MySQL server, the server will open and\n\
176
191
read the text file directly. In other cases the client will open the text\n\
177
192
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
178
193
 
182
197
  my_print_variables(my_long_options);
183
198
}
184
199
 
185
 
static bool
 
200
#include <help_end.h>
 
201
 
 
202
static my_bool
186
203
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
187
 
         char *argument)
 
204
               char *argument)
188
205
{
189
206
  switch(optid) {
190
207
  case 'p':
191
208
    if (argument)
192
209
    {
193
210
      char *start=argument;
194
 
      free(opt_password);
 
211
      my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
195
212
      opt_password=my_strdup(argument,MYF(MY_FAE));
196
 
      while (*argument) *argument++= 'x';    /* Destroy argument */
 
213
      while (*argument) *argument++= 'x';               /* Destroy argument */
197
214
      if (*start)
198
 
  start[1]=0;        /* Cut length of argument */
 
215
        start[1]=0;                             /* Cut length of argument */
199
216
      tty_password= 0;
200
217
    }
201
218
    else
202
219
      tty_password= 1;
203
220
    break;
204
 
  case OPT_DRIZZLE_PROTOCOL:
 
221
  case OPT_MYSQL_PROTOCOL:
 
222
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
223
                                    opt->name);
 
224
    break;
 
225
  case '#':
 
226
    DBUG_PUSH(argument ? argument : "d:t:o");
 
227
    debug_check_flag= 1;
205
228
    break;
206
229
  case 'V': print_version(); exit(0);
207
230
  case 'I':
229
252
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
230
253
    return(1);
231
254
  }
232
 
  if (opt_replace && ignore)
 
255
  if (replace && ignore)
233
256
  {
234
257
    fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
235
258
    return(1);
236
259
  }
237
260
  if (strcmp(default_charset, charset_info->csname) &&
238
261
      !(charset_info= get_charset_by_csname(default_charset,
239
 
                MY_CS_PRIMARY, MYF(MY_WME))))
 
262
                                            MY_CS_PRIMARY, MYF(MY_WME))))
240
263
    exit(1);
241
264
  if (*argc < 2)
242
265
  {
246
269
  current_db= *((*argv)++);
247
270
  (*argc)--;
248
271
  if (tty_password)
249
 
    opt_password=get_tty_password(NULL);
 
272
    opt_password=get_tty_password(NullS);
250
273
  return(0);
251
274
}
252
275
 
253
276
 
254
277
 
255
 
static int write_to_table(char *filename, DRIZZLE *drizzle)
 
278
static int write_to_table(char *filename, MYSQL *mysql)
256
279
{
257
280
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
258
281
       sql_statement[FN_REFLEN*16+256], *end;
 
282
  DBUG_ENTER("write_to_table");
 
283
  DBUG_PRINT("enter",("filename: %s",filename));
259
284
 
260
285
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
261
286
  if (!opt_local_file)
262
 
    my_stpcpy(hard_path,filename);
 
287
    strmov(hard_path,filename);
263
288
  else
264
289
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
265
290
 
272
297
#else
273
298
    sprintf(sql_statement, "DELETE FROM %s", tablename);
274
299
#endif
275
 
    if (drizzle_query(drizzle, sql_statement))
 
300
    if (mysql_query(mysql, sql_statement))
276
301
    {
277
 
      db_error_with_table(drizzle, tablename);
278
 
      return(1);
 
302
      db_error_with_table(mysql, tablename);
 
303
      DBUG_RETURN(1);
279
304
    }
280
305
  }
281
306
  to_unix_path(hard_path);
283
308
  {
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);
287
312
    else
288
313
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
289
 
        hard_path, tablename);
 
314
              hard_path, tablename);
290
315
  }
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');
295
 
  if (opt_replace)
296
 
    end= my_stpcpy(end, " REPLACE");
 
317
          opt_low_priority ? "LOW_PRIORITY" : "",
 
318
          opt_local_file ? "LOCAL" : "", hard_path);
 
319
  end= strend(sql_statement);
 
320
  if (replace)
 
321
    end= strmov(end, " REPLACE");
297
322
  if (ignore)
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);
300
325
 
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");
312
337
  if (opt_columns)
313
 
    end= my_stpcpy(my_stpcpy(my_stpcpy(end, " ("), opt_columns), ")");
 
338
    end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
314
339
  *end= '\0';
315
340
 
316
 
  if (drizzle_query(drizzle, sql_statement))
 
341
  if (mysql_query(mysql, sql_statement))
317
342
  {
318
 
    db_error_with_table(drizzle, tablename);
319
 
    return(1);
 
343
    db_error_with_table(mysql, tablename);
 
344
    DBUG_RETURN(1);
320
345
  }
321
346
  if (!silent)
322
347
  {
323
 
    if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
 
348
    if (mysql_info(mysql)) /* If NULL-pointer, print nothing */
324
349
    {
325
350
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
326
 
        drizzle_info(drizzle));
 
351
              mysql_info(mysql));
327
352
    }
328
353
  }
329
 
  return(0);
 
354
  DBUG_RETURN(0);
330
355
}
331
356
 
332
357
 
333
358
 
334
 
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
 
359
static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
335
360
{
336
 
  string query;
 
361
  DYNAMIC_STRING query;
337
362
  int i;
338
363
  char tablename[FN_REFLEN];
339
364
 
340
365
  if (verbose)
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++)
344
369
  {
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,");
348
373
  }
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 */
351
376
}
352
377
 
353
378
 
354
379
 
355
380
 
356
 
static DRIZZLE *db_connect(char *host, char *database,
 
381
static MYSQL *db_connect(char *host, char *database,
357
382
                         char *user, char *passwd)
358
383
{
359
 
  DRIZZLE *drizzle;
 
384
  MYSQL *mysql;
360
385
  if (verbose)
361
386
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
362
 
  if (!(drizzle= drizzle_create(NULL)))
 
387
  if (!(mysql= mysql_init(NULL)))
363
388
    return 0;
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);
 
394
#ifdef HAVE_OPENSSL
 
395
  if (opt_use_ssl)
 
396
    mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
 
397
                  opt_ssl_capath, opt_ssl_cipher);
 
398
  mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
 
399
                (char*)&opt_ssl_verify_server_cert);
 
400
#endif
369
401
  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,
 
402
    mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
403
#ifdef HAVE_SMEM
 
404
  if (shared_memory_base_name)
 
405
    mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 
406
#endif
 
407
  if (!(mysql_real_connect(mysql,host,user,passwd,
 
408
                           database,opt_mysql_port,opt_mysql_unix_port,
373
409
                           0)))
374
410
  {
375
 
    ignore_errors=0;    /* NO RETURN FROM db_error */
376
 
    db_error(drizzle);
 
411
    ignore_errors=0;      /* NO RETURN FROM db_error */
 
412
    db_error(mysql);
377
413
  }
378
 
  drizzle->reconnect= 0;
 
414
  mysql->reconnect= 0;
379
415
  if (verbose)
380
416
    fprintf(stdout, "Selecting database %s\n", database);
381
 
  if (drizzle_select_db(drizzle, database))
 
417
  if (mysql_select_db(mysql, database))
382
418
  {
383
419
    ignore_errors=0;
384
 
    db_error(drizzle);
 
420
    db_error(mysql);
385
421
  }
386
 
  return drizzle;
 
422
  return mysql;
387
423
}
388
424
 
389
425
 
390
426
 
391
 
static void db_disconnect(char *host, DRIZZLE *drizzle)
 
427
static void db_disconnect(char *host, MYSQL *mysql)
392
428
{
393
429
  if (verbose)
394
430
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
395
 
  drizzle_close(drizzle);
 
431
  mysql_close(mysql);
396
432
}
397
433
 
398
434
 
399
435
 
400
 
static void safe_exit(int error, DRIZZLE *drizzle)
 
436
static void safe_exit(int error, MYSQL *mysql)
401
437
{
402
438
  if (ignore_errors)
403
439
    return;
404
 
  if (drizzle)
405
 
    drizzle_close(drizzle);
 
440
  if (mysql)
 
441
    mysql_close(mysql);
406
442
  exit(error);
407
443
}
408
444
 
409
445
 
410
446
 
411
 
static void db_error_with_table(DRIZZLE *drizzle, char *table)
 
447
static void db_error_with_table(MYSQL *mysql, char *table)
412
448
{
413
449
  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);
 
450
                  MYF(0), mysql_errno(mysql), mysql_error(mysql), table);
 
451
  safe_exit(1, mysql);
416
452
}
417
453
 
418
454
 
419
455
 
420
 
static void db_error(DRIZZLE *drizzle)
 
456
static void db_error(MYSQL *mysql)
421
457
{
422
 
  my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
423
 
  safe_exit(1, drizzle);
 
458
  my_printf_error(0,"Error: %d %s", MYF(0), mysql_errno(mysql), mysql_error(mysql));
 
459
  safe_exit(1, mysql);
424
460
}
425
461
 
426
462
 
427
463
static char *add_load_option(char *ptr, const char *object,
428
 
           const char *statement)
 
464
                             const char *statement)
429
465
{
430
466
  if (object)
431
467
  {
432
468
    /* Don't escape hex constants */
433
469
    if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
434
 
      ptr= strxmov(ptr," ",statement," ",object,NULL);
 
470
      ptr= strxmov(ptr," ",statement," ",object,NullS);
435
471
    else
436
472
    {
437
473
      /* char constant; escape */
438
 
      ptr= strxmov(ptr," ",statement," '",NULL);
 
474
      ptr= strxmov(ptr," ",statement," '",NullS);
439
475
      ptr= field_escape(ptr,object,(uint) strlen(object));
440
476
      *ptr++= '\'';
441
477
    }
448
484
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
449
485
** This is done by doubleing ' and add a end -\ if needed to avoid
450
486
** syntax errors from the SQL parser.
451
 
*/
 
487
*/ 
452
488
 
453
489
static char *field_escape(char *to,const char *from,uint length)
454
490
{
455
491
  const char *end;
456
 
  uint end_backslashes=0;
 
492
  uint end_backslashes=0; 
457
493
 
458
494
  for (end= from+length; from != end; from++)
459
495
  {
460
496
    *to++= *from;
461
497
    if (*from == '\\')
462
498
      end_backslashes^=1;    /* find odd number of backslashes */
463
 
    else
 
499
    else 
464
500
    {
465
501
      if (*from == '\'' && !end_backslashes)
466
 
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
 
502
        *to++= *from;      /* We want a dublicate of "'" for MySQL */
467
503
      end_backslashes=0;
468
504
    }
469
505
  }
470
506
  /* Add missing backslashes if user has specified odd number of backs.*/
471
507
  if (end_backslashes)
472
 
    *to++= '\\';         
 
508
    *to++= '\\';          
473
509
  return to;
474
510
}
475
511
 
476
512
int exitcode= 0;
477
513
 
478
 
static void * worker_thread(void *arg)
 
514
#ifdef HAVE_LIBPTHREAD
 
515
pthread_handler_t worker_thread(void *arg)
479
516
{
480
517
  int error;
481
518
  char *raw_table_name= (char *)arg;
482
 
  DRIZZLE *drizzle= 0;
 
519
  MYSQL *mysql= 0;
483
520
 
484
 
  if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
 
521
  if (mysql_thread_init())
 
522
    goto error;
 
523
  
 
524
  if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
485
525
  {
486
526
    goto error;
487
527
  }
488
528
 
489
 
  if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
 
529
  if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
490
530
  {
491
 
    db_error(drizzle); /* We shall countinue here, if --force was given */
 
531
    db_error(mysql); /* We shall countinue here, if --force was given */
492
532
    goto error;
493
533
  }
494
534
 
495
535
  /*
496
536
    We are not currently catching the error here.
497
537
  */
498
 
  if((error= write_to_table(raw_table_name, drizzle)))
 
538
  if((error= write_to_table(raw_table_name, mysql)))
499
539
    if (exitcode == 0)
500
540
      exitcode= error;
501
541
 
502
542
error:
503
 
  if (drizzle)
504
 
    db_disconnect(current_host, drizzle);
 
543
  if (mysql)
 
544
    db_disconnect(current_host, mysql);
505
545
 
506
546
  pthread_mutex_lock(&counter_mutex);
507
547
  counter--;
511
551
 
512
552
  return 0;
513
553
}
 
554
#endif
514
555
 
515
556
 
516
557
int main(int argc, char **argv)
537
578
    pthread_attr_setdetachstate(&attr,
538
579
                                PTHREAD_CREATE_DETACHED);
539
580
 
540
 
    pthread_mutex_init(&counter_mutex, NULL);
541
 
    pthread_cond_init(&count_threshhold, NULL);
 
581
    VOID(pthread_mutex_init(&counter_mutex, NULL));
 
582
    VOID(pthread_cond_init(&count_threshhold, NULL));
542
583
 
543
584
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
544
585
    {
554
595
      counter++;
555
596
      pthread_mutex_unlock(&counter_mutex);
556
597
      /* now create the thread */
557
 
      if (pthread_create(&mainthread, &attr, worker_thread,
 
598
      if (pthread_create(&mainthread, &attr, worker_thread, 
558
599
                         (void *)*argv) != 0)
559
600
      {
560
601
        pthread_mutex_lock(&counter_mutex);
577
618
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
578
619
    }
579
620
    pthread_mutex_unlock(&counter_mutex);
580
 
    pthread_mutex_destroy(&counter_mutex);
581
 
    pthread_cond_destroy(&count_threshhold);
 
621
    VOID(pthread_mutex_destroy(&counter_mutex));
 
622
    VOID(pthread_cond_destroy(&count_threshhold));
582
623
    pthread_attr_destroy(&attr);
583
624
  }
584
625
  else
585
626
#endif
586
627
  {
587
 
    DRIZZLE *drizzle= 0;
588
 
    if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
 
628
    MYSQL *mysql= 0;
 
629
    if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
589
630
    {
590
631
      free_defaults(argv_to_free);
591
632
      return(1); /* purecov: deadcode */
592
633
    }
593
634
 
594
 
    if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
 
635
    if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
595
636
    {
596
 
      db_error(drizzle); /* We shall countinue here, if --force was given */
 
637
      db_error(mysql); /* We shall countinue here, if --force was given */
597
638
      return(1);
598
639
    }
599
640
 
600
641
    if (lock_tables)
601
 
      lock_table(drizzle, argc, argv);
 
642
      lock_table(mysql, argc, argv);
602
643
    for (; *argv != NULL; argv++)
603
 
      if ((error= write_to_table(*argv, drizzle)))
 
644
      if ((error= write_to_table(*argv, mysql)))
604
645
        if (exitcode == 0)
605
646
          exitcode= error;
606
 
    db_disconnect(current_host, drizzle);
 
647
    db_disconnect(current_host, mysql);
607
648
  }
608
 
  free(opt_password);
 
649
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
650
#ifdef HAVE_SMEM
 
651
  my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
652
#endif
609
653
  free_defaults(argv_to_free);
610
654
  my_end(my_end_arg);
611
655
  return(exitcode);