~drizzle-trunk/drizzle/development

1235.3.6 by Stewart Smith
fix copyright notice in drizzleimport.cc
1
/* Copyright (C) 2000-2006 MySQL AB
2
   Copyright (C) 2008-2009 Sun Microsystems, Inc
1 by brian
clean slate
3
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; version 2 of the License.
7
8
   This program is distributed in the hope that it will be useful,
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
   GNU General Public License for more details.
12
13
   You should have received a copy of the GNU General Public License
14
   along with this program; if not, write to the Free Software
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
16
17
/*
206.3.1 by Patrick Galbraith
Most everything working with client rename
18
**     drizzleimport.c  - Imports all given files
19
**          into a table(s).
1 by brian
clean slate
20
**
206.3.1 by Patrick Galbraith
Most everything working with client rename
21
**         *************************
22
**         *         *
23
**         * AUTHOR: Monty & Jani  *
24
**         * DATE:   June 24, 1997 *
25
**         *         *
26
**         *************************
1 by brian
clean slate
27
*/
28
#define IMPORT_VERSION "3.7"
29
612.2.4 by Monty Taylor
Moved some defines to config.h. Stopped including config.h directly anywhere.
30
#include "client_priv.h"
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
31
#include <string>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
32
#include <sstream>
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
33
279.2.4 by Monty Taylor
Moved import, check and dump to C++... fixed errors.
34
#include <pthread.h>
1 by brian
clean slate
35
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
36
/* Added this for string translation. */
37
#include <drizzled/gettext.h>
38
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
39
using namespace std;
1 by brian
clean slate
40
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
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;
48
1 by brian
clean slate
49
/* Global Thread counter */
893 by Brian Aker
First pass of stripping uint
50
uint32_t counter;
1 by brian
clean slate
51
pthread_mutex_t counter_mutex;
52
pthread_cond_t count_threshhold;
53
928.1.6 by Eric Day
All utilities done except slap.
54
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
55
                     drizzle_return_t ret, char *table);
893 by Brian Aker
First pass of stripping uint
56
static char *field_escape(char *to,const char *from,uint32_t length);
1 by brian
clean slate
57
static char *add_load_option(char *ptr,const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
58
           const char *statement);
1 by brian
clean slate
59
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
60
static bool verbose= false, lock_tables= false, ignore_errors= false,
61
            opt_delete= false, opt_replace= false, silent= false,
1235.3.7 by Stewart Smith
remove outdated --compress option from drizzleimport
62
            ignore_unique= false, opt_low_priority= false,
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
63
            tty_password= false;
