~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleimport.cc

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

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