~drizzle-trunk/drizzle/development

206.3.1 by Patrick Galbraith
Most everything working with client rename
1
/* Copyright (C) 2008 Drizzle Open Source Development Team
1 by brian
clean slate
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
206.3.1 by Patrick Galbraith
Most everything working with client rename
17
**     drizzleimport.c  - Imports all given files
18
**          into a table(s).
1 by brian
clean slate
19
**
206.3.1 by Patrick Galbraith
Most everything working with client rename
20
**         *************************
21
**         *         *
22
**         * AUTHOR: Monty & Jani  *
23
**         * DATE:   June 24, 1997 *
24
**         *         *
25
**         *************************
1 by brian
clean slate
26
*/
27
#define IMPORT_VERSION "3.7"
28
612.2.4 by Monty Taylor
Moved some defines to config.h. Stopped including config.h directly anywhere.
29
#include "client_priv.h"
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
30
#include <string>
31
279.2.4 by Monty Taylor
Moved import, check and dump to C++... fixed errors.
32
#include <pthread.h>
1 by brian
clean slate
33
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
34
/* Added this for string translation. */
35
#include <drizzled/gettext.h>
36
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
37
using namespace std;
1 by brian
clean slate
38
39
/* Global Thread counter */
40
uint counter;
41
pthread_mutex_t counter_mutex;
42
pthread_cond_t count_threshhold;
43
206.3.1 by Patrick Galbraith
Most everything working with client rename
44
static void db_error_with_table(DRIZZLE *drizzle, char *table);
45
static void db_error(DRIZZLE *drizzle);
1 by brian
clean slate
46
static char *field_escape(char *to,const char *from,uint length);
47
static char *add_load_option(char *ptr,const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
48
           const char *statement);
1 by brian
clean slate
49
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
50
static bool verbose= false, lock_tables= false, ignore_errors= false,
51
            opt_delete= false, opt_replace= false, silent= false,
52
            ignore= 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 uint 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,
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
60
    *default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
