~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlimport.c

Renamed more stuff to drizzle.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
  Copyright (C) 2010 Vijay Samuel
3
 
  Copyright (C) 2010 Brian Aker
4
 
  Copyright (C) 2000-2006 MySQL AB
5
 
  Copyright (C) 2008-2009 Sun Microsystems, Inc
6
 
 
7
 
  This program is free software; you can redistribute it and/or modify
8
 
  it under the terms of the GNU General Public License as published by
9
 
  the Free Software Foundation; version 2 of the License.
10
 
 
11
 
  This program is distributed in the hope that it will be useful,
12
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
  GNU General Public License for more details.
15
 
 
16
 
  You should have received a copy of the GNU General Public License
17
 
  along with this program; if not, write to the Free Software
18
 
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19
 
 
20
 
#define IMPORT_VERSION "4.0"
 
1
/* Copyright (C) 2000-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
/*
 
17
**         mysqlimport.c  - Imports all given files
 
18
**                          into a table(s).
 
19
**
 
20
**                         *************************
 
21
**                         *                       *
 
22
**                         * AUTHOR: Monty & Jani  *
 
23
**                         * DATE:   June 24, 1997 *
 
24
**                         *                       *
 
25
**                         *************************
 
26
*/
 
27
#define IMPORT_VERSION "3.7"
21
28
 
22
29
#include "client_priv.h"
23
 
#include <string>
24
 
#include <sstream>
25
 
#include <iostream>
26
 
#include <fstream>
27
 
#include <boost/program_options.hpp>
28
 
#include <pthread.h>
29
 
 
30
 
/* Added this for string translation. */
31
 
#include <drizzled/gettext.h>
32
 
#include <drizzled/configmake.h>
33
 
 
34
 
namespace po= boost::program_options;
35
 
using namespace std;
36
 
using namespace drizzled;
37
 
 
38
 
extern "C" void * worker_thread(void *arg);
39
 
 
40
 
int exitcode= 0;
41
 
 
42
 
const char *program_name= "drizzlesimport";
 
30
#include "mysql_version.h"
 
31
#ifdef HAVE_LIBPTHREAD
 
32
#include <my_pthread.h>
 
33
#endif
 
34
 
43
35
 
44
36
/* Global Thread counter */
45
 
uint32_t counter;
 
37
uint counter;
 
38
#ifdef HAVE_LIBPTHREAD
46
39
pthread_mutex_t counter_mutex;
47
40
pthread_cond_t count_threshhold;
 
41
#endif
48
42
 
49
 
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
50
 
                     drizzle_return_t ret, char *table);
51
 
static char *field_escape(char *to,const char *from,uint32_t length);
 
43
static void db_error_with_table(MYSQL *mysql, char *table);
 
44
static void db_error(MYSQL *mysql);
 
45
static char *field_escape(char *to,const char *from,uint length);
52
46
static char *add_load_option(char *ptr,const char *object,
53
 
           const char *statement);
54
 
 
55
 
static bool verbose= false, ignore_errors= false,
56
 
            opt_delete= false, opt_replace= false, silent= false,
57
 
            ignore_unique= false, opt_low_priority= false,
58
 
            use_drizzle_protocol= false, opt_local_file;
59
 
 
60
 
static uint32_t opt_use_threads;
61
 
static uint32_t opt_drizzle_port= 0;
62
 
static int64_t opt_ignore_lines= -1;
63
 
 
64
 
std::string opt_columns,
65
 
  opt_enclosed,
66
 
  escaped,
67
 
  password,
68
 
  current_db,
69
 
  lines_terminated,
70
 
  current_user,
71
 
  opt_password,
72
 
  enclosed,  
73
 
  current_host,
74
 
  fields_terminated,
75
 
  opt_protocol;
76
 
 
77
 
 
78
 
static int get_options(void)
79
 
{
80
 
 
81
 
  if (! enclosed.empty() && ! opt_enclosed.empty())
 
47
                             const char *statement);
 
48
 
 
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;
 
53
static uint opt_use_threads=0, opt_local_file=0, my_end_arg= 0;
 
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
 
67
 
 
68
static struct my_option my_long_options[] =
 
