~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlimport.c

  • Committer: Stewart Smith
  • Date: 2008-07-13 08:00:16 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713080016-8qtjv9ypt42azzr6
CRC32() as UDF

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 Drizzle Open Source Development Team
 
1
/* Copyright (C) 2000-2006 MySQL AB
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/*
17
 
**     drizzleimport.c  - Imports all given files
18
 
**          into a table(s).
 
17
**         mysqlimport.c  - Imports all given files
 
18
**                          into a table(s).
19
19
**
20
 
**         *************************
21
 
**         *         *
22
 
**         * AUTHOR: Monty & Jani  *
23
 
**         * DATE:   June 24, 1997 *
24
 
**         *         *
25
 
**         *************************
 
20
**                         *************************
 
21
**                         *                       *
 
22
**                         * AUTHOR: Monty & Jani  *
 
23
**                         * DATE:   June 24, 1997 *
 
24
**                         *                       *
 
25
**                         *************************
26
26
*/
27
27
#define IMPORT_VERSION "3.7"
28
28
 
29
29
#include "client_priv.h"
30
 
#include <string>
31
 
 
32
 
#include <pthread.h>
33
 
 
34
 
/* Added this for string translation. */
35
 
#include <drizzled/gettext.h>
36
 
 
37
 
using namespace std;
 
30
#include "drizzle_version.h"
 
31
#ifdef HAVE_LIBPTHREAD
 
32
#include <my_pthread.h>
 
33
#endif
 
34
 
38
35
 
39
36
/* Global Thread counter */
40
 
uint32_t counter;
 
37
uint counter;
 
38
#ifdef HAVE_LIBPTHREAD
41
39
pthread_mutex_t counter_mutex;
42
40
pthread_cond_t count_threshhold;
 
41
#endif
43
42
 
44
 
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
45
 
                     drizzle_return_t ret, char *table);
46
 
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);
47
46
static char *add_load_option(char *ptr,const char *object,
48
 
           const char *statement);
49
 
 
50
 
static bool verbose= false, lock_tables= false, ignore_errors= false,
51
 
            opt_delete= false, opt_replace= false, silent= false,
52
 
            ignore_unique= false, opt_compress= false, opt_low_priority= false,
53
 
            tty_password= false;
54
 
static bool debug_info_flag= false, debug_check_flag= false;
55
 
static uint32_t opt_use_threads= 0, opt_local_file= 0, my_end_arg= 0;
56
 
static char  *opt_password= NULL, *current_user= NULL,
57
 
    *current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
58
 
    *lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
59
 
    *escaped= NULL, *opt_columns= NULL,
60
 
    *default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
61
 
static uint32_t opt_drizzle_port= 0;
62
 
static char * opt_drizzle_unix_port= 0;
63
 
static int64_t opt_ignore_lines= -1;
64
 
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
 
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
65
67
 
