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