1235.3.13 by Stewart Smith
remove MY_GIVE_INFO parameter to my_end() that really just gave us the output of time(1). Use UNIX, don't re-implement the kitchen sink. This also removes --debug-info from most command line utilities.
64
1235.3.14 by Stewart Smith
my_end() no longer requires an argument (we removed them all)
65
static uint32_t opt_use_threads= 0, opt_local_file= 0;
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
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,
1081.1.1 by Monty Taylor
Whole boat-load of build fixes.
69
    *escaped= NULL, *opt_columns= NULL;
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
70
static uint32_t opt_drizzle_port= 0;
71
static char * opt_drizzle_unix_port= 0;
152 by Brian Aker
longlong replacement
72
static int64_t opt_ignore_lines= -1;
1 by brian
clean slate
73
74
static struct my_option my_long_options[] =
75
{
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.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
78
   (char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
1 by brian
clean slate
79
   0, 0, 0},
80
  {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
81
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
82
  {"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
83
   (char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
84
  {"fields-terminated-by", OPT_FTB,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
85
   "Fields in the textfile are terminated by ...", (char**) &fields_terminated,
86
   (char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
87
  {"fields-enclosed-by", OPT_ENC,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
88
   "Fields in the importfile are enclosed by ...", (char**) &enclosed,
89
   (char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
90
  {"fields-optionally-enclosed-by", OPT_O_ENC,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
91
   "Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
92
   (char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
93
  {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
94
   (char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
1 by brian
clean slate
95
   0, 0},
96
  {"force", 'f', "Continue even if we get an sql-error.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
97
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
1 by brian
clean slate
98
   0, 0, 0, 0},
99
  {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
100
   0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
101
  {"host", 'h', "Connect to host.", (char**) &current_host,
102
   (char**) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
103
  {"ignore", 'i', "If duplicate unique key was found, keep old row.",
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
104
   (char**) &ignore_unique, (char**) &ignore_unique, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
105
  {"ignore-lines", OPT_IGN_LINES, "Ignore first n lines of data infile.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
106
   (char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
1 by brian
clean slate
107
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
108
  {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
109
   (char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
1 by brian
clean slate
110
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
111
  {"local", 'L', "Read all files through the client.", (char**) &opt_local_file,
112
   (char**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
113
  {"lock-tables", 'l', "Lock all tables for write (this disables threads).",
206.3.1 by Patrick Galbraith
Most everything working with client rename
114
    (char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG,
1 by brian
clean slate
115
    0, 0, 0, 0, 0, 0},
116
  {"low-priority", OPT_LOW_PRIORITY,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
117
   "Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
118
   (char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
119
  {"password", 'P',
1 by brian
clean slate
120
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
121
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
122
  {"port", 'p', "Port number to use for connection or 0 for default to, in "
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
123
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
301 by Brian Aker
Clean up port startup
124
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
125
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
206.3.1 by Patrick Galbraith
Most everything working with client rename
126
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
1 by brian
clean slate
127
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
128
  {"replace", 'r', "If duplicate unique key was found, replace old row.",
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
129
   (char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
130
  {"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
1 by brian
clean slate
131
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
132
  {"socket", 'S', "Socket file to use for connection.",
206.3.1 by Patrick Galbraith
Most everything working with client rename
133
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
1 by brian
clean slate
134
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
135
  {"use-threads", OPT_USE_THREADS,
136
   "Load files in parallel. The argument is the number "
137
   "of threads to use for loading data.",
206.3.1 by Patrick Galbraith
Most everything working with client rename
138
   (char**) &opt_use_threads, (char**) &opt_use_threads, 0,
1 by brian
clean slate
139
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
140
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
141
   (char**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
142
  {"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
143
   (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
144
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
145
   NO_ARG, 0, 0, 0, 0, 0, 0},
146
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
147
};
148
149
206.3.1 by Patrick Galbraith
Most everything working with client rename
150
static const char *load_default_groups[]= { "drizzleimport","client",0 };
1 by brian
clean slate
151
152
static void print_version(void)
153
{
1081.1.1 by Monty Taylor
Whole boat-load of build fixes.
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);
1 by brian
clean slate
156
}
157
158
159
static void usage(void)
160
{
161
  print_version();
206.3.1 by Patrick Galbraith
Most everything working with client rename
162
  puts("Copyright (C) 2008 Drizzle Open Source Development Team");
1 by brian
clean slate
163
  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");
164
  printf("\
165
Loads tables from text files in various formats.  The base name of the\n\
166
text file must be the name of the table that should be used.\n\
206.3.1 by Patrick Galbraith
Most everything working with client rename
167
If one uses sockets to connect to the Drizzle server, the server will open and\n\
1 by brian
clean slate
168
read the text file directly. In other cases the client will open the text\n\
169
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
170
171
  printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
172
  print_defaults("drizzle",load_default_groups);
1 by brian
clean slate
173
  my_print_help(my_long_options);
174
  my_print_variables(my_long_options);
175
}
176
637 by Brian Aker
Merge from Monty
177
bool get_one_option(int optid, const struct my_option *, char *argument)
1 by brian
clean slate
178
{
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
179
  char *endchar= NULL;
180
  uint64_t temp_drizzle_port= 0;
181
1 by brian
clean slate
182
  switch(optid) {
183
  case 'p':
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
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':
1 by brian
clean slate
205
    if (argument)
206
    {
207
      char *start=argument;
656.1.51 by Monty Taylor
Fixed strdup return checking in client/
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
      }
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
217
      while (*argument)
218
      {
219
        /* Overwriting password with 'x' */
220
        *argument++= 'x';
221
      }
1 by brian
clean slate
222
      if (*start)
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
223
      {
224
        /* Cut length of argument */
225
        start[1]= 0;
226
      }
1 by brian
clean slate
227
      tty_password= 0;
228
    }
229
    else
230
      tty_password= 1;
231
    break;
206.3.1 by Patrick Galbraith
Most everything working with client rename
232
  case OPT_DRIZZLE_PROTOCOL:
1 by brian
clean slate
233
    break;
234
  case 'V': print_version(); exit(0);
235
  case 'I':
236
  case '?':
237
    usage();
238
    exit(0);
239
  }
240
  return 0;
241
}
242
243
244
static int get_options(int *argc, char ***argv)
245
{
246
  int ho_error;
247
248
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
249
    exit(ho_error);
250
251
  if (enclosed && opt_enclosed)
252
  {
253
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
254
    return(1);
255
  }
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
256
  if (opt_replace && ignore_unique)
1 by brian
clean slate
257
  {
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
258
    fprintf(stderr, "You can't use --ignore_unique (-i) and --replace (-r) at the same time.\n");
1 by brian
clean slate
259
    return(1);
260
  }
261
  if (*argc < 2)
262
  {
263
    usage();
264
    return 1;
265
  }
266
  current_db= *((*argv)++);
267
  (*argc)--;
268
  if (tty_password)
928.1.6 by Eric Day
All utilities done except slap.
269
    opt_password=client_get_tty_password(NULL);
1 by brian
clean slate
270
  return(0);
271
}
272
273
274
928.1.6 by Eric Day
All utilities done except slap.
275
static int write_to_table(char *filename, drizzle_con_st *con)
1 by brian
clean slate
276
{
277
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
278
       sql_statement[FN_REFLEN*16+256], *end;
928.1.6 by Eric Day
All utilities done except slap.
279
  drizzle_result_st result;
280
  drizzle_return_t ret;
1 by brian
clean slate
281
282
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
283
  if (!opt_local_file)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
284
    strcpy(hard_path,filename);
1 by brian
clean slate
285
  else
286
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
287
288
  if (opt_delete)
289
  {
290
    if (verbose)
291
      fprintf(stdout, "Deleting the old data from table %s\n", tablename);
292
#ifdef HAVE_SNPRINTF
293
    snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
294
#else
295
    sprintf(sql_statement, "DELETE FROM %s", tablename);
296
#endif
928.1.6 by Eric Day
All utilities done except slap.
297
    if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
298
        ret != DRIZZLE_RETURN_OK)
1 by brian
clean slate
299
    {
928.1.6 by Eric Day
All utilities done except slap.
300
      db_error(con, &result, ret, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
301
      return(1);
1 by brian
clean slate
302
    }
928.1.6 by Eric Day
All utilities done except slap.
303
    drizzle_result_free(&result);
1 by brian
clean slate
304
  }
305
  if (verbose)
306
  {
307
    if (opt_local_file)
308
      fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
309
        hard_path, tablename);
1 by brian
clean slate
310
    else
311
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
312
        hard_path, tablename);
1 by brian
clean slate
313
  }
314
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
206.3.1 by Patrick Galbraith
Most everything working with client rename
315
    opt_low_priority ? "LOW_PRIORITY" : "",
316
    opt_local_file ? "LOCAL" : "", hard_path);
376 by Brian Aker
strend remove
317
  end= strchr(sql_statement, '\0');
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
318
  if (opt_replace)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
319
    end= strcpy(end, " REPLACE")+8;
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
320
  if (ignore_unique)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
321
    end= strcpy(end, " IGNORE")+7;
322
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
323
  end+= sprintf(end, " INTO TABLE %s", tablename);
1 by brian
clean slate
324
325
  if (fields_terminated || enclosed || opt_enclosed || escaped)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
326
      end= strcpy(end, " FIELDS")+7;
1 by brian
clean slate
327
  end= add_load_option(end, fields_terminated, " TERMINATED BY");
328
  end= add_load_option(end, enclosed, " ENCLOSED BY");
329
  end= add_load_option(end, opt_enclosed,
206.3.1 by Patrick Galbraith
Most everything working with client rename
330
           " OPTIONALLY ENCLOSED BY");
1 by brian
clean slate
331
  end= add_load_option(end, escaped, " ESCAPED BY");
332
  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
333
  if (opt_ignore_lines >= 0)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
334
  {
335
    end= strcpy(end, " IGNORE ")+8;
971.1.77 by Monty Taylor
Removed mysys/mystrings things from client/ progs. Still need to get rid of my_getopt, but I think that's all now.
336
    ostringstream buffer;
337
    buffer << opt_ignore_lines;
338
    end= strcpy(end, buffer.str().c_str())+ buffer.str().size();
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
339
    end= strcpy(end, " LINES")+6;
340
  }
1 by brian
clean slate
341
  if (opt_columns)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
342
  {
343
    end= strcpy(end, " (")+2;
344
    end= strcpy(end, opt_columns)+strlen(opt_columns);
345
    end= strcpy(end, ")")+1;
346
  }
1 by brian
clean slate
347
  *end= '\0';
348
928.1.6 by Eric Day
All utilities done except slap.
349
  if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
350
      ret != DRIZZLE_RETURN_OK)
1 by brian
clean slate
351
  {
928.1.6 by Eric Day
All utilities done except slap.
352
    db_error(con, &result, ret, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
353
    return(1);
1 by brian
clean slate
354
  }
355
  if (!silent)
356
  {
928.1.6 by Eric Day
All utilities done except slap.
357
    if (strcmp(drizzle_result_info(&result), ""))
1 by brian
clean slate
358
    {
359
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
928.1.6 by Eric Day
All utilities done except slap.
360
        drizzle_result_info(&result));
1 by brian
clean slate
361
    }
362
  }
928.1.6 by Eric Day
All utilities done except slap.
363
  drizzle_result_free(&result);
142.1.2 by Patrick
All DBUG_x removed from client/
364
  return(0);
1 by brian
clean slate
365
}
366
367
928.1.6 by Eric Day
All utilities done except slap.
368
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
1 by brian
clean slate
369
{
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
370
  string query;
1 by brian
clean slate
371
  int i;
372
  char tablename[FN_REFLEN];
928.1.6 by Eric Day
All utilities done except slap.
373
  drizzle_result_st result;
374
  drizzle_return_t ret;
1 by brian
clean slate
375
376
  if (verbose)
377
    fprintf(stdout, "Locking tables for write\n");
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
378
  query.append("LOCK TABLES ");
1 by brian
clean slate
379
  for (i=0 ; i < tablecount ; i++)
380
  {
381
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
382
    query.append(tablename);
383
    query.append(" WRITE,");
1 by brian
clean slate
384
  }
928.1.6 by Eric Day
All utilities done except slap.
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);
1 by brian
clean slate
394
}
395
396
928.1.6 by Eric Day
All utilities done except slap.
397
static drizzle_con_st *db_connect(char *host, char *database,
398
                                  char *user, char *passwd)
1 by brian
clean slate
399
{
928.1.6 by Eric Day
All utilities done except slap.
400
  drizzle_st *drizzle;
401
  drizzle_con_st *con;
402
  drizzle_return_t ret;
403
1 by brian
clean slate
404
  if (verbose)
405
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
928.1.6 by Eric Day
All utilities done except slap.
406
  if (!(drizzle= drizzle_create(NULL)))
407
    return 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)
1 by brian
clean slate
415
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
416
    ignore_errors=0;    /* NO RETURN FROM db_error */
928.1.6 by Eric Day
All utilities done except slap.
417
    db_error(con, NULL, ret, NULL);
1 by brian
clean slate
418
  }
928.1.6 by Eric Day
All utilities done except slap.
419
1 by brian
clean slate
420
  if (verbose)
421
    fprintf(stdout, "Selecting database %s\n", database);
928.1.6 by Eric Day
All utilities done except slap.
422
423
  return con;
1 by brian
clean slate
424
}
425
426
427
928.1.6 by Eric Day
All utilities done except slap.
428
static void db_disconnect(char *host, drizzle_con_st *con)
1 by brian
clean slate
429
{
430
  if (verbose)
431
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
928.1.6 by Eric Day
All utilities done except slap.
432
  drizzle_free(drizzle_con_drizzle(con));
1 by brian
clean slate
433
}
434
435
436
928.1.6 by Eric Day
All utilities done except slap.
437
static void safe_exit(int error, drizzle_con_st *con)
1 by brian
clean slate
438
{
439
  if (ignore_errors)
440
    return;
928.1.6 by Eric Day
All utilities done except slap.
441
  if (con)
442
    drizzle_free(drizzle_con_drizzle(con));
1 by brian
clean slate
443
  exit(error);
444
}
445
446
447
928.1.6 by Eric Day
All utilities done except slap.
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);
1 by brian
clean slate
466
}
467
468
469
static char *add_load_option(char *ptr, const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
470
           const char *statement)
1 by brian
clean slate
471
{
472
  if (object)
473
  {
474
    /* Don't escape hex constants */
475
    if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
476
      ptr+= sprintf(ptr, " %s %s", statement, object);
1 by brian
clean slate
477
    else
478
    {
479
      /* char constant; escape */
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
480
      ptr+= sprintf(ptr, " %s '", statement); 
895 by Brian Aker
Completion (?) of uint conversion.
481
      ptr= field_escape(ptr,object,(uint32_t) strlen(object));
1 by brian
clean slate
482
      *ptr++= '\'';
483
    }
484
  }
485
  return ptr;
486
}
487
488
/*
489
** Allow the user to specify field terminator strings like:
490
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
491
** This is done by doubleing ' and add a end -\ if needed to avoid
492
** syntax errors from the SQL parser.
206.3.1 by Patrick Galbraith
Most everything working with client rename
493
*/
1 by brian
clean slate
494
893 by Brian Aker
First pass of stripping uint
495
static char *field_escape(char *to,const char *from,uint32_t length)
1 by brian
clean slate
496
{
497
  const char *end;
893 by Brian Aker
First pass of stripping uint
498
  uint32_t end_backslashes=0;
1 by brian
clean slate
499
500
  for (end= from+length; from != end; from++)
501
  {
502
    *to++= *from;
503
    if (*from == '\\')
504
      end_backslashes^=1;    /* find odd number of backslashes */
206.3.1 by Patrick Galbraith
Most everything working with client rename
505
    else
1 by brian
clean slate
506
    {
507
      if (*from == '\'' && !end_backslashes)
206.3.1 by Patrick Galbraith
Most everything working with client rename
508
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
1 by brian
clean slate
509
      end_backslashes=0;
510
    }
511
  }
512
  /* Add missing backslashes if user has specified odd number of backs.*/
513
  if (end_backslashes)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
514
    *to++= '\\';
1 by brian
clean slate
515
  return to;
516
}
517
632.1.12 by Monty Taylor
Fixed more sun studio warnings.
518
void * worker_thread(void *arg)
1 by brian
clean slate
519
{
520
  int error;
521
  char *raw_table_name= (char *)arg;
928.1.6 by Eric Day
All utilities done except slap.
522
  drizzle_con_st *con= NULL;
523
  drizzle_result_st result;
524
  drizzle_return_t ret;
1 by brian
clean slate
525
928.1.6 by Eric Day
All utilities done except slap.
526
  if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
527
  {
528
    goto error;
529
  }
530
928.1.6 by Eric Day
All utilities done except slap.
531
  if (drizzle_query_str(con, &result,
532
                        "/*!40101 set @@character_set_database=binary */;",
533
                        &ret) == NULL ||
534
      ret != DRIZZLE_RETURN_OK)
1 by brian
clean slate
535
  {
928.1.6 by Eric Day
All utilities done except slap.
536
    db_error(con, &result, ret, NULL);
537
    /* We shall countinue here, if --force was given */
1 by brian
clean slate
538
    goto error;
539
  }
540
541
  /*
542
    We are not currently catching the error here.
543
  */
928.1.6 by Eric Day
All utilities done except slap.
544
  if((error= write_to_table(raw_table_name, con)))
1 by brian
clean slate
545
    if (exitcode == 0)
546
      exitcode= error;
547
548
error:
928.1.6 by Eric Day
All utilities done except slap.
549
  if (con)
550
    db_disconnect(current_host, con);
1 by brian
clean slate
551
552
  pthread_mutex_lock(&counter_mutex);
553
  counter--;
554
  pthread_cond_signal(&count_threshhold);
555
  pthread_mutex_unlock(&counter_mutex);
556
  my_thread_end();
557
558
  return 0;
559
}
560
561
562
int main(int argc, char **argv)
563
{
564
  int error=0;
565
  char **argv_to_free;
566
  MY_INIT(argv[0]);
567
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
568
  load_defaults("drizzle",load_default_groups,&argc,&argv);
1 by brian
clean slate
569
  /* argv is changed in the program */
570
  argv_to_free= argv;
571
  if (get_options(&argc, &argv))
572
  {
573
    free_defaults(argv_to_free);
574
    return(1);
575
  }
576
577
#ifdef HAVE_LIBPTHREAD
578
  if (opt_use_threads && !lock_tables)
579
  {
580
    pthread_t mainthread;            /* Thread descriptor */
581
    pthread_attr_t attr;          /* Thread attributes */
582
    pthread_attr_init(&attr);
583
    pthread_attr_setdetachstate(&attr,
584
                                PTHREAD_CREATE_DETACHED);
585
398.1.10 by Monty Taylor
Actually removed VOID() this time.
586
    pthread_mutex_init(&counter_mutex, NULL);
587
    pthread_cond_init(&count_threshhold, NULL);
1 by brian
clean slate
588
589
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
590
    {
591
      pthread_mutex_lock(&counter_mutex);
592
      while (counter == opt_use_threads)
593
      {
594
        struct timespec abstime;
595
596
        set_timespec(abstime, 3);
597
        pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
598
      }
599
      /* Before exiting the lock we set ourselves up for the next thread */
600
      counter++;
601
      pthread_mutex_unlock(&counter_mutex);
602
      /* now create the thread */
206.3.1 by Patrick Galbraith
Most everything working with client rename
603
      if (pthread_create(&mainthread, &attr, worker_thread,
1 by brian
clean slate
604
                         (void *)*argv) != 0)
605
      {
606
        pthread_mutex_lock(&counter_mutex);
607
        counter--;
608
        pthread_mutex_unlock(&counter_mutex);
609
        fprintf(stderr,"%s: Could not create thread\n",
610
                my_progname);
611
      }
612
    }
613
614
    /*
615
      We loop until we know that all children have cleaned up.
616
    */
617
    pthread_mutex_lock(&counter_mutex);
618
    while (counter)
619
    {
620
      struct timespec abstime;
621
622
      set_timespec(abstime, 3);
623
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
624
    }
625
    pthread_mutex_unlock(&counter_mutex);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
626
    pthread_mutex_destroy(&counter_mutex);
627
    pthread_cond_destroy(&count_threshhold);
1 by brian
clean slate
628
    pthread_attr_destroy(&attr);
629
  }
630
  else
631
#endif
632
  {
928.1.6 by Eric Day
All utilities done except slap.
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)))
1 by brian
clean slate
637
    {
638
      free_defaults(argv_to_free);
971.6.11 by Eric Day
Removed purecov messages.
639
      return(1);
1 by brian
clean slate
640
    }
641
928.1.6 by Eric Day
All utilities done except slap.
642
    if (drizzle_query_str(con, &result,
643
                          "/*!40101 set @@character_set_database=binary */;",
644
                          &ret) == NULL ||
645
        ret != DRIZZLE_RETURN_OK)
1 by brian
clean slate
646
    {
928.1.6 by Eric Day
All utilities done except slap.
647
      db_error(con, &result, ret, NULL);
648
      /* We shall countinue here, if --force was given */
1 by brian
clean slate
649
      return(1);
650
    }
651
928.1.6 by Eric Day
All utilities done except slap.
652
    drizzle_result_free(&result);
653
1 by brian
clean slate
654
    if (lock_tables)
928.1.6 by Eric Day
All utilities done except slap.
655
      lock_table(con, argc, argv);
1 by brian
clean slate
656
    for (; *argv != NULL; argv++)
928.1.6 by Eric Day
All utilities done except slap.
657
      if ((error= write_to_table(*argv, con)))
1 by brian
clean slate
658
        if (exitcode == 0)
659
          exitcode= error;
928.1.6 by Eric Day
All utilities done except slap.
660
    db_disconnect(current_host, con);
1 by brian
clean slate
661
  }
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
662
  free(opt_password);
1 by brian
clean slate
663
  free_defaults(argv_to_free);
1235.3.14 by Stewart Smith
my_end() no longer requires an argument (we removed them all)
664
  my_end();
1 by brian
clean slate
665
  return(exitcode);
666
}