~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleimport.cc

Merge Monty.

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
   Copyright (C) 2008-2009 Sun Microsystems, Inc
2
3
 
3
4
   This program is free software; you can redistribute it and/or modify
4
5
   it under the terms of the GNU General Public License as published by
27
28
#define IMPORT_VERSION "3.7"
28
29
 
29
30
#include "client_priv.h"
30
 
#include "drizzle_version.h"
31
 
#include <my_pthread.h>
32
 
 
 
31
#include <string>
 
32
#include <sstream>
 
33
 
 
34
#include <pthread.h>
 
35
 
 
36
/* Added this for string translation. */
 
37
#include <drizzled/gettext.h>
 
38
 
 
39
using namespace std;
 
40
 
 
41
extern "C"
 
42
{
 
43
  bool get_one_option(int optid, const struct my_option *, char *argument);
 
44
  void * worker_thread(void *arg);
 
45
}
 
46
 
 
47
int exitcode= 0;
33
48
 
34
49
/* Global Thread counter */
35
 
uint counter;
 
50
uint32_t counter;
36
51
pthread_mutex_t counter_mutex;
37
52
pthread_cond_t count_threshhold;
38
53
 
39
 
static void db_error_with_table(DRIZZLE *drizzle, char *table);
40
 
static void db_error(DRIZZLE *drizzle);
41
 
static char *field_escape(char *to,const char *from,uint length);
 
54
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
 
55
                     drizzle_return_t ret, char *table);
 
56
static char *field_escape(char *to,const char *from,uint32_t length);
42
57
static char *add_load_option(char *ptr,const char *object,
43
58
           const char *statement);
44
59
 
45
 
static bool  verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
46
 
    replace=0,silent=0,ignore=0,opt_compress=0,
47
 
                opt_low_priority= 0, tty_password= 0;
48
 
static bool debug_info_flag= 0, debug_check_flag= 0;
49
 
static uint opt_use_threads=0, opt_local_file=0, my_end_arg= 0;
50
 
static char  *opt_password=0, *current_user=0,
51
 
    *current_host=0, *current_db=0, *fields_terminated=0,
52
 
    *lines_terminated=0, *enclosed=0, *opt_enclosed=0,
53
 
    *escaped=0, *opt_columns=0,
54
 
    *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
55
 
static uint     opt_drizzle_port= 0, opt_protocol= 0;
56
 
static char * opt_drizzle_unix_port=0;
 
60
static bool verbose= false, lock_tables= false, ignore_errors= false,
 
61
            opt_delete= false, opt_replace= false, silent= false,
 
62
            ignore_unique= false, opt_low_priority= false,
 
63
            tty_password= false;
 
64
 
 
65
static uint32_t opt_use_threads= 0, opt_local_file= 0;
 
66
static char  *opt_password= NULL, *current_user= NULL,
 
67
    *current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
 
68
    *lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
 
69
    *escaped= NULL, *opt_columns= NULL;
 
70
static uint32_t opt_drizzle_port= 0;
 
71
static char * opt_drizzle_unix_port= 0;
57
72
static int64_t opt_ignore_lines= -1;
58
 
static CHARSET_INFO *charset_info= &my_charset_latin1;
59
73
 