66
68
static struct my_option my_long_options[] =
67
69
{
 
70
  {"character-sets-dir", OPT_CHARSETS_DIR,
 
71
   "Directory where character sets are.", (char**) &charsets_dir,
 
72
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
68
73
  {"default-character-set", OPT_DEFAULT_CHARSET,
69
74
   "Set the default character set.", (char**) &default_charset,
70
75
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
105
110
  {"host", 'h', "Connect to host.", (char**) &current_host,
106
111
   (char**) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
107
112
  {"ignore", 'i', "If duplicate unique key was found, keep old row.",
108
 
   (char**) &ignore_unique, (char**) &ignore_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
113
   (char**) &ignore, (char**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
109
114
  {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
110
115
   (char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
111
116
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
115
120
  {"local", 'L', "Read all files through the client.", (char**) &opt_local_file,
116
121
   (char**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
117
122
  {"lock-tables", 'l', "Lock all tables for write (this disables threads).",
118
 
    (char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG,
 
123
    (char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG, 
119
124
    0, 0, 0, 0, 0, 0},
120
125
  {"low-priority", OPT_LOW_PRIORITY,
121
126
   "Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
122
127
   (char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
123
 
  {"password", 'P',
 
128
  {"password", 'p',
124
129
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
125
130
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
126
 
  {"port", 'p', "Port number to use for connection or 0 for default to, in "
127
 
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
128
 
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
129
 
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
130
 
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
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
   (char**) &opt_mysql_port,
 
138
   (char**) &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).",
131
141
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
132
142
  {"replace", 'r', "If duplicate unique key was found, replace old row.",
133
 
   (char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
143
   (char**) &replace, (char**) &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.", (char**) &shared_memory_base_name, (char**) &shared_memory_base_name,
 
147
   0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
148
#endif
134
149
  {"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
135
150
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
136
151
  {"socket", 'S', "Socket file to use for connection.",
137
 
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
 
152
   (char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
138
153
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
139
154
  {"use-threads", OPT_USE_THREADS,
140
155
   "Load files in parallel. The argument is the number "
141
156
   "of threads to use for loading data.",
142
 
   (char**) &opt_use_threads, (char**) &opt_use_threads, 0,
 
157
   (char**) &opt_use_threads, (char**) &opt_use_threads, 0, 
143
158
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
144
159
#ifndef DONT_ALLOW_USER_CHANGE
145
160
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
153
168
};
154
169
 
155
170
 
156
 
static const char *load_default_groups[]= { "drizzleimport","client",0 };
 
171
static const char *load_default_groups[]= { "mysqlimport","client",0 };
 
172
 
 
173
#include <help_start.h>
157
174
 
158
175
static void print_version(void)
159
176
{
160
177
  printf("%s  Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
161
 
    IMPORT_VERSION, drizzle_version(),SYSTEM_TYPE,MACHINE_TYPE);
 
178
          IMPORT_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
162
179
}
163
180
 
164
181
 
165
182
static void usage(void)
166
183
{
167
184
  print_version();
168
 
  puts("Copyright (C) 2008 Drizzle Open Source Development Team");
 
185
  puts("Copyright (C) 2000-2006 MySQL AB");
169
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");
170
187
  printf("\
171
188
Loads tables from text files in various formats.  The base name of the\n\
172
189
text file must be the name of the table that should be used.\n\
173
 
If one uses sockets to connect to the Drizzle server, the server will open and\n\
 
190
If one uses sockets to connect to the MySQL server, the server will open and\n\
174
191
read the text file directly. In other cases the client will open the text\n\
175
192
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
176
193
 
177
194
  printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
178
 
  print_defaults("drizzle",load_default_groups);
 
195
  print_defaults("my",load_default_groups);
179
196
  my_print_help(my_long_options);
180
197
  my_print_variables(my_long_options);
181
198
}
182
199
 
183
 
extern "C"
184
 
bool get_one_option(int optid, const struct my_option *, char *argument)
 
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)
185
205
{
186
 
  char *endchar= NULL;
187
 
  uint64_t temp_drizzle_port= 0;
188
 
 
189
206
  switch(optid) {
190
207
  case 'p':
191
 
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
192
 
    /* if there is an alpha character this is not a valid port */
193
 
    if (strlen(endchar) != 0)
194
 
    {
195
 
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
196
 
      exit(1);
197
 
    }
198
 
    /* If the port number is > 65535 it is not a valid port
199
 
       This also helps with potential data loss casting unsigned long to a
200
 
       uint32_t. */
201
 
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
202
 
    {
203
 
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
204
 
      exit(1);
205
 
    }
206
 
    else
207
 
    {
208
 
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
209
 
    }
210
 
    break;
211
 
  case 'P':
212
208
    if (argument)
213
209
    {
214
210
      char *start=argument;
215
 
      if (opt_password)
216
 
        free(opt_password);
217
 
      opt_password = strdup(argument);
218
 
      if (opt_password == NULL)
219
 
      {
220
 
        fprintf(stderr, "Memory allocation error while copying password. "
221
 
                        "Aborting.\n");
222
 
        exit(ENOMEM);
223
 
      }
224
 
      while (*argument)
225
 
      {
226
 
        /* Overwriting password with 'x' */
227
 
        *argument++= 'x';
228
 
      }
 
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 */
229
214
      if (*start)
230
 
      {
231
 
        /* Cut length of argument */
232
 
        start[1]= 0;
233
 
      }
 
215
        start[1]=0;                             /* Cut length of argument */
234
216
      tty_password= 0;
235
217
    }
236
218
    else
237
219
      tty_password= 1;
238
220
    break;
239
 
  case OPT_DRIZZLE_PROTOCOL:
 
221
  case OPT_MYSQL_PROTOCOL:
 
222
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
223
                                    opt->name);
 
224
    break;
 
225
  case '#':
 
226
    DBUG_PUSH(argument ? argument : "d:t:o");
 
227
    debug_check_flag= 1;
240
228
    break;
241
229
  case 'V': print_version(); exit(0);
242
230
  case 'I':
264
252
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
265
253
    return(1);
266
254
  }
267
 
  if (opt_replace && ignore_unique)
 
255
  if (replace && ignore)
268
256
  {
269
 
    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");
270
258
    return(1);
271
259
  }
272
260
  if (strcmp(default_charset, charset_info->csname) &&
273
 
      !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY)))
 
261
      !(charset_info= get_charset_by_csname(default_charset,
 
262
                                            MY_CS_PRIMARY, MYF(MY_WME))))
274
263
    exit(1);
275
264
  if (*argc < 2)
276
265
  {
280
269
  current_db= *((*argv)++);
281
270
  (*argc)--;
282
271
  if (tty_password)
283
 
    opt_password=client_get_tty_password(NULL);
 
272
    opt_password=get_tty_password(NullS);
284
273
  return(0);
285
274
}
286
275
 
287
276
 
288
277
 
289
 
static int write_to_table(char *filename, drizzle_con_st *con)
 
278
static int write_to_table(char *filename, MYSQL *mysql)
290
279
{
291
280
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
292
281
       sql_statement[FN_REFLEN*16+256], *end;
293
 
  drizzle_result_st result;
294
 
  drizzle_return_t ret;
 
282
  DBUG_ENTER("write_to_table");
 
283
  DBUG_PRINT("enter",("filename: %s",filename));
295
284
 
296
285
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
297
286
  if (!opt_local_file)
298
 
    strcpy(hard_path,filename);
 
287
    strmov(hard_path,filename);
299
288
  else
300
289
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
301
290
 
308
297
#else
309
298
    sprintf(sql_statement, "DELETE FROM %s", tablename);
310
299
#endif
311
 
    if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
312
 
        ret != DRIZZLE_RETURN_OK)
 
300
    if (mysql_query(mysql, sql_statement))
313
301
    {
314
 
      db_error(con, &result, ret, tablename);
315
 
      return(1);
 
302
      db_error_with_table(mysql, tablename);
 
303
      DBUG_RETURN(1);
316
304
    }
317
 
    drizzle_result_free(&result);
318
305
  }
 
306
  to_unix_path(hard_path);
319
307
  if (verbose)
320
308
  {
321
309
    if (opt_local_file)
322
310
      fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
323
 
        hard_path, tablename);
 
311
              hard_path, tablename);
324
312
    else
325
313
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
326
 
        hard_path, tablename);
 
314
              hard_path, tablename);
327
315
  }
328
316
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
329
 
    opt_low_priority ? "LOW_PRIORITY" : "",
330
 
    opt_local_file ? "LOCAL" : "", hard_path);
331
 
  end= strchr(sql_statement, '\0');
332
 
  if (opt_replace)
333
 
    end= strcpy(end, " REPLACE")+8;
334
 
  if (ignore_unique)
335
 
    end= strcpy(end, " IGNORE")+7;
336
 
 
337
 
  end+= sprintf(end, " INTO TABLE %s", tablename);
 
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);
338
325
 
339
326
  if (fields_terminated || enclosed || opt_enclosed || escaped)
340
 
      end= strcpy(end, " FIELDS")+7;
 
327
      end= strmov(end, " FIELDS");
341
328
  end= add_load_option(end, fields_terminated, " TERMINATED BY");
342
329
  end= add_load_option(end, enclosed, " ENCLOSED BY");
343
330
  end= add_load_option(end, opt_enclosed,
344
 
           " OPTIONALLY ENCLOSED BY");
 
331
                       " OPTIONALLY ENCLOSED BY");
345
332
  end= add_load_option(end, escaped, " ESCAPED BY");
346
333
  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
347
334
  if (opt_ignore_lines >= 0)
348
 
  {
349
 
    end= strcpy(end, " IGNORE ")+8;
350
 
    ostringstream buffer;
351
 
    buffer << opt_ignore_lines;
352
 
    end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
353
 
    end= strcpy(end, " LINES")+6;
354
 
  }
 
335
    end= strmov(longlong10_to_str(opt_ignore_lines, 
 
336
                                  strmov(end, " IGNORE "),10), " LINES");
355
337
  if (opt_columns)
356
 
  {
357
 
    end= strcpy(end, " (")+2;
358
 
    end= strcpy(end, opt_columns)+strlen(opt_columns);
359
 
    end= strcpy(end, ")")+1;
360
 
  }
 
338
    end= strmov(strmov(strmov(end, " ("), opt_columns), ")");
361
339
  *end= '\0';
362
340
 
363
 
  if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
364
 
      ret != DRIZZLE_RETURN_OK)
 
341
  if (mysql_query(mysql, sql_statement))
365
342
  {
366
 
    db_error(con, &result, ret, tablename);
367
 
    return(1);
 
343
    db_error_with_table(mysql, tablename);
 
344
    DBUG_RETURN(1);
368
345
  }
369
346
  if (!silent)
370
347
  {
371
 
    if (strcmp(drizzle_result_info(&result), ""))
 
348
    if (mysql_info(mysql)) /* If NULL-pointer, print nothing */
372
349
    {
373
350
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
374
 
        drizzle_result_info(&result));
 
351
              mysql_info(mysql));
375
352
    }
376
353
  }
377
 
  drizzle_result_free(&result);
378
 
  return(0);
 
354
  DBUG_RETURN(0);
379
355
}
380
356
 
381
357
 
382
 
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
 
358
 
 
359
static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename)
383
360
{
384
 
  string query;
 
361
  DYNAMIC_STRING query;
385
362
  int i;
386
363
  char tablename[FN_REFLEN];
387
 
  drizzle_result_st result;
388
 
  drizzle_return_t ret;
389
364
 
390
365
  if (verbose)
391
366
    fprintf(stdout, "Locking tables for write\n");
392
 
  query.append("LOCK TABLES ");
 
367
  init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
393
368
  for (i=0 ; i < tablecount ; i++)
394
369
  {
395
370
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
396
 
    query.append(tablename);
397
 
    query.append(" WRITE,");
398
 
  }
399
 
  if (drizzle_query(con, &result, query.c_str(), query.length()-1,
400
 
                    &ret) == NULL ||
401
 
      ret != DRIZZLE_RETURN_OK)
402
 
  {
403
 
    db_error(con, &result, ret, NULL);
404
 
    /* We shall countinue here, if --force was given */
405
 
    return;
406
 
  }
407
 
  drizzle_result_free(&result);
 
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 */
408
376
}
409
377
 
410
378
 
411
 
static drizzle_con_st *db_connect(char *host, char *database,
412
 
                                  char *user, char *passwd)
 
379
 
 
380
 
 
381
static MYSQL *db_connect(char *host, char *database,
 
382
                         char *user, char *passwd)
413
383
{
414
 
  drizzle_st *drizzle;
415
 
  drizzle_con_st *con;
416
 
  drizzle_return_t ret;
417
 
 
 
384
  MYSQL *mysql;
418
385
  if (verbose)
419
386
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
420
 
  if (!(drizzle= drizzle_create(NULL)))
421
 
    return 0;
422
 
  if (!(con= drizzle_con_add_tcp(drizzle,NULL,host,opt_drizzle_port,user,passwd,
423
 
                                 database, DRIZZLE_CON_NONE)))
424
 
  {
425
 
    return 0;
426
 
  }
427
 
 
428
 
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
429
 
  {
430
 
    ignore_errors=0;    /* NO RETURN FROM db_error */
431
 
    db_error(con, NULL, ret, NULL);
432
 
  }
433
 
 
 
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;
434
408
  if (verbose)
435
409
    fprintf(stdout, "Selecting database %s\n", database);
436
 
 
437
 
  return con;
 
410
  if (mysql_select_db(mysql, database))
 
411
  {
 
412
    ignore_errors=0;
 
413
    db_error(mysql);
 
414
  }
 
415
  return mysql;
438
416
}
439
417
 
440
418
 
441
419
 
442
 
static void db_disconnect(char *host, drizzle_con_st *con)
 
420
static void db_disconnect(char *host, MYSQL *mysql)
443
421
{
444
422
  if (verbose)
445
423
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
446
 
  drizzle_free(drizzle_con_drizzle(con));
 
424
  mysql_close(mysql);
447
425
}
448
426
 
449
427
 
450
428
 
451
 
static void safe_exit(int error, drizzle_con_st *con)
 
429
static void safe_exit(int error, MYSQL *mysql)
452
430
{
453
431
  if (ignore_errors)
454
432
    return;
455
 
  if (con)
456
 
    drizzle_free(drizzle_con_drizzle(con));
 
433
  if (mysql)
 
434
    mysql_close(mysql);
457
435
  exit(error);
458
436
}
459
437
 
460
438
 
461
439
 
462
 
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
463
 
                     drizzle_return_t ret, char *table)
464
 
{
465
 
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
466
 
  {
467
 
    my_printf_error(0,"Error: %d, %s%s%s", MYF(0),
468
 
                    drizzle_result_error_code(result),
469
 
                    drizzle_result_error(result),
470
 
                    table ? ", when using table: " : "", table ? table : "");
471
 
    drizzle_result_free(result);
472
 
  }
473
 
  else
474
 
  {
475
 
    my_printf_error(0,"Error: %d, %s%s%s", MYF(0), ret, drizzle_con_error(con),
476
 
                    table ? ", when using table: " : "", table ? table : "");
477
 
  }
478
 
 
479
 
  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);
480
453
}
481
454
 
482
455
 
483
456
static char *add_load_option(char *ptr, const char *object,
484
 
           const char *statement)
 
457
                             const char *statement)
485
458
{
486
459
  if (object)
487
460
  {
488
461
    /* Don't escape hex constants */
489
462
    if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
490
 
      ptr+= sprintf(ptr, " %s %s", statement, object);
 
463
      ptr= strxmov(ptr," ",statement," ",object,NullS);
491
464
    else
492
465
    {
493
466
      /* char constant; escape */
494
 
      ptr+= sprintf(ptr, " %s '", statement); 
495
 
      ptr= field_escape(ptr,object,(uint32_t) strlen(object));
 
467
      ptr= strxmov(ptr," ",statement," '",NullS);
 
468
      ptr= field_escape(ptr,object,(uint) strlen(object));
496
469
      *ptr++= '\'';
497
470
    }
498
471
  }
504
477
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
505
478
** This is done by doubleing ' and add a end -\ if needed to avoid
506
479
** syntax errors from the SQL parser.
507
 
*/
 
480
*/ 
508
481
 
509
 
static char *field_escape(char *to,const char *from,uint32_t length)
 
482
static char *field_escape(char *to,const char *from,uint length)
510
483
{
511
484
  const char *end;
512
 
  uint32_t end_backslashes=0;
 
485
  uint end_backslashes=0; 
513
486
 
514
487
  for (end= from+length; from != end; from++)
515
488
  {
516
489
    *to++= *from;
517
490
    if (*from == '\\')
518
491
      end_backslashes^=1;    /* find odd number of backslashes */
519
 
    else
 
492
    else 
520
493
    {
521
494
      if (*from == '\'' && !end_backslashes)
522
 
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
 
495
        *to++= *from;      /* We want a dublicate of "'" for MySQL */
523
496
      end_backslashes=0;
524
497
    }
525
498
  }
526
499
  /* Add missing backslashes if user has specified odd number of backs.*/
527
500
  if (end_backslashes)
528
 
    *to++= '\\';
 
501
    *to++= '\\';          
529
502
  return to;
530
503
}
531
504
 
532
505
int exitcode= 0;
533
506
 
534
 
extern "C"
535
 
void * worker_thread(void *arg)
 
507
#ifdef HAVE_LIBPTHREAD
 
508
static pthread_handler_t worker_thread(void *arg)
536
509
{
537
510
  int error;
538
511
  char *raw_table_name= (char *)arg;
539
 
  drizzle_con_st *con= NULL;
540
 
  drizzle_result_st result;
541
 
  drizzle_return_t ret;
 
512
  MYSQL *mysql= 0;
542
513
 
543
 
  if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
 
514
  if (mysql_thread_init())
 
515
    goto error;
 
516
  
 
517
  if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
544
518
  {
545
519
    goto error;
546
520
  }
547
521
 
548
 
  if (drizzle_query_str(con, &result,
549
 
                        "/*!40101 set @@character_set_database=binary */;",
550
 
                        &ret) == NULL ||
551
 
      ret != DRIZZLE_RETURN_OK)
 
522
  if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
552
523
  {
553
 
    db_error(con, &result, ret, NULL);
554
 
    /* We shall countinue here, if --force was given */
 
524
    db_error(mysql); /* We shall countinue here, if --force was given */
555
525
    goto error;
556
526
  }
557
527
 
558
528
  /*
559
529
    We are not currently catching the error here.
560
530
  */
561
 
  if((error= write_to_table(raw_table_name, con)))
 
531
  if((error= write_to_table(raw_table_name, mysql)))
562
532
    if (exitcode == 0)
563
533
      exitcode= error;
564
534
 
565
535
error:
566
 
  if (con)
567
 
    db_disconnect(current_host, con);
 
536
  if (mysql)
 
537
    db_disconnect(current_host, mysql);
568
538
 
569
539
  pthread_mutex_lock(&counter_mutex);
570
540
  counter--;
574
544
 
575
545
  return 0;
576
546
}
 
547
#endif
577
548
 
578
549
 
579
550
int main(int argc, char **argv)
582
553
  char **argv_to_free;
583
554
  MY_INIT(argv[0]);
584
555
 
585
 
  load_defaults("drizzle",load_default_groups,&argc,&argv);
 
556
  load_defaults("my",load_default_groups,&argc,&argv);
586
557
  /* argv is changed in the program */
587
558
  argv_to_free= argv;
588
559
  if (get_options(&argc, &argv))
600
571
    pthread_attr_setdetachstate(&attr,
601
572
                                PTHREAD_CREATE_DETACHED);
602
573
 
603
 
    pthread_mutex_init(&counter_mutex, NULL);
604
 
    pthread_cond_init(&count_threshhold, NULL);
 
574
    VOID(pthread_mutex_init(&counter_mutex, NULL));
 
575
    VOID(pthread_cond_init(&count_threshhold, NULL));
605
576
 
606
577
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
607
578
    {
617
588
      counter++;
618
589
      pthread_mutex_unlock(&counter_mutex);
619
590
      /* now create the thread */
620
 
      if (pthread_create(&mainthread, &attr, worker_thread,
 
591
      if (pthread_create(&mainthread, &attr, worker_thread, 
621
592
                         (void *)*argv) != 0)
622
593
      {
623
594
        pthread_mutex_lock(&counter_mutex);
640
611
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
641
612
    }
642
613
    pthread_mutex_unlock(&counter_mutex);
643
 
    pthread_mutex_destroy(&counter_mutex);
644
 
    pthread_cond_destroy(&count_threshhold);
 
614
    VOID(pthread_mutex_destroy(&counter_mutex));
 
615
    VOID(pthread_cond_destroy(&count_threshhold));
645
616
    pthread_attr_destroy(&attr);
646
617
  }
647
618
  else
648
619
#endif
649
620
  {
650
 
    drizzle_con_st *con= 0;
651
 
    drizzle_result_st result;
652
 
    drizzle_return_t ret;
653
 
    if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
 
621
    MYSQL *mysql= 0;
 
622
    if (!(mysql= db_connect(current_host,current_db,current_user,opt_password)))
654
623
    {
655
624
      free_defaults(argv_to_free);
656
625
      return(1); /* purecov: deadcode */
657
626
    }
658
627
 
659
 
    if (drizzle_query_str(con, &result,
660
 
                          "/*!40101 set @@character_set_database=binary */;",
661
 
                          &ret) == NULL ||
662
 
        ret != DRIZZLE_RETURN_OK)
 
628
    if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;"))
663
629
    {
664
 
      db_error(con, &result, ret, NULL);
665
 
      /* We shall countinue here, if --force was given */
 
630
      db_error(mysql); /* We shall countinue here, if --force was given */
666
631
      return(1);
667
632
    }
668
633
 
669
 
    drizzle_result_free(&result);
670
 
 
671
634
    if (lock_tables)
672
 
      lock_table(con, argc, argv);
 
635
      lock_table(mysql, argc, argv);
673
636
    for (; *argv != NULL; argv++)
674
 
      if ((error= write_to_table(*argv, con)))
 
637
      if ((error= write_to_table(*argv, mysql)))
675
638
        if (exitcode == 0)
676
639
          exitcode= error;
677
 
    db_disconnect(current_host, con);
 
640
    db_disconnect(current_host, mysql);
678
641
  }
679
 
  free(opt_password);
 
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
680
646
  free_defaults(argv_to_free);
681
647
  my_end(my_end_arg);
682
648
  return(exitcode);