61
static uint opt_protocol= 0;
62
static uint32_t opt_drizzle_port= 0;
63
static char * opt_drizzle_unix_port= 0;
152 by Brian Aker
longlong replacement
64
static int64_t opt_ignore_lines= -1;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
65
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
1 by brian
clean slate
66
67
static struct my_option my_long_options[] =
68
{
69
  {"character-sets-dir", OPT_CHARSETS_DIR,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
70
   "Directory where character sets are.", (char**) &charsets_dir,
71
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
72
  {"default-character-set", OPT_DEFAULT_CHARSET,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
73
   "Set the default character set.", (char**) &default_charset,
74
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
75
  {"columns", 'c',
76
   "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)
77
   (char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
1 by brian
clean slate
78
   0, 0, 0},
79
  {"compress", 'C', "Use compression in server/client protocol.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
80
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1 by brian
clean slate
81
   0, 0, 0},
82
  {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
83
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
84
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
85
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
1 by brian
clean slate
86
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
87
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
88
   (char**) &debug_info_flag, (char**) &debug_info_flag,
1 by brian
clean slate
89
   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)
90
  {"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
91
   (char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
92
  {"fields-terminated-by", OPT_FTB,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
93
   "Fields in the textfile are terminated by ...", (char**) &fields_terminated,
94
   (char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
95
  {"fields-enclosed-by", OPT_ENC,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
96
   "Fields in the importfile are enclosed by ...", (char**) &enclosed,
97
   (char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
98
  {"fields-optionally-enclosed-by", OPT_O_ENC,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
99
   "Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
100
   (char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
101
  {"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)
102
   (char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
1 by brian
clean slate
103
   0, 0},
104
  {"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)
105
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
1 by brian
clean slate
106
   0, 0, 0, 0},
107
  {"help", '?', "Displays this help and exits.", 0, 0, 0, GET_NO_ARG, NO_ARG,
108
   0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
109
  {"host", 'h', "Connect to host.", (char**) &current_host,
110
   (char**) &current_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
111
  {"ignore", 'i', "If duplicate unique key was found, keep old row.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
112
   (char**) &ignore, (char**) &ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
113
  {"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)
114
   (char**) &opt_ignore_lines, (char**) &opt_ignore_lines, 0, GET_LL,
1 by brian
clean slate
115
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
116
  {"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)
117
   (char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
1 by brian
clean slate
118
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
119
  {"local", 'L', "Read all files through the client.", (char**) &opt_local_file,
120
   (char**) &opt_local_file, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
121
  {"lock-tables", 'l', "Lock all tables for write (this disables threads).",
206.3.1 by Patrick Galbraith
Most everything working with client rename
122
    (char**) &lock_tables, (char**) &lock_tables, 0, GET_BOOL, NO_ARG,
1 by brian
clean slate
123
    0, 0, 0, 0, 0, 0},
124
  {"low-priority", OPT_LOW_PRIORITY,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
125
   "Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
126
   (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
127
  {"password", 'P',
1 by brian
clean slate
128
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
129
   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
130
  {"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.
131
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
301 by Brian Aker
Clean up port startup
132
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
133
   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
134
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
1 by brian
clean slate
135
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
136
  {"replace", 'r', "If duplicate unique key was found, replace old row.",
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
137
   (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)
138
  {"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
1 by brian
clean slate
139
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
140
  {"socket", 'S', "Socket file to use for connection.",
206.3.1 by Patrick Galbraith
Most everything working with client rename
141
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
1 by brian
clean slate
142
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
143
  {"use-threads", OPT_USE_THREADS,
144
   "Load files in parallel. The argument is the number "
145
   "of threads to use for loading data.",
206.3.1 by Patrick Galbraith
Most everything working with client rename
146
   (char**) &opt_use_threads, (char**) &opt_use_threads, 0,
1 by brian
clean slate
147
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
148
#ifndef DONT_ALLOW_USER_CHANGE
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
149
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
150
   (char**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
151
#endif
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
152
  {"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
153
   (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
154
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
155
   NO_ARG, 0, 0, 0, 0, 0, 0},
156
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
157
};
158
159
206.3.1 by Patrick Galbraith
Most everything working with client rename
160
static const char *load_default_groups[]= { "drizzleimport","client",0 };
1 by brian
clean slate
161
162
static void print_version(void)
163
{
164
  printf("%s  Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
264.1.10 by Monty Taylor
Removed client insistence on version.h stuff.
165
    IMPORT_VERSION, drizzle_get_client_info(),SYSTEM_TYPE,MACHINE_TYPE);
1 by brian
clean slate
166
}
167
168
169
static void usage(void)
170
{
171
  print_version();
206.3.1 by Patrick Galbraith
Most everything working with client rename
172
  puts("Copyright (C) 2008 Drizzle Open Source Development Team");
1 by brian
clean slate
173
  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");
174
  printf("\
175
Loads tables from text files in various formats.  The base name of the\n\
176
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
177
If one uses sockets to connect to the Drizzle server, the server will open and\n\
1 by brian
clean slate
178
read the text file directly. In other cases the client will open the text\n\
179
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
180
181
  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.
182
  print_defaults("drizzle",load_default_groups);
1 by brian
clean slate
183
  my_print_help(my_long_options);
184
  my_print_variables(my_long_options);
185
}
186
632.1.12 by Monty Taylor
Fixed more sun studio warnings.
187
extern "C"
637 by Brian Aker
Merge from Monty
188
bool get_one_option(int optid, const struct my_option *, char *argument)
1 by brian
clean slate
189
{
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
190
  char *endchar= NULL;
191
  uint64_t temp_drizzle_port= 0;
192
1 by brian
clean slate
193
  switch(optid) {
194
  case 'p':
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
195
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
196
    /* if there is an alpha character this is not a valid port */
197
    if (strlen(endchar) != 0)
198
    {
199
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
200
      exit(1);
201
    }
202
    /* If the port number is > 65535 it is not a valid port
203
       This also helps with potential data loss casting unsigned long to a
204
       uint32_t. */
205
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
206
    {
207
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
208
      exit(1);
209
    }
210
    else
211
    {
212
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
213
    }
214
    break;
215
  case 'P':
1 by brian
clean slate
216
    if (argument)
217
    {
218
      char *start=argument;
656.1.51 by Monty Taylor
Fixed strdup return checking in client/
219
      if (opt_password)
220
        free(opt_password);
221
      opt_password = strdup(argument);
222
      if (opt_password == NULL)
223
      {
224
        fprintf(stderr, "Memory allocation error while copying password. "
225
                        "Aborting.\n");
226
        exit(ENOMEM);
227
      }
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
228
      while (*argument)
229
      {
230
        /* Overwriting password with 'x' */
231
        *argument++= 'x';
232
      }
1 by brian
clean slate
233
      if (*start)
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
234
      {
235
        /* Cut length of argument */
236
        start[1]= 0;
237
      }
1 by brian
clean slate
238
      tty_password= 0;
239
    }
240
    else
241
      tty_password= 1;
242
    break;
206.3.1 by Patrick Galbraith
Most everything working with client rename
243
  case OPT_DRIZZLE_PROTOCOL:
1 by brian
clean slate
244
    break;
245
  case 'V': print_version(); exit(0);
246
  case 'I':
247
  case '?':
248
    usage();
249
    exit(0);
250
  }
251
  return 0;
252
}
253
254
255
static int get_options(int *argc, char ***argv)
256
{
257
  int ho_error;
258
259
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
260
    exit(ho_error);
261
  if (debug_info_flag)
262
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
263
  if (debug_check_flag)
264
    my_end_arg= MY_CHECK_ERROR;
265
266
  if (enclosed && opt_enclosed)
267
  {
268
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
269
    return(1);
270
  }
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
271
  if (opt_replace && ignore)
1 by brian
clean slate
272
  {
273
    fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
274
    return(1);
275
  }
276
  if (strcmp(default_charset, charset_info->csname) &&
277
      !(charset_info= get_charset_by_csname(default_charset,
206.3.1 by Patrick Galbraith
Most everything working with client rename
278
                MY_CS_PRIMARY, MYF(MY_WME))))
1 by brian
clean slate
279
    exit(1);
280
  if (*argc < 2)
281
  {
282
    usage();
283
    return 1;
284
  }
285
  current_db= *((*argv)++);
286
  (*argc)--;
287
  if (tty_password)
461 by Monty Taylor
Removed NullS. bu-bye.
288
    opt_password=get_tty_password(NULL);
1 by brian
clean slate
289
  return(0);
290
}
291
292
293
206.3.1 by Patrick Galbraith
Most everything working with client rename
294
static int write_to_table(char *filename, DRIZZLE *drizzle)
1 by brian
clean slate
295
{
296
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
297
       sql_statement[FN_REFLEN*16+256], *end;
298
299
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
300
  if (!opt_local_file)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
301
    strcpy(hard_path,filename);
1 by brian
clean slate
302
  else
303
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
304
305
  if (opt_delete)
306
  {
307
    if (verbose)
308
      fprintf(stdout, "Deleting the old data from table %s\n", tablename);
309
#ifdef HAVE_SNPRINTF
310
    snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
311
#else
312
    sprintf(sql_statement, "DELETE FROM %s", tablename);
313
#endif
206.3.1 by Patrick Galbraith
Most everything working with client rename
314
    if (drizzle_query(drizzle, sql_statement))
1 by brian
clean slate
315
    {
206.3.1 by Patrick Galbraith
Most everything working with client rename
316
      db_error_with_table(drizzle, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
317
      return(1);
1 by brian
clean slate
318
    }
319
  }
320
  to_unix_path(hard_path);
321
  if (verbose)
322
  {
323
    if (opt_local_file)
324
      fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
325
        hard_path, tablename);
1 by brian
clean slate
326
    else
327
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
328
        hard_path, tablename);
1 by brian
clean slate
329
  }
330
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
206.3.1 by Patrick Galbraith
Most everything working with client rename
331
    opt_low_priority ? "LOW_PRIORITY" : "",
332
    opt_local_file ? "LOCAL" : "", hard_path);
376 by Brian Aker
strend remove
333
  end= strchr(sql_statement, '\0');
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
334
  if (opt_replace)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
335
    end= strcpy(end, " REPLACE")+8;
1 by brian
clean slate
336
  if (ignore)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
337
    end= strcpy(end, " IGNORE")+7;
338
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
339
  end+= sprintf(end, " INTO TABLE %s", tablename);
1 by brian
clean slate
340
341
  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
342
      end= strcpy(end, " FIELDS")+7;
1 by brian
clean slate
343
  end= add_load_option(end, fields_terminated, " TERMINATED BY");
344
  end= add_load_option(end, enclosed, " ENCLOSED BY");
345
  end= add_load_option(end, opt_enclosed,
206.3.1 by Patrick Galbraith
Most everything working with client rename
346
           " OPTIONALLY ENCLOSED BY");
1 by brian
clean slate
347
  end= add_load_option(end, escaped, " ESCAPED BY");
348
  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
349
  if (opt_ignore_lines >= 0)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
350
  {
351
    end= strcpy(end, " IGNORE ")+8;
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
352
    end= int64_t2str(opt_ignore_lines, end, 10);
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
353
    end= strcpy(end, " LINES")+6;
354
  }
1 by brian
clean slate
355
  if (opt_columns)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
356
  {
357
    end= strcpy(end, " (")+2;
358
    end= strcpy(end, opt_columns)+strlen(opt_columns);
359
    end= strcpy(end, ")")+1;
360
  }
1 by brian
clean slate
361
  *end= '\0';
362
206.3.1 by Patrick Galbraith
Most everything working with client rename
363
  if (drizzle_query(drizzle, sql_statement))
1 by brian
clean slate
364
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
365
    db_error_with_table(drizzle, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
366
    return(1);
1 by brian
clean slate
367
  }
368
  if (!silent)
369
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
370
    if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
1 by brian
clean slate
371
    {
372
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
206.3.1 by Patrick Galbraith
Most everything working with client rename
373
        drizzle_info(drizzle));
1 by brian
clean slate
374
    }
375
  }
142.1.2 by Patrick
All DBUG_x removed from client/
376
  return(0);
1 by brian
clean slate
377
}
378
379
380
206.3.1 by Patrick Galbraith
Most everything working with client rename
381
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
1 by brian
clean slate
382
{
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
383
  string query;
1 by brian
clean slate
384
  int i;
385
  char tablename[FN_REFLEN];
386
387
  if (verbose)
388
    fprintf(stdout, "Locking tables for write\n");
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
389
  query.append("LOCK TABLES ");
1 by brian
clean slate
390
  for (i=0 ; i < tablecount ; i++)
391
  {
392
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
393
    query.append(tablename);
394
    query.append(" WRITE,");
1 by brian
clean slate
395
  }
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
396
  if (drizzle_real_query(drizzle, query.c_str(), query.length()-1))
206.3.1 by Patrick Galbraith
Most everything working with client rename
397
    db_error(drizzle); /* We shall countinue here, if --force was given */
1 by brian
clean slate
398
}
399
400
401
402
206.3.1 by Patrick Galbraith
Most everything working with client rename
403
static DRIZZLE *db_connect(char *host, char *database,
1 by brian
clean slate
404
                         char *user, char *passwd)
405
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
406
  DRIZZLE *drizzle;
1 by brian
clean slate
407
  if (verbose)
408
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
202.2.4 by Monty Taylor
Merged from Patrick.
409
  if (!(drizzle= drizzle_create(NULL)))
1 by brian
clean slate
410
    return 0;
411
  if (opt_compress)
461 by Monty Taylor
Removed NullS. bu-bye.
412
    drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NULL);
1 by brian
clean slate
413
  if (opt_local_file)
206.3.1 by Patrick Galbraith
Most everything working with client rename
414
    drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
415
      (char*) &opt_local_file);
1 by brian
clean slate
416
  if (opt_protocol)
206.3.1 by Patrick Galbraith
Most everything working with client rename
417
    drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
418
  if (!(drizzle_connect(drizzle,host,user,passwd,
419
                           database,opt_drizzle_port,opt_drizzle_unix_port,
1 by brian
clean slate
420
                           0)))
421
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
422
    ignore_errors=0;    /* NO RETURN FROM db_error */
423
    db_error(drizzle);
1 by brian
clean slate
424
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
425
  drizzle->reconnect= 0;
1 by brian
clean slate
426
  if (verbose)
427
    fprintf(stdout, "Selecting database %s\n", database);
206.3.1 by Patrick Galbraith
Most everything working with client rename
428
  if (drizzle_select_db(drizzle, database))
1 by brian
clean slate
429
  {
430
    ignore_errors=0;
206.3.1 by Patrick Galbraith
Most everything working with client rename
431
    db_error(drizzle);
1 by brian
clean slate
432
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
433
  return drizzle;
1 by brian
clean slate
434
}
435
436
437
206.3.1 by Patrick Galbraith
Most everything working with client rename
438
static void db_disconnect(char *host, DRIZZLE *drizzle)
1 by brian
clean slate
439
{
440
  if (verbose)
441
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
206.3.1 by Patrick Galbraith
Most everything working with client rename
442
  drizzle_close(drizzle);
1 by brian
clean slate
443
}
444
445
446
206.3.1 by Patrick Galbraith
Most everything working with client rename
447
static void safe_exit(int error, DRIZZLE *drizzle)
1 by brian
clean slate
448
{
449
  if (ignore_errors)
450
    return;
206.3.1 by Patrick Galbraith
Most everything working with client rename
451
  if (drizzle)
452
    drizzle_close(drizzle);
1 by brian
clean slate
453
  exit(error);
454
}
455
456
457
206.3.1 by Patrick Galbraith
Most everything working with client rename
458
static void db_error_with_table(DRIZZLE *drizzle, char *table)
1 by brian
clean slate
459
{
460
  my_printf_error(0,"Error: %d, %s, when using table: %s",
206.3.1 by Patrick Galbraith
Most everything working with client rename
461
      MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
462
  safe_exit(1, drizzle);
1 by brian
clean slate
463
}
464
465
466
206.3.1 by Patrick Galbraith
Most everything working with client rename
467
static void db_error(DRIZZLE *drizzle)
1 by brian
clean slate
468
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
469
  my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
470
  safe_exit(1, drizzle);
1 by brian
clean slate
471
}
472
473
474
static char *add_load_option(char *ptr, const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
475
           const char *statement)
1 by brian
clean slate
476
{
477
  if (object)
478
  {
479
    /* Don't escape hex constants */
480
    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
481
      ptr+= sprintf(ptr, " %s %s", statement, object);
1 by brian
clean slate
482
    else
483
    {
484
      /* char constant; escape */
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
485
      ptr+= sprintf(ptr, " %s '", statement); 
1 by brian
clean slate
486
      ptr= field_escape(ptr,object,(uint) strlen(object));
487
      *ptr++= '\'';
488
    }
489
  }
490
  return ptr;
491
}
492
493
/*
494
** Allow the user to specify field terminator strings like:
495
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
496
** This is done by doubleing ' and add a end -\ if needed to avoid
497
** syntax errors from the SQL parser.
206.3.1 by Patrick Galbraith
Most everything working with client rename
498
*/
1 by brian
clean slate
499
500
static char *field_escape(char *to,const char *from,uint length)
501
{
502
  const char *end;
206.3.1 by Patrick Galbraith
Most everything working with client rename
503
  uint end_backslashes=0;
1 by brian
clean slate
504
505
  for (end= from+length; from != end; from++)
506
  {
507
    *to++= *from;
508
    if (*from == '\\')
509
      end_backslashes^=1;    /* find odd number of backslashes */
206.3.1 by Patrick Galbraith
Most everything working with client rename
510
    else
1 by brian
clean slate
511
    {
512
      if (*from == '\'' && !end_backslashes)
206.3.1 by Patrick Galbraith
Most everything working with client rename
513
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
1 by brian
clean slate
514
      end_backslashes=0;
515
    }
516
  }
517
  /* Add missing backslashes if user has specified odd number of backs.*/
518
  if (end_backslashes)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
519
    *to++= '\\';
1 by brian
clean slate
520
  return to;
521
}
522
523
int exitcode= 0;
524
632.1.12 by Monty Taylor
Fixed more sun studio warnings.
525
extern "C"
526
void * worker_thread(void *arg)
1 by brian
clean slate
527
{
528
  int error;
529
  char *raw_table_name= (char *)arg;
206.3.1 by Patrick Galbraith
Most everything working with client rename
530
  DRIZZLE *drizzle= 0;
1 by brian
clean slate
531
206.3.1 by Patrick Galbraith
Most everything working with client rename
532
  if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
533
  {
534
    goto error;
535
  }
536
206.3.1 by Patrick Galbraith
Most everything working with client rename
537
  if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
1 by brian
clean slate
538
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
539
    db_error(drizzle); /* We shall countinue here, if --force was given */
1 by brian
clean slate
540
    goto error;
541
  }
542
543
  /*
544
    We are not currently catching the error here.
545
  */
206.3.1 by Patrick Galbraith
Most everything working with client rename
546
  if((error= write_to_table(raw_table_name, drizzle)))
1 by brian
clean slate
547
    if (exitcode == 0)
548
      exitcode= error;
549
550
error:
206.3.1 by Patrick Galbraith
Most everything working with client rename
551
  if (drizzle)
552
    db_disconnect(current_host, drizzle);
1 by brian
clean slate
553
554
  pthread_mutex_lock(&counter_mutex);
555
  counter--;
556
  pthread_cond_signal(&count_threshhold);
557
  pthread_mutex_unlock(&counter_mutex);
558
  my_thread_end();
559
560
  return 0;
561
}
562
563
564
int main(int argc, char **argv)
565
{
566
  int error=0;
567
  char **argv_to_free;
568
  MY_INIT(argv[0]);
569
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
570
  load_defaults("drizzle",load_default_groups,&argc,&argv);
1 by brian
clean slate
571
  /* argv is changed in the program */
572
  argv_to_free= argv;
573
  if (get_options(&argc, &argv))
574
  {
575
    free_defaults(argv_to_free);
576
    return(1);
577
  }
578
579
#ifdef HAVE_LIBPTHREAD
580
  if (opt_use_threads && !lock_tables)
581
  {
582
    pthread_t mainthread;            /* Thread descriptor */
583
    pthread_attr_t attr;          /* Thread attributes */
584
    pthread_attr_init(&attr);
585
    pthread_attr_setdetachstate(&attr,
586
                                PTHREAD_CREATE_DETACHED);
587
398.1.10 by Monty Taylor
Actually removed VOID() this time.
588
    pthread_mutex_init(&counter_mutex, NULL);
589
    pthread_cond_init(&count_threshhold, NULL);
1 by brian
clean slate
590
591
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
592
    {
593
      pthread_mutex_lock(&counter_mutex);
594
      while (counter == opt_use_threads)
595
      {
596
        struct timespec abstime;
597
598
        set_timespec(abstime, 3);
599
        pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
600
      }
601
      /* Before exiting the lock we set ourselves up for the next thread */
602
      counter++;
603
      pthread_mutex_unlock(&counter_mutex);
604
      /* now create the thread */
206.3.1 by Patrick Galbraith
Most everything working with client rename
605
      if (pthread_create(&mainthread, &attr, worker_thread,
1 by brian
clean slate
606
                         (void *)*argv) != 0)
607
      {
608
        pthread_mutex_lock(&counter_mutex);
609
        counter--;
610
        pthread_mutex_unlock(&counter_mutex);
611
        fprintf(stderr,"%s: Could not create thread\n",
612
                my_progname);
613
      }
614
    }
615
616
    /*
617
      We loop until we know that all children have cleaned up.
618
    */
619
    pthread_mutex_lock(&counter_mutex);
620
    while (counter)
621
    {
622
      struct timespec abstime;
623
624
      set_timespec(abstime, 3);
625
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
626
    }
627
    pthread_mutex_unlock(&counter_mutex);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
628
    pthread_mutex_destroy(&counter_mutex);
629
    pthread_cond_destroy(&count_threshhold);
1 by brian
clean slate
630
    pthread_attr_destroy(&attr);
631
  }
632
  else
633
#endif
634
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
635
    DRIZZLE *drizzle= 0;
636
    if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
637
    {
638
      free_defaults(argv_to_free);
639
      return(1); /* purecov: deadcode */
640
    }
641
206.3.1 by Patrick Galbraith
Most everything working with client rename
642
    if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
1 by brian
clean slate
643
    {
206.3.1 by Patrick Galbraith
Most everything working with client rename
644
      db_error(drizzle); /* We shall countinue here, if --force was given */
1 by brian
clean slate
645
      return(1);
646
    }
647
648
    if (lock_tables)
206.3.1 by Patrick Galbraith
Most everything working with client rename
649
      lock_table(drizzle, argc, argv);
1 by brian
clean slate
650
    for (; *argv != NULL; argv++)
206.3.1 by Patrick Galbraith
Most everything working with client rename
651
      if ((error= write_to_table(*argv, drizzle)))
1 by brian
clean slate
652
        if (exitcode == 0)
653
          exitcode= error;
206.3.1 by Patrick Galbraith
Most everything working with client rename
654
    db_disconnect(current_host, drizzle);
1 by brian
clean slate
655
  }
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.
656
  free(opt_password);
1 by brian
clean slate
657
  free_defaults(argv_to_free);
658
  my_end(my_end_arg);
659
  return(exitcode);
660
}