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