60
74
static struct my_option my_long_options[] =
61
75
{
62
 
  {"character-sets-dir", OPT_CHARSETS_DIR,
63
 
   "Directory where character sets are.", (char**) &charsets_dir,
64
 
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
65
 
  {"default-character-set", OPT_DEFAULT_CHARSET,
66
 
   "Set the default character set.", (char**) &default_charset,
67
 
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
68
76
  {"columns", 'c',
69
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.",
70
78
   (char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
71
79
   0, 0, 0},
72
 
  {"compress", 'C', "Use compression in server/client protocol.",
73
 
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
74
 
   0, 0, 0},
75
80
  {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
76
81
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
77
 
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
78
 
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
79
 
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
80
 
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
81
 
   (char**) &debug_info_flag, (char**) &debug_info_flag,
82
 
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
83
82
  {"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
84
83
   (char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
85
84
  {"fields-terminated-by", OPT_FTB,
102
101
  {"host", 'h', "Connect to host.", (char**) &current_host,
103
102
   (char**) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
104
103
  {"ignore", 'i', "If duplicate unique key was found, keep old row.",
105
 
   (char**) &ignore, (char**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
104
   (char**) &ignore_unique, (char**) &ignore_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
106
105
  {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
107
106
   (char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
108
107
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
117
116
  {"low-priority", OPT_LOW_PRIORITY,
118
117
   "Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
119
118
   (char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
120
 
  {"password", 'p',
 
119
  {"password", 'P',
121
120
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
122
121
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
123
 
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
124
 
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
125
 
#if MYSQL_PORT_DEFAULT == 0
126
 
   "/etc/services, "
127
 
#endif
128
 
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
129
 
   (char**) &opt_drizzle_port,
130
 
   (char**) &opt_drizzle_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
131
 
   0},
 
122
  {"port", 'p', "Port number to use for connection or 0 for default to, in "
 
123
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
 
124
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
125
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
132
126
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
133
127
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
134
128
  {"replace", 'r', "If duplicate unique key was found, replace old row.",
135
 
   (char**) &replace, (char**) &replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
129
   (char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
136
130
  {"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
137
131
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
138
132
  {"socket", 'S', "Socket file to use for connection.",
143
137
   "of threads to use for loading data.",
144
138
   (char**) &opt_use_threads, (char**) &opt_use_threads, 0,
145
139
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
146
 
#ifndef DONT_ALLOW_USER_CHANGE
147
140
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
148
141
   (char**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
149
 
#endif
150
142
  {"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
151
143
   (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
152
144
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
159
151
 
160
152
static void print_version(void)
161
153
{
162
 
  printf("%s  Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
163
 
    IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
 
154
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n" ,my_progname,
 
155
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
164
156
}
165
157
 
166
158
 
177
169
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
178
170
 
179
171
  printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
180
 
  print_defaults("my",load_default_groups);
 
172
  print_defaults("drizzle",load_default_groups);
181
173
  my_print_help(my_long_options);
182
174
  my_print_variables(my_long_options);
183
175
}
184
176
 
185
 
static bool
186
 
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
187
 
         char *argument)
 
177
bool get_one_option(int optid, const struct my_option *, char *argument)
188
178
{
 
179
  char *endchar= NULL;
 
180
  uint64_t temp_drizzle_port= 0;
 
181
 
189
182
  switch(optid) {
190
183
  case 'p':
 
184
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
185
    /* if there is an alpha character this is not a valid port */
 
186
    if (strlen(endchar) != 0)
 
187
    {
 
188
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
 
189
      exit(1);
 
190
    }
 
191
    /* If the port number is > 65535 it is not a valid port
 
192
       This also helps with potential data loss casting unsigned long to a
 
193
       uint32_t. */
 
194
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
195
    {
 
196
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
 
197
      exit(1);
 
198
    }
 
199
    else
 
200
    {
 
201
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
202
    }
 
203
    break;
 
204
  case 'P':
191
205
    if (argument)
192
206
    {
193
207
      char *start=argument;
194
 
      my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
195
 
      opt_password=my_strdup(argument,MYF(MY_FAE));
196
 
      while (*argument) *argument++= 'x';    /* Destroy argument */
 
208
      if (opt_password)
 
209
        free(opt_password);
 
210
      opt_password = strdup(argument);
 
211
      if (opt_password == NULL)
 
212
      {
 
213
        fprintf(stderr, "Memory allocation error while copying password. "
 
214
                        "Aborting.\n");
 
215
        exit(ENOMEM);
 
216
      }
 
217
      while (*argument)
 
218
      {
 
219
        /* Overwriting password with 'x' */
 
220
        *argument++= 'x';
 
221
      }
197
222
      if (*start)
198
 
  start[1]=0;        /* Cut length of argument */
 
223
      {
 
224
        /* Cut length of argument */
 
225
        start[1]= 0;
 
226
      }
199
227
      tty_password= 0;
200
228
    }
201
229
    else
202
230
      tty_password= 1;
203
231
    break;
204
232
  case OPT_DRIZZLE_PROTOCOL:
205
 
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
206
 
                                    opt->name);
207
233
    break;
208
234
  case 'V': print_version(); exit(0);
209
235
  case 'I':
221
247
 
222
248
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
223
249
    exit(ho_error);
224
 
  if (debug_info_flag)
225
 
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
226
 
  if (debug_check_flag)
227
 
    my_end_arg= MY_CHECK_ERROR;
228
250
 
229
251
  if (enclosed && opt_enclosed)
230
252
  {
231
253
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
232
254
    return(1);
233
255
  }
234
 
  if (replace && ignore)
 
256
  if (opt_replace && ignore_unique)
235
257
  {
236
 
    fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
 
258
    fprintf(stderr, "You can't use --ignore_unique (-i) and --replace (-r) at the same time.\n");
237
259
    return(1);
238
260
  }
239
 
  if (strcmp(default_charset, charset_info->csname) &&
240
 
      !(charset_info= get_charset_by_csname(default_charset,
241
 
                MY_CS_PRIMARY, MYF(MY_WME))))
242
 
    exit(1);
243
261
  if (*argc < 2)
244
262
  {
245
263
    usage();
248
266
  current_db= *((*argv)++);
249
267
  (*argc)--;
250
268
  if (tty_password)
251
 
    opt_password=get_tty_password(NullS);
 
269
    opt_password=client_get_tty_password(NULL);
252
270
  return(0);
253
271
}
254
272
 
255
273
 
256
274
 
257
 
static int write_to_table(char *filename, DRIZZLE *drizzle)
 
275
static int write_to_table(char *filename, drizzle_con_st *con)
258
276
{
259
277
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
260
278
       sql_statement[FN_REFLEN*16+256], *end;
 
279
  drizzle_result_st result;
 
280
  drizzle_return_t ret;
261
281
 
262
282
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
263
283
  if (!opt_local_file)
264
 
    strmov(hard_path,filename);
 
284
    strcpy(hard_path,filename);
265
285
  else
266
286
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
267
287
 
274
294
#else
275
295
    sprintf(sql_statement, "DELETE FROM %s", tablename);
276
296
#endif
277
 
    if (drizzle_query(drizzle, sql_statement))
 
297
    if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
 
298
        ret != DRIZZLE_RETURN_OK)
278
299
    {
279
 
      db_error_with_table(drizzle, tablename);
 
300
      db_error(con, &result, ret, tablename);
280
301
      return(1);
281
302
    }
 
303
    drizzle_result_free(&result);
282
304
  }
283
 
  to_unix_path(hard_path);
284
305
  if (verbose)
285
306
  {
286
307
    if (opt_local_file)
293
314
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
294
315
    opt_low_priority ? "LOW_PRIORITY" : "",
295
316
    opt_local_file ? "LOCAL" : "", hard_path);
296
 
  end= strend(sql_statement);
297
 
  if (replace)
298
 
    end= strmov(end, " REPLACE");
299
 
  if (ignore)
300
 
    end= strmov(end, " IGNORE");
301
 
  end= strmov(strmov(end, " INTO TABLE "), tablename);
 
317
  end= strchr(sql_statement, '\0');
 
318
  if (opt_replace)
 
319
    end= strcpy(end, " REPLACE")+8;
 
320
  if (ignore_unique)
 
321
    end= strcpy(end, " IGNORE")+7;
 
322
 
 
323
  end+= sprintf(end, " INTO TABLE %s", tablename);
302
324
 
303
325
  if (fields_terminated || enclosed || opt_enclosed || escaped)
304
 
      end= strmov(end, " FIELDS");
 
326
      end= strcpy(end, " FIELDS")+7;
305
327
  end= add_load_option(end, fields_terminated, " TERMINATED BY");
306
328
  end= add_load_option(end, enclosed, " ENCLOSED BY");
307
329
  end= add_load_option(end, opt_enclosed,
309
331
  end= add_load_option(end, escaped, " ESCAPED BY");
310
332
  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
311
333
  if (opt_ignore_lines >= 0)
312
 
    end= strmov(int64_t10_to_str(opt_ignore_lines,
313
 
          strmov(end, " IGNORE "),10), " LINES");
 
334
  {
 
335
    end= strcpy(end, " IGNORE ")+8;
 
336
    ostringstream buffer;
 
337
    buffer << opt_ignore_lines;
 
338
    end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
 
339
    end= strcpy(end, " LINES")+6;
 
340
  }
314
341
  if (opt_columns)
315
 
    end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
 
342
  {
 
343
    end= strcpy(end, " (")+2;
 
344
    end= strcpy(end, opt_columns)+strlen(opt_columns);
 
345
    end= strcpy(end, ")")+1;
 
346
  }
316
347
  *end= '\0';
317
348
 
318
 
  if (drizzle_query(drizzle, sql_statement))
 
349
  if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
 
350
      ret != DRIZZLE_RETURN_OK)
319
351
  {
320
 
    db_error_with_table(drizzle, tablename);
 
352
    db_error(con, &result, ret, tablename);
321
353
    return(1);
322
354
  }
323
355
  if (!silent)
324
356
  {
325
 
    if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
 
357
    if (strcmp(drizzle_result_info(&result), ""))
326
358
    {
327
359
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
328
 
        drizzle_info(drizzle));
 
360
        drizzle_result_info(&result));
329
361
    }
330
362
  }
 
363
  drizzle_result_free(&result);
331
364
  return(0);
332
365
}
333
366
 
334
367
 
335
 
 
336
 
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
 
368
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
337
369
{
338
 
  DYNAMIC_STRING query;
 
370
  string query;
339
371
  int i;
340
372
  char tablename[FN_REFLEN];
 
373
  drizzle_result_st result;
 
374
  drizzle_return_t ret;
341
375
 
342
376
  if (verbose)
343
377
    fprintf(stdout, "Locking tables for write\n");
344
 
  init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
 
378
  query.append("LOCK TABLES ");
345
379
  for (i=0 ; i < tablecount ; i++)
346
380
  {
347
381
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
348
 
    dynstr_append(&query, tablename);
349
 
    dynstr_append(&query, " WRITE,");
350
 
  }
351
 
  if (drizzle_real_query(drizzle, query.str, query.length-1))
352
 
    db_error(drizzle); /* We shall countinue here, if --force was given */
 
382
    query.append(tablename);
 
383
    query.append(" WRITE,");
 
384
  }
 
385
  if (drizzle_query(con, &result, query.c_str(), query.length()-1,
 
386
                    &ret) == NULL ||
 
387
      ret != DRIZZLE_RETURN_OK)
 
388
  {
 
389
    db_error(con, &result, ret, NULL);
 
390
    /* We shall countinue here, if --force was given */
 
391
    return;
 
392
  }
 
393
  drizzle_result_free(&result);
353
394
}
354
395
 
355
396
 
356
 
 
357
 
 
358
 
static DRIZZLE *db_connect(char *host, char *database,
359
 
                         char *user, char *passwd)
 
397
static drizzle_con_st *db_connect(char *host, char *database,
 
398
                                  char *user, char *passwd)
360
399
{
361
 
  DRIZZLE *drizzle;
 
400
  drizzle_st *drizzle;
 
401
  drizzle_con_st *con;
 
402
  drizzle_return_t ret;
 
403
 
362
404
  if (verbose)
363
405
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
364
406
  if (!(drizzle= drizzle_create(NULL)))
365
407
    return 0;
366
 
  if (opt_compress)
367
 
    drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NullS);
368
 
  if (opt_local_file)
369
 
    drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
370
 
      (char*) &opt_local_file);
371
 
  if (opt_protocol)
372
 
    drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
373
 
  if (!(drizzle_connect(drizzle,host,user,passwd,
374
 
                           database,opt_drizzle_port,opt_drizzle_unix_port,
375
 
                           0)))
 
408
  if (!(con= drizzle_con_add_tcp(drizzle,NULL,host,opt_drizzle_port,user,passwd,
 
409
                                 database, DRIZZLE_CON_NONE)))
 
410
  {
 
411
    return 0;
 
412
  }
 
413
 
 
414
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
376
415
  {
377
416
    ignore_errors=0;    /* NO RETURN FROM db_error */
378
 
    db_error(drizzle);
 
417
    db_error(con, NULL, ret, NULL);
379
418
  }
380
 
  drizzle->reconnect= 0;
 
419
 
381
420
  if (verbose)
382
421
    fprintf(stdout, "Selecting database %s\n", database);
383
 
  if (drizzle_select_db(drizzle, database))
384
 
  {
385
 
    ignore_errors=0;
386
 
    db_error(drizzle);
387
 
  }
388
 
  return drizzle;
 
422
 
 
423
  return con;
389
424
}
390
425
 
391
426
 
392
427
 
393
 
static void db_disconnect(char *host, DRIZZLE *drizzle)
 
428
static void db_disconnect(char *host, drizzle_con_st *con)
394
429
{
395
430
  if (verbose)
396
431
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
397
 
  drizzle_close(drizzle);
 
432
  drizzle_free(drizzle_con_drizzle(con));
398
433
}
399
434
 
400
435
 
401
436
 
402
 
static void safe_exit(int error, DRIZZLE *drizzle)
 
437
static void safe_exit(int error, drizzle_con_st *con)
403
438
{
404
439
  if (ignore_errors)
405
440
    return;
406
 
  if (drizzle)
407
 
    drizzle_close(drizzle);
 
441
  if (con)
 
442
    drizzle_free(drizzle_con_drizzle(con));
408
443
  exit(error);
409
444
}
410
445
 
411
446
 
412
447
 
413
 
static void db_error_with_table(DRIZZLE *drizzle, char *table)
414
 
{
415
 
  my_printf_error(0,"Error: %d, %s, when using table: %s",
416
 
      MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
417
 
  safe_exit(1, drizzle);
418
 
}
419
 
 
420
 
 
421
 
 
422
 
static void db_error(DRIZZLE *drizzle)
423
 
{
424
 
  my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
425
 
  safe_exit(1, drizzle);
 
448
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
 
449
                     drizzle_return_t ret, char *table)
 
450
{
 
451
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
 
452
  {
 
453
    my_printf_error(0,"Error: %d, %s%s%s", MYF(0),
 
454
                    drizzle_result_error_code(result),
 
455
                    drizzle_result_error(result),
 
456
                    table ? ", when using table: " : "", table ? table : "");
 
457
    drizzle_result_free(result);
 
458
  }
 
459
  else
 
460
  {
 
461
    my_printf_error(0,"Error: %d, %s%s%s", MYF(0), ret, drizzle_con_error(con),
 
462
                    table ? ", when using table: " : "", table ? table : "");
 
463
  }
 
464
 
 
465
  safe_exit(1, con);
426
466
}
427
467
 
428
468
 
433
473
  {
434
474
    /* Don't escape hex constants */
435
475
    if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
436
 
      ptr= strxmov(ptr," ",statement," ",object,NullS);
 
476
      ptr+= sprintf(ptr, " %s %s", statement, object);
437
477
    else
438
478
    {
439
479
      /* char constant; escape */
440
 
      ptr= strxmov(ptr," ",statement," '",NullS);
441
 
      ptr= field_escape(ptr,object,(uint) strlen(object));
 
480
      ptr+= sprintf(ptr, " %s '", statement); 
 
481
      ptr= field_escape(ptr,object,(uint32_t) strlen(object));
442
482
      *ptr++= '\'';
443
483
    }
444
484
  }
452
492
** syntax errors from the SQL parser.
453
493
*/
454
494
 
455
 
static char *field_escape(char *to,const char *from,uint length)
 
495
static char *field_escape(char *to,const char *from,uint32_t length)
456
496
{
457
497
  const char *end;
458
 
  uint end_backslashes=0;
 
498
  uint32_t end_backslashes=0;
459
499
 
460
500
  for (end= from+length; from != end; from++)
461
501
  {
471
511
  }
472
512
  /* Add missing backslashes if user has specified odd number of backs.*/
473
513
  if (end_backslashes)
474
 
    *to++= '\\';         
 
514
    *to++= '\\';
475
515
  return to;
476
516
}
477
517
 
478
 
int exitcode= 0;
479
 
 
480
 
static pthread_handler_t worker_thread(void *arg)
 
518
void * worker_thread(void *arg)
481
519
{
482
520
  int error;
483
521
  char *raw_table_name= (char *)arg;
484
 
  DRIZZLE *drizzle= 0;
 
522
  drizzle_con_st *con= NULL;
 
523
  drizzle_result_st result;
 
524
  drizzle_return_t ret;
485
525
 
486
 
  if (drizzle_thread_init())
487
 
    goto error;
488
 
 
489
 
  if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
 
526
  if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
490
527
  {
491
528
    goto error;
492
529
  }
493
530
 
494
 
  if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
 
531
  if (drizzle_query_str(con, &result,
 
532
                        "/*!40101 set @@character_set_database=binary */;",
 
533
                        &ret) == NULL ||
 
534
      ret != DRIZZLE_RETURN_OK)
495
535
  {
496
 
    db_error(drizzle); /* We shall countinue here, if --force was given */
 
536
    db_error(con, &result, ret, NULL);
 
537
    /* We shall countinue here, if --force was given */
497
538
    goto error;
498
539
  }
499
540
 
500
541
  /*
501
542
    We are not currently catching the error here.
502
543
  */
503
 
  if((error= write_to_table(raw_table_name, drizzle)))
 
544
  if((error= write_to_table(raw_table_name, con)))
504
545
    if (exitcode == 0)
505
546
      exitcode= error;
506
547
 
507
548
error:
508
 
  if (drizzle)
509
 
    db_disconnect(current_host, drizzle);
 
549
  if (con)
 
550
    db_disconnect(current_host, con);
510
551
 
511
552
  pthread_mutex_lock(&counter_mutex);
512
553
  counter--;
524
565
  char **argv_to_free;
525
566
  MY_INIT(argv[0]);
526
567
 
527
 
  load_defaults("my",load_default_groups,&argc,&argv);
 
568
  load_defaults("drizzle",load_default_groups,&argc,&argv);
528
569
  /* argv is changed in the program */
529
570
  argv_to_free= argv;
530
571
  if (get_options(&argc, &argv))
542
583
    pthread_attr_setdetachstate(&attr,
543
584
                                PTHREAD_CREATE_DETACHED);
544
585
 
545
 
    VOID(pthread_mutex_init(&counter_mutex, NULL));
546
 
    VOID(pthread_cond_init(&count_threshhold, NULL));
 
586
    pthread_mutex_init(&counter_mutex, NULL);
 
587
    pthread_cond_init(&count_threshhold, NULL);
547
588
 
548
589
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
549
590
    {
582
623
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
583
624
    }
584
625
    pthread_mutex_unlock(&counter_mutex);
585
 
    VOID(pthread_mutex_destroy(&counter_mutex));
586
 
    VOID(pthread_cond_destroy(&count_threshhold));
 
626
    pthread_mutex_destroy(&counter_mutex);
 
627
    pthread_cond_destroy(&count_threshhold);
587
628
    pthread_attr_destroy(&attr);
588
629
  }
589
630
  else
590
631
#endif
591
632
  {
592
 
    DRIZZLE *drizzle= 0;
593
 
    if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
 
633
    drizzle_con_st *con= 0;
 
634
    drizzle_result_st result;
 
635
    drizzle_return_t ret;
 
636
    if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
594
637
    {
595
638
      free_defaults(argv_to_free);
596
 
      return(1); /* purecov: deadcode */
 
639
      return(1);
597
640
    }
598
641
 
599
 
    if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
 
642
    if (drizzle_query_str(con, &result,
 
643
                          "/*!40101 set @@character_set_database=binary */;",
 
644
                          &ret) == NULL ||
 
645
        ret != DRIZZLE_RETURN_OK)
600
646
    {
601
 
      db_error(drizzle); /* We shall countinue here, if --force was given */
 
647
      db_error(con, &result, ret, NULL);
 
648
      /* We shall countinue here, if --force was given */
602
649
      return(1);
603
650
    }
604
651
 
 
652
    drizzle_result_free(&result);
 
653
 
605
654
    if (lock_tables)
606
 
      lock_table(drizzle, argc, argv);
 
655
      lock_table(con, argc, argv);
607
656
    for (; *argv != NULL; argv++)
608
 
      if ((error= write_to_table(*argv, drizzle)))
 
657
      if ((error= write_to_table(*argv, con)))
609
658
        if (exitcode == 0)
610
659
          exitcode= error;
611
 
    db_disconnect(current_host, drizzle);
 
660
    db_disconnect(current_host, con);
612
661
  }
613
 
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
662
  free(opt_password);
614
663
  free_defaults(argv_to_free);
615
 
  my_end(my_end_arg);
 
664
  my_end();
616
665
  return(exitcode);
617
666
}