69
{
 
70
  {"character-sets-dir", OPT_CHARSETS_DIR,
 
71
   "Directory where character sets are.", (uchar**) &charsets_dir,
 
72
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
73
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
74
   "Set the default character set.", (uchar**) &default_charset,
 
75
   (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
76
  {"columns", 'c',
 
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.",
 
78
   (uchar**) &opt_columns, (uchar**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
 
79
   0, 0, 0},
 
80
  {"compress", 'C', "Use compression in server/client protocol.",
 
81
   (uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
82
   0, 0, 0},
 
83
  {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
 
84
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
85
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
 
86
   (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
 
87
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
88
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
89
   (uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
 
90
   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},
 
93
  {"fields-terminated-by", OPT_FTB,
 
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},
 
96
  {"fields-enclosed-by", OPT_ENC,
 
97
   "Fields in the importfile are enclosed by ...", (uchar**) &enclosed,
 
98
   (uchar**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
99
  {"fields-optionally-enclosed-by", OPT_O_ENC,
 
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},
 
102
  {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
 
103
   (uchar**) &escaped, (uchar**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
 
104
   0, 0},
 
105
  {"force", 'f', "Continue even if we get an sql-error.",
 
106
   (uchar**) &ignore_errors, (uchar**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
 
107
   0, 0, 0, 0},
 
108
  {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
 
109
   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},
 
112
  {"ignore", 'i', "If duplicate unique key was found, keep old row.",
 
113
   (uchar**) &ignore, (uchar**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
114
  {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
 
115
   (uchar**) &opt_ignore_lines, (uchar**) &opt_ignore_lines, 0, GET_LL,
 
116
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
117
  {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
 
118
   (uchar**) &lines_terminated, (uchar**) &lines_terminated, 0, GET_STR,
 
119
   REQUIRED_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},
 
122
  {"lock-tables", 'l', "Lock all tables for write (this disables threads).",
 
123
    (uchar**) &lock_tables, (uchar**) &lock_tables, 0, GET_BOOL, NO_ARG, 
 
124
    0, 0, 0, 0, 0, 0},
 
125
  {"low-priority", OPT_LOW_PRIORITY,
 
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},
 
128
  {"password", 'p',
 
129
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
 
130
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
131
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
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,
 
139
   0},
 
140
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
141
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
142
  {"replace", 'r', "If duplicate unique key was found, replace old row.",
 
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,
 
150
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
151
  {"socket", 'S', "Socket file to use for connection.",
 
152
   (uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
 
153
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
154
  {"use-threads", OPT_USE_THREADS,
 
155
   "Load files in parallel. The argument is the number "
 
156
   "of threads to use for loading data.",
 
157
   (uchar**) &opt_use_threads, (uchar**) &opt_use_threads, 0, 
 
158
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
159
#ifndef DONT_ALLOW_USER_CHANGE
 
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},
 
162
#endif
 
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},
 
165
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
 
166
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
167
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
168
};
 
169
 
 
170
 
 
171
static const char *load_default_groups[]= { "mysqlimport","client",0 };
 
172
 
 
173
#include <help_start.h>
 
174
 
 
175
static void print_version(void)
 
176
{
 
177
  printf("%s  Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
 
178
          IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
 
179
}
 
180
 
 
181
 
 
182
static void usage(void)
 
183
{
 
184
  print_version();
 
185
  puts("Copyright (C) 2000-2006 MySQL AB");
 
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");
 
187
  printf("\
 
188
Loads tables from text files in various formats.  The base name of the\n\
 
189
text file must be the name of the table that should be used.\n\
 
190
If one uses sockets to connect to the MySQL server, the server will open and\n\
 
191
read the text file directly. In other cases the client will open the text\n\
 
192
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
 
193
 
 
194
  printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
 
195
  print_defaults("my",load_default_groups);
 
196
  my_print_help(my_long_options);
 
197
  my_print_variables(my_long_options);
 
198
}
 
199
 
 
200
#include <help_end.h>
 
201
 
 
202
static my_bool
 
203
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
204
               char *argument)
 
205
{
 
206
  switch(optid) {
 
207
  case 'p':
 
208
    if (argument)
 
209
    {
 
210
      char *start=argument;
 
211
      my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
212
      opt_password=my_strdup(argument,MYF(MY_FAE));
 
213
      while (*argument) *argument++= 'x';               /* Destroy argument */
 
214
      if (*start)
 
215
        start[1]=0;                             /* Cut length of argument */
 
216
      tty_password= 0;
 
217
    }
 
218
    else
 
219
      tty_password= 1;
 
220
    break;
 
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;
 
228
    break;
 
229
  case 'V': print_version(); exit(0);
 
230
  case 'I':
 
231
  case '?':
 
232
    usage();
 
233
    exit(0);
 
234
  }
 
235
  return 0;
 
236
}
 
237
 
 
238
 
 
239
static int get_options(int *argc, char ***argv)
 
240
{
 
241
  int ho_error;
 
242
 
 
243
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
 
244
    exit(ho_error);
 
245
  if (debug_info_flag)
 
246
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
247
  if (debug_check_flag)
 
248
    my_end_arg= MY_CHECK_ERROR;
 
249
 
 
250
  if (enclosed && opt_enclosed)
82
251
  {
83
252
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
84
253
    return(1);
85
254
  }
86
 
  if (opt_replace && ignore_unique)
 
255
  if (replace && ignore)
87
256
  {
88
 
    fprintf(stderr, "You can't use --ignore_unique (-i) and --replace (-r) at the same time.\n");
 
257
    fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
89
258
    return(1);
90
259
  }
91
 
 
 
260
  if (strcmp(default_charset, charset_info->csname) &&
 
261
      !(charset_info= get_charset_by_csname(default_charset,
 
262
                                            MY_CS_PRIMARY, MYF(MY_WME))))
 
263
    exit(1);
 
264
  if (*argc < 2)
 
265
  {
 
266
    usage();
 
267
    return 1;
 
268
  }
 
269
  current_db= *((*argv)++);
 
270
  (*argc)--;
92
271
  if (tty_password)
93
 
    opt_password=client_get_tty_password(NULL);
 
272
    opt_password=get_tty_password(NullS);
94
273
  return(0);
95
274
}
96
275
 
97
276
 
98
277
 
99
 
static int write_to_table(char *filename, drizzle_con_st *con)
 
278
static int write_to_table(char *filename, MYSQL *mysql)
100
279
{
101
280
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
102
281
       sql_statement[FN_REFLEN*16+256], *end;
103
 
  drizzle_result_st result;
104
 
  drizzle_return_t ret;
 
282
  DBUG_ENTER("write_to_table");
 
283
  DBUG_PRINT("enter",("filename: %s",filename));
105
284
 
106
 
  internal::fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
107
 
  if (not opt_local_file)
108
 
    strcpy(hard_path,filename);
 
285
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
 
286
  if (!opt_local_file)
 
287
    strmov(hard_path,filename);
109
288
  else
110
 
    internal::my_load_path(hard_path, filename, NULL); /* filename includes the path */
 
289
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
111
290
 
112
291
  if (opt_delete)
113
292
  {
114
293
    if (verbose)
115
294
      fprintf(stdout, "Deleting the old data from table %s\n", tablename);
116
295
#ifdef HAVE_SNPRINTF
117
 
    snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
 
296
    snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
118
297
#else
119
 
    snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
 
298
    sprintf(sql_statement, "DELETE FROM %s", tablename);
120
299
#endif
121
 
    if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
122
 
        ret != DRIZZLE_RETURN_OK)
 
300
    if (mysql_query(mysql, sql_statement))
123
301
    {
124
 
      db_error(con, &result, ret, tablename);
125
 
      return(1);
 
302
      db_error_with_table(mysql, tablename);
 
303
      DBUG_RETURN(1);
126
304
    }
127
 
    drizzle_result_free(&result);
128
305
  }
 
306
  to_unix_path(hard_path);
129
307
  if (verbose)
130
308
  {
131
309
    if (opt_local_file)
132
310
      fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
133
 
        hard_path, tablename);
 
311
              hard_path, tablename);
134
312
    else
135
313
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
136
 
        hard_path, tablename);
 
314
              hard_path, tablename);
137
315
  }
138
 
  snprintf(sql_statement, sizeof(sql_statement), "LOAD DATA %s %s INFILE '%s'",
139
 
    opt_low_priority ? "LOW_PRIORITY" : "",
140
 
    opt_local_file ? "LOCAL" : "", hard_path);
141
 
  end= strchr(sql_statement, '\0');
142
 
  if (opt_replace)
143
 
    end= strcpy(end, " REPLACE")+8;
144
 
  if (ignore_unique)
145
 
    end= strcpy(end, " IGNORE")+7;
146
 
 
147
 
  end+= sprintf(end, " INTO TABLE %s", tablename);
148
 
 
149
 
  if (! fields_terminated.empty() || ! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty())
150
 
      end= strcpy(end, " FIELDS")+7;
151
 
  end= add_load_option(end, (char *)fields_terminated.c_str(), " TERMINATED BY");
152
 
  end= add_load_option(end, (char *)enclosed.c_str(), " ENCLOSED BY");
153
 
  end= add_load_option(end, (char *)opt_enclosed.c_str(),
154
 
           " OPTIONALLY ENCLOSED BY");
155
 
  end= add_load_option(end, (char *)escaped.c_str(), " ESCAPED BY");
156
 
  end= add_load_option(end, (char *)lines_terminated.c_str(), " LINES TERMINATED BY");
 
316
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
 
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");
 
322
  if (ignore)
 
323
    end= strmov(end, " IGNORE");
 
324
  end= strmov(strmov(end, " INTO TABLE "), tablename);
 
325
 
 
326
  if (fields_terminated || enclosed || opt_enclosed || escaped)
 
327
      end= strmov(end, " FIELDS");
 
328
  end= add_load_option(end, fields_terminated, " TERMINATED BY");
 
329
  end= add_load_option(end, enclosed, " ENCLOSED BY");
 
330
  end= add_load_option(end, opt_enclosed,
 
331
                       " OPTIONALLY ENCLOSED BY");
 
332
  end= add_load_option(end, escaped, " ESCAPED BY");
 
333
  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
157
334
  if (opt_ignore_lines >= 0)
158
 
  {
159
 
    end= strcpy(end, " IGNORE ")+8;
160
 
    ostringstream buffer;
161
 
    buffer << opt_ignore_lines;
162
 
    end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
163
 
    end= strcpy(end, " LINES")+6;
164
 
  }
165
 
  if (! opt_columns.empty())
166
 
  {
167
 
    end= strcpy(end, " (")+2;
168
 
    end= strcpy(end, (char *)opt_columns.c_str()+opt_columns.length());
169
 
    end= strcpy(end, ")")+1;
170
 
  }
 
335
    end= strmov(longlong10_to_str(opt_ignore_lines, 
 
336
                                  strmov(end, " IGNORE "),10), " LINES");
 
337
  if (opt_columns)
 
338
    end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
171
339
  *end= '\0';
172
340
 
173
 
  if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
174
 
      ret != DRIZZLE_RETURN_OK)
 
341
  if (mysql_query(mysql, sql_statement))
175
342
  {
176
 
    db_error(con, &result, ret, tablename);
177
 
    return(1);
 
343
    db_error_with_table(mysql, tablename);
 
344
    DBUG_RETURN(1);
178
345
  }
179
346
  if (!silent)
180
347
  {
181
 
    if (strcmp(drizzle_result_info(&result), ""))
 
348
    if (mysql_info(mysql)) /* If NULL-pointer, print nothing */
182
349
    {
183
 
      fprintf(stdout, "%s.%s: %s\n", current_db.c_str(), tablename,
184
 
        drizzle_result_info(&result));
 
350
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
 
351
              mysql_info(mysql));
185
352
    }
186
353
  }
187
 
  drizzle_result_free(&result);
188
 
  return(0);
189
 
}
190
 
 
191
 
 
192
 
static drizzle_con_st *db_connect(const string host, const string database,
193
 
                                  const string user, const string passwd)
194
 
{
195
 
  drizzle_st *drizzle;
196
 
  drizzle_con_st *con;
197
 
  drizzle_return_t ret;
198
 
 
199
 
  if (verbose)
200
 
    fprintf(stdout, "Connecting to %s, using protocol %s...\n", ! host.empty() ? host.c_str() : "localhost", opt_protocol.c_str());
201
 
  if (!(drizzle= drizzle_create(NULL)))
202
 
    return 0;
203
 
  if (!(con= drizzle_con_add_tcp(drizzle,NULL,(char *)host.c_str(),opt_drizzle_port,(char *)user.c_str(),(char *)passwd.c_str(),
204
 
                                 (char *)database.c_str(), use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL)))
205
 
  {
206
 
    return 0;
207
 
  }
208
 
 
209
 
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
210
 
  {
211
 
    ignore_errors=0;    /* NO RETURN FROM db_error */
212
 
    db_error(con, NULL, ret, NULL);
213
 
  }
214
 
 
215
 
  if (verbose)
216
 
    fprintf(stdout, "Selecting database %s\n", database.c_str());
217
 
 
218
 
  return con;
219
 
}
220
 
 
221
 
 
222
 
 
223
 
static void db_disconnect(const string host, drizzle_con_st *con)
224
 
{
225
 
  if (verbose)
226
 
    fprintf(stdout, "Disconnecting from %s\n", ! host.empty() ? host.c_str() : "localhost");
227
 
  drizzle_free(drizzle_con_drizzle(con));
228
 
}
229
 
 
230
 
 
231
 
 
232
 
static void safe_exit(int error, drizzle_con_st *con)
 
354
  DBUG_RETURN(0);
 
355
}
 
356
 
 
357
 
 
358
 
 
359
static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
 
360
{
 
361
  DYNAMIC_STRING query;
 
362
  int i;
 
363
  char tablename[FN_REFLEN];
 
364
 
 
365
  if (verbose)
 
366
    fprintf(stdout, "Locking tables for write\n");
 
367
  init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
 
368
  for (i=0 ; i < tablecount ; i++)
 
369
  {
 
370
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
 
371
    dynstr_append(&query, tablename);
 
372
    dynstr_append(&query, " WRITE,");
 
373
  }
 
374
  if (mysql_real_query(mysql, query.str, query.length-1))
 
375
    db_error(mysql); /* We shall countinue here, if --force was given */
 
376
}
 
377
 
 
378
 
 
379
 
 
380
 
 
381
static MYSQL *db_connect(char *host, char *database,
 
382
                         char *user, char *passwd)
 
383
{
 
384
  MYSQL *mysql;
 
385
  if (verbose)
 
386
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
 
387
  if (!(mysql= mysql_init(NULL)))
 
388
    return 0;
 
389
  if (opt_compress)
 
390
    mysql_options(mysql,MYSQL_OPT_COMPRESS,NullS);
 
391
  if (opt_local_file)
 
392
    mysql_options(mysql,MYSQL_OPT_LOCAL_INFILE,
 
393
                  (char*) &opt_local_file);
 
394
  if (opt_protocol)
 
395
    mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
396
#ifdef HAVE_SMEM
 
397
  if (shared_memory_base_name)
 
398
    mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 
399
#endif
 
400
  if (!(mysql_real_connect(mysql,host,user,passwd,
 
401
                           database,opt_mysql_port,opt_mysql_unix_port,
 
402
                           0)))
 
403
  {
 
404
    ignore_errors=0;      /* NO RETURN FROM db_error */
 
405
    db_error(mysql);
 
406
  }
 
407
  mysql->reconnect= 0;
 
408
  if (verbose)
 
409
    fprintf(stdout, "Selecting database %s\n", database);
 
410
  if (mysql_select_db(mysql, database))
 
411
  {
 
412
    ignore_errors=0;
 
413
    db_error(mysql);
 
414
  }
 
415
  return mysql;
 
416
}
 
417
 
 
418
 
 
419
 
 
420
static void db_disconnect(char *host, MYSQL *mysql)
 
421
{
 
422
  if (verbose)
 
423
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
 
424
  mysql_close(mysql);
 
425
}
 
426
 
 
427
 
 
428
 
 
429
static void safe_exit(int error, MYSQL *mysql)
233
430
{
234
431
  if (ignore_errors)
235
432
    return;
236
 
  if (con)
237
 
    drizzle_free(drizzle_con_drizzle(con));
 
433
  if (mysql)
 
434
    mysql_close(mysql);
238
435
  exit(error);
239
436
}
240
437
 
241
438
 
242
439
 
243
 
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
244
 
                     drizzle_return_t ret, char *table)
245
 
{
246
 
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
247
 
  {
248
 
    fprintf(stdout, "Error: %d, %s%s%s",
249
 
            drizzle_result_error_code(result),
250
 
            drizzle_result_error(result),
251
 
            table ? ", when using table: " : "", table ? table : "");
252
 
    drizzle_result_free(result);
253
 
  }
254
 
  else
255
 
  {
256
 
    fprintf(stdout, "Error: %d, %s%s%s", ret, drizzle_con_error(con),
257
 
            table ? ", when using table: " : "", table ? table : "");
258
 
  }
259
 
 
260
 
  safe_exit(1, con);
 
440
static void db_error_with_table(MYSQL *mysql, char *table)
 
441
{
 
442
  my_printf_error(0,"Error: %d, %s, when using table: %s",
 
443
                  MYF(0), mysql_errno(mysql), mysql_error(mysql), table);
 
444
  safe_exit(1, mysql);
 
445
}
 
446
 
 
447
 
 
448
 
 
449
static void db_error(MYSQL *mysql)
 
450
{
 
451
  my_printf_error(0,"Error: %d %s", MYF(0), mysql_errno(mysql), mysql_error(mysql));
 
452
  safe_exit(1, mysql);
261
453
}
262
454
 
263
455
 
264
456
static char *add_load_option(char *ptr, const char *object,
265
 
           const char *statement)
 
457
                             const char *statement)
266
458
{
267
459
  if (object)
268
460
  {
269
461
    /* Don't escape hex constants */
270
462
    if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
271
 
      ptr+= sprintf(ptr, " %s %s", statement, object);
 
463
      ptr= strxmov(ptr," ",statement," ",object,NullS);
272
464
    else
273
465
    {
274
466
      /* char constant; escape */
275
 
      ptr+= sprintf(ptr, " %s '", statement); 
276
 
      ptr= field_escape(ptr,object,(uint32_t) strlen(object));
 
467
      ptr= strxmov(ptr," ",statement," '",NullS);
 
468
      ptr= field_escape(ptr,object,(uint) strlen(object));
277
469
      *ptr++= '\'';
278
470
    }
279
471
  }
285
477
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
286
478
** This is done by doubleing ' and add a end -\ if needed to avoid
287
479
** syntax errors from the SQL parser.
288
 
*/
 
480
*/ 
289
481
 
290
 
static char *field_escape(char *to,const char *from,uint32_t length)
 
482
static char *field_escape(char *to,const char *from,uint length)
291
483
{
292
484
  const char *end;
293
 
  uint32_t end_backslashes=0;
 
485
  uint end_backslashes=0; 
294
486
 
295
487
  for (end= from+length; from != end; from++)
296
488
  {
297
489
    *to++= *from;
298
490
    if (*from == '\\')
299
491
      end_backslashes^=1;    /* find odd number of backslashes */
300
 
    else
 
492
    else 
301
493
    {
302
494
      if (*from == '\'' && !end_backslashes)
303
 
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
 
495
        *to++= *from;      /* We want a dublicate of "'" for MySQL */
304
496
      end_backslashes=0;
305
497
    }
306
498
  }
307
499
  /* Add missing backslashes if user has specified odd number of backs.*/
308
500
  if (end_backslashes)
309
 
    *to++= '\\';
 
501
    *to++= '\\';          
310
502
  return to;
311
503
}
312
504
 
313
 
void * worker_thread(void *arg)
 
505
int exitcode= 0;
 
506
 
 
507
#ifdef HAVE_LIBPTHREAD
 
508
static pthread_handler_t worker_thread(void *arg)
314
509
{
315
510
  int error;
316
511
  char *raw_table_name= (char *)arg;
317
 
  drizzle_con_st *con;
318
 
 
319
 
  if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
320
 
  {
321
 
    return 0;
 
512
  MYSQL *mysql= 0;
 
513
 
 
514
  if (mysql_thread_init())
 
515
    goto error;
 
516
  
 
517
  if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
 
518
  {
 
519
    goto error;
 
520
  }
 
521
 
 
522
  if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
 
523
  {
 
524
    db_error(mysql); /* We shall countinue here, if --force was given */
 
525
    goto error;
322
526
  }
323
527
 
324
528
  /*
325
529
    We are not currently catching the error here.
326
530
  */
327
 
  if ((error= write_to_table(raw_table_name, con)))
328
 
  {
 
531
  if((error= write_to_table(raw_table_name, mysql)))
329
532
    if (exitcode == 0)
330
 
    {
331
533
      exitcode= error;
332
 
    }
333
 
  }
334
534
 
335
 
  if (con)
336
 
  {
337
 
    db_disconnect(current_host, con);
338
 
  }
 
535
error:
 
536
  if (mysql)
 
537
    db_disconnect(current_host, mysql);
339
538
 
340
539
  pthread_mutex_lock(&counter_mutex);
341
540
  counter--;
342
541
  pthread_cond_signal(&count_threshhold);
343
542
  pthread_mutex_unlock(&counter_mutex);
 
543
  my_thread_end();
344
544
 
345
545
  return 0;
346
546
}
 
547
#endif
347
548
 
348
549
 
349
550
int main(int argc, char **argv)
350
551
{
351
 
try
352
 
{
353
552
  int error=0;
354
 
 
355
 
  po::options_description commandline_options("Options used only in command line");
356
 
  commandline_options.add_options()
357
 
 
358
 
  ("debug,#", po::value<string>(),
359
 
  "Output debug log. Often this is 'd:t:o,filename'.")
360
 
  ("delete,d", po::value<bool>(&opt_delete)->default_value(false)->zero_tokens(),
361
 
  "First delete all rows from table.")
362
 
  ("help,?", "Displays this help and exits.")
363
 
  ("ignore,i", po::value<bool>(&ignore_unique)->default_value(false)->zero_tokens(),
364
 
  "If duplicate unique key was found, keep old row.")
365
 
  ("low-priority", po::value<bool>(&opt_low_priority)->default_value(false)->zero_tokens(),
366
 
  "Use LOW_PRIORITY when updating the table.")
367
 
  ("replace,r", po::value<bool>(&opt_replace)->default_value(false)->zero_tokens(),
368
 
  "If duplicate unique key was found, replace old row.")
369
 
  ("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
370
 
  "Print info about the various stages.")
371
 
  ("version,V", "Output version information and exit.")
372
 
  ;
373
 
 
374
 
  po::options_description import_options("Options specific to the drizzleimport");
375
 
  import_options.add_options()
376
 
  ("columns,C", po::value<string>(&opt_columns)->default_value(""),
377
 
  "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.")
378
 
  ("fields-terminated-by", po::value<string>(&fields_terminated)->default_value(""),
379
 
  "Fields in the textfile are terminated by ...")
380
 
  ("fields-enclosed-by", po::value<string>(&enclosed)->default_value(""),
381
 
  "Fields in the importfile are enclosed by ...")
382
 
  ("fields-optionally-enclosed-by", po::value<string>(&opt_enclosed)->default_value(""),
383
 
  "Fields in the i.file are opt. enclosed by ...")
384
 
  ("fields-escaped-by", po::value<string>(&escaped)->default_value(""),
385
 
  "Fields in the i.file are escaped by ...")
386
 
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
387
 
  "Continue even if we get an sql-error.")
388
 
  ("ignore-lines", po::value<int64_t>(&opt_ignore_lines)->default_value(0),
389
 
  "Ignore first n lines of data infile.")
390
 
  ("lines-terminated-by", po::value<string>(&lines_terminated)->default_value(""),
391
 
  "Lines in the i.file are terminated by ...")
392
 
  ("local,L", po::value<bool>(&opt_local_file)->default_value(false)->zero_tokens(),
393
 
  "Read all files through the client.")
394
 
  ("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
395
 
  "Be more silent.")
396
 
  ("use-threads", po::value<uint32_t>(&opt_use_threads)->default_value(4),
397
 
  "Load files in parallel. The argument is the number of threads to use for loading data (default is 4.")
398
 
  ;
399
 
 
400
 
  po::options_description client_options("Options specific to the client");
401
 
  client_options.add_options()
402
 
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
403
 
  "Connect to host.")
404
 
  ("password,P", po::value<string>(&password),
405
 
  "Password to use when connecting to server. If password is not given it's asked from the tty." )
406
 
  ("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
407
 
  "Port number to use for connection") 
408
 
  ("protocol", po::value<string>(&opt_protocol)->default_value("mysql"),
409
 
  "The protocol of connection (mysql or drizzle).")
410
 
  ("user,u", po::value<string>(&current_user)->default_value(""),
411
 
  "User for login if not current user.")
412
 
  ;
413
 
 
414
 
  po::options_description long_options("Allowed Options");
415
 
  long_options.add(commandline_options).add(import_options).add(client_options);
416
 
 
417
 
  std::string system_config_dir_import(SYSCONFDIR); 
418
 
  system_config_dir_import.append("/drizzle/drizzleimport.cnf");
419
 
 
420
 
  std::string system_config_dir_client(SYSCONFDIR); 
421
 
  system_config_dir_client.append("/drizzle/client.cnf");
422
 
  
423
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
424
 
 
425
 
  po::variables_map vm;
426
 
 
427
 
  // Disable allow_guessing
428
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
429
 
 
430
 
  po::store(po::command_line_parser(argc, argv).options(long_options).
431
 
            style(style).extra_parser(parse_password_arg).run(), vm);
432
 
 
433
 
  std::string user_config_dir_import(user_config_dir);
434
 
  user_config_dir_import.append("/drizzle/drizzleimport.cnf"); 
435
 
 
436
 
  std::string user_config_dir_client(user_config_dir);
437
 
  user_config_dir_client.append("/drizzle/client.cnf");
438
 
 
439
 
  ifstream user_import_ifs(user_config_dir_import.c_str());
440
 
  po::store(parse_config_file(user_import_ifs, import_options), vm);
441
 
 
442
 
  ifstream user_client_ifs(user_config_dir_client.c_str());
443
 
  po::store(parse_config_file(user_client_ifs, client_options), vm);
444
 
 
445
 
  ifstream system_import_ifs(system_config_dir_import.c_str());
446
 
  store(parse_config_file(system_import_ifs, import_options), vm);
447
 
 
448
 
  ifstream system_client_ifs(system_config_dir_client.c_str());
449
 
  po::store(parse_config_file(system_client_ifs, client_options), vm);
450
 
 
451
 
  po::notify(vm);
452
 
  if (vm.count("protocol"))
453
 
  {
454
 
    std::transform(opt_protocol.begin(), opt_protocol.end(),
455
 
      opt_protocol.begin(), ::tolower);
456
 
 
457
 
    if (not opt_protocol.compare("mysql"))
458
 
      use_drizzle_protocol=false;
459
 
    else if (not opt_protocol.compare("drizzle"))
460
 
      use_drizzle_protocol=true;
461
 
    else
462
 
    {
463
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
464
 
      exit(-1);
465
 
    }
466
 
  }
467
 
 
468
 
  if (vm.count("port"))
469
 
  {
470
 
    
471
 
    /* If the port number is > 65535 it is not a valid port
472
 
       This also helps with potential data loss casting unsigned long to a
473
 
       uint32_t. */
474
 
    if (opt_drizzle_port > 65535)
475
 
    {
476
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
477
 
      exit(EXIT_ARGUMENT_INVALID);
478
 
    }
479
 
  }
480
 
 
481
 
  if( vm.count("password") )
482
 
  {
483
 
    if (!opt_password.empty())
484
 
      opt_password.erase();
485
 
    if (password == PASSWORD_SENTINEL)
486
 
    {
487
 
      opt_password= "";
488
 
    }
489
 
    else
490
 
    {
491
 
      opt_password= password;
492
 
      tty_password= false;
493
 
    }
494
 
  }
495
 
  else
496
 
  {
497
 
      tty_password= true;
498
 
  }
499
 
 
500
 
 
501
 
  if (vm.count("version"))
502
 
  {
503
 
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
504
 
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
505
 
  }
506
 
  
507
 
  if (vm.count("help") || argc < 2)
508
 
  {
509
 
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
510
 
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
511
 
    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");
512
 
    printf("\
513
 
    Loads tables from text files in various formats.  The base name of the\n\
514
 
    text file must be the name of the table that should be used.\n\
515
 
    If one uses sockets to connect to the Drizzle server, the server will open and\n\
516
 
    read the text file directly. In other cases the client will open the text\n\
517
 
    file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
518
 
 
519
 
    printf("\nUsage: %s [OPTIONS] database textfile...", program_name);
520
 
    cout<<long_options;
521
 
    exit(0);
522
 
  }
523
 
 
524
 
 
525
 
  if (get_options())
526
 
  {
 
553
  char **argv_to_free;
 
554
  MY_INIT(argv[0]);
 
555
 
 
556
  load_defaults("my",load_default_groups,&argc,&argv);
 
557
  /* argv is changed in the program */
 
558
  argv_to_free= argv;
 
559
  if (get_options(&argc, &argv))
 
560
  {
 
561
    free_defaults(argv_to_free);
527
562
    return(1);
528
563
  }
529
 
  
530
 
  current_db= (*argv)++;
531
 
  argc--;
532
564
 
533
 
  if (opt_use_threads)
 
565
#ifdef HAVE_LIBPTHREAD
 
566
  if (opt_use_threads && !lock_tables)
534
567
  {
535
568
    pthread_t mainthread;            /* Thread descriptor */
536
569
    pthread_attr_t attr;          /* Thread attributes */
538
571
    pthread_attr_setdetachstate(&attr,
539
572
                                PTHREAD_CREATE_DETACHED);
540
573
 
541
 
    pthread_mutex_init(&counter_mutex, NULL);
542
 
    pthread_cond_init(&count_threshhold, NULL);
 
574
    VOID(pthread_mutex_init(&counter_mutex, NULL));
 
575
    VOID(pthread_cond_init(&count_threshhold, NULL));
543
576
 
544
577
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
545
578
    {
555
588
      counter++;
556
589
      pthread_mutex_unlock(&counter_mutex);
557
590
      /* now create the thread */
558
 
      if (pthread_create(&mainthread, &attr, worker_thread,
 
591
      if (pthread_create(&mainthread, &attr, worker_thread, 
559
592
                         (void *)*argv) != 0)
560
593
      {
561
594
        pthread_mutex_lock(&counter_mutex);
562
595
        counter--;
563
596
        pthread_mutex_unlock(&counter_mutex);
564
 
        fprintf(stderr,"%s: Could not create thread\n", program_name);
 
597
        fprintf(stderr,"%s: Could not create thread\n",
 
598
                my_progname);
565
599
      }
566
600
    }
567
601
 
577
611
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
578
612
    }
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);
583
617
  }
584
618
  else
 
619
#endif
585
620
  {
586
 
    drizzle_con_st *con;
 
621
    MYSQL *mysql= 0;
 
622
    if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
 
623
    {
 
624
      free_defaults(argv_to_free);
 
625
      return(1); /* purecov: deadcode */
 
626
    }
587
627
 
588
 
    if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
 
628
    if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
589
629
    {
 
630
      db_error(mysql); /* We shall countinue here, if --force was given */
590
631
      return(1);
591
632
    }
592
633
 
 
634
    if (lock_tables)
 
635
      lock_table(mysql, argc, argv);
593
636
    for (; *argv != NULL; argv++)
594
 
      if ((error= write_to_table(*argv, con)))
 
637
      if ((error= write_to_table(*argv, mysql)))
595
638
        if (exitcode == 0)
596
639
          exitcode= error;
597
 
    db_disconnect(current_host, con);
598
 
  }
599
 
  opt_password.empty();
600
 
}
601
 
  catch(exception &err)
602
 
  {
603
 
    cerr<<err.what()<<endl;
604
 
  }
 
640
    db_disconnect(current_host, mysql);
 
641
  }
 
642
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
643
#ifdef HAVE_SMEM
 
644
  my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
645
#endif
 
646
  free_defaults(argv_to_free);
 
647
  my_end(my_end_arg);
605
648
  return(exitcode);
606
649
}