~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
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
29
#include <string>
30
1 by brian
clean slate
31
#include "client_priv.h"
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;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
60
static const CHARSET_INFO *charset_info= &my_charset_latin1;
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 "
301 by Brian Aker
Clean up port startup
126
   "order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
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);
179
  print_defaults("my",load_default_groups);
180
  my_print_help(my_long_options);
181
  my_print_variables(my_long_options);
182
}
183
143 by Brian Aker
Bool cleanup.
184
static bool
1 by brian
clean slate
185
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
206.3.1 by Patrick Galbraith
Most everything working with client rename
186
         char *argument)
1 by brian
clean slate
187
{
188
  switch(optid) {
189
  case 'p':
190
    if (argument)
191
    {
192
      char *start=argument;
193
      my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
194
      opt_password=my_strdup(argument,MYF(MY_FAE));
206.3.1 by Patrick Galbraith
Most everything working with client rename
195
      while (*argument) *argument++= 'x';    /* Destroy argument */
1 by brian
clean slate
196
      if (*start)
206.3.1 by Patrick Galbraith
Most everything working with client rename
197
  start[1]=0;        /* Cut length of argument */
1 by brian
clean slate
198
      tty_password= 0;
199
    }
200
    else
201
      tty_password= 1;
202
    break;
206.3.1 by Patrick Galbraith
Most everything working with client rename
203
  case OPT_DRIZZLE_PROTOCOL:
1 by brian
clean slate
204
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
205
                                    opt->name);
206
    break;
207
  case 'V': print_version(); exit(0);
208
  case 'I':
209
  case '?':
210
    usage();
211
    exit(0);
212
  }
213
  return 0;
214
}
215
216
217
static int get_options(int *argc, char ***argv)
218
{
219
  int ho_error;
220
221
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
222
    exit(ho_error);
223
  if (debug_info_flag)
224
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
225
  if (debug_check_flag)
226
    my_end_arg= MY_CHECK_ERROR;
227
228
  if (enclosed && opt_enclosed)
229
  {
230
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
231
    return(1);
232
  }
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
233
  if (opt_replace && ignore)
1 by brian
clean slate
234
  {
235
    fprintf(stderr, "You can't use --ignore (-i) and --replace (-r) at the same time.\n");
236
    return(1);
237
  }
238
  if (strcmp(default_charset, charset_info->csname) &&
239
      !(charset_info= get_charset_by_csname(default_charset,
206.3.1 by Patrick Galbraith
Most everything working with client rename
240
                MY_CS_PRIMARY, MYF(MY_WME))))
1 by brian
clean slate
241
    exit(1);
242
  if (*argc < 2)
243
  {
244
    usage();
245
    return 1;
246
  }
247
  current_db= *((*argv)++);
248
  (*argc)--;
249
  if (tty_password)
250
    opt_password=get_tty_password(NullS);
251
  return(0);
252
}
253
254
255
206.3.1 by Patrick Galbraith
Most everything working with client rename
256
static int write_to_table(char *filename, DRIZZLE *drizzle)
1 by brian
clean slate
257
{
258
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
259
       sql_statement[FN_REFLEN*16+256], *end;
260
261
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
262
  if (!opt_local_file)
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
263
    stpcpy(hard_path,filename);
1 by brian
clean slate
264
  else
265
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
266
267
  if (opt_delete)
268
  {
269
    if (verbose)
270
      fprintf(stdout, "Deleting the old data from table %s\n", tablename);
271
#ifdef HAVE_SNPRINTF
272
    snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
273
#else
274
    sprintf(sql_statement, "DELETE FROM %s", tablename);
275
#endif
206.3.1 by Patrick Galbraith
Most everything working with client rename
276
    if (drizzle_query(drizzle, sql_statement))
1 by brian
clean slate
277
    {
206.3.1 by Patrick Galbraith
Most everything working with client rename
278
      db_error_with_table(drizzle, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
279
      return(1);
1 by brian
clean slate
280
    }
281
  }
282
  to_unix_path(hard_path);
283
  if (verbose)
284
  {
285
    if (opt_local_file)
286
      fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
287
        hard_path, tablename);
1 by brian
clean slate
288
    else
289
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
290
        hard_path, tablename);
1 by brian
clean slate
291
  }
292
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
206.3.1 by Patrick Galbraith
Most everything working with client rename
293
    opt_low_priority ? "LOW_PRIORITY" : "",
294
    opt_local_file ? "LOCAL" : "", hard_path);
1 by brian
clean slate
295
  end= strend(sql_statement);
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
296
  if (opt_replace)
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
297
    end= stpcpy(end, " REPLACE");
1 by brian
clean slate
298
  if (ignore)
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
299
    end= stpcpy(end, " IGNORE");
300
  end= stpcpy(stpcpy(end, " INTO TABLE "), tablename);
1 by brian
clean slate
301
302
  if (fields_terminated || enclosed || opt_enclosed || escaped)
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
303
      end= stpcpy(end, " FIELDS");
1 by brian
clean slate
304
  end= add_load_option(end, fields_terminated, " TERMINATED BY");
305
  end= add_load_option(end, enclosed, " ENCLOSED BY");
306
  end= add_load_option(end, opt_enclosed,
206.3.1 by Patrick Galbraith
Most everything working with client rename
307
           " OPTIONALLY ENCLOSED BY");
1 by brian
clean slate
308
  end= add_load_option(end, escaped, " ESCAPED BY");
309
  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
310
  if (opt_ignore_lines >= 0)
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
311
    end= stpcpy(int64_t10_to_str(opt_ignore_lines,
312
          stpcpy(end, " IGNORE "),10), " LINES");
1 by brian
clean slate
313
  if (opt_columns)
266.1.21 by Monty Taylor
Removed references to strmov and strnmov
314
    end= stpcpy(stpcpy(stpcpy(end, " ("), opt_columns), ")");
1 by brian
clean slate
315
  *end= '\0';
316
206.3.1 by Patrick Galbraith
Most everything working with client rename
317
  if (drizzle_query(drizzle, sql_statement))
1 by brian
clean slate
318
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
319
    db_error_with_table(drizzle, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
320
    return(1);
1 by brian
clean slate
321
  }
322
  if (!silent)
323
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
324
    if (drizzle_info(drizzle)) /* If NULL-pointer, print nothing */
1 by brian
clean slate
325
    {
326
      fprintf(stdout, "%s.%s: %s\n", current_db, tablename,
206.3.1 by Patrick Galbraith
Most everything working with client rename
327
        drizzle_info(drizzle));
1 by brian
clean slate
328
    }
329
  }
142.1.2 by Patrick
All DBUG_x removed from client/
330
  return(0);
1 by brian
clean slate
331
}
332
333
334
206.3.1 by Patrick Galbraith
Most everything working with client rename
335
static void lock_table(DRIZZLE *drizzle, int tablecount, char **raw_tablename)
1 by brian
clean slate
336
{
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
337
  string query;
1 by brian
clean slate
338
  int i;
339
  char tablename[FN_REFLEN];
340
341
  if (verbose)
342
    fprintf(stdout, "Locking tables for write\n");
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
343
  query.append("LOCK TABLES ");
1 by brian
clean slate
344
  for (i=0 ; i < tablecount ; i++)
345
  {
346
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
347
    query.append(tablename);
348
    query.append(" WRITE,");
1 by brian
clean slate
349
  }
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
350
  if (drizzle_real_query(drizzle, query.c_str(), query.length()-1))
206.3.1 by Patrick Galbraith
Most everything working with client rename
351
    db_error(drizzle); /* We shall countinue here, if --force was given */
1 by brian
clean slate
352
}
353
354
355
356
206.3.1 by Patrick Galbraith
Most everything working with client rename
357
static DRIZZLE *db_connect(char *host, char *database,
1 by brian
clean slate
358
                         char *user, char *passwd)
359
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
360
  DRIZZLE *drizzle;
1 by brian
clean slate
361
  if (verbose)
362
    fprintf(stdout, "Connecting to %s\n", host ? host : "localhost");
202.2.4 by Monty Taylor
Merged from Patrick.
363
  if (!(drizzle= drizzle_create(NULL)))
1 by brian
clean slate
364
    return 0;
365
  if (opt_compress)
206.3.1 by Patrick Galbraith
Most everything working with client rename
366
    drizzle_options(drizzle,DRIZZLE_OPT_COMPRESS,NullS);
1 by brian
clean slate
367
  if (opt_local_file)
206.3.1 by Patrick Galbraith
Most everything working with client rename
368
    drizzle_options(drizzle,DRIZZLE_OPT_LOCAL_INFILE,
369
      (char*) &opt_local_file);
1 by brian
clean slate
370
  if (opt_protocol)
206.3.1 by Patrick Galbraith
Most everything working with client rename
371
    drizzle_options(drizzle,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
372
  if (!(drizzle_connect(drizzle,host,user,passwd,
373
                           database,opt_drizzle_port,opt_drizzle_unix_port,
1 by brian
clean slate
374
                           0)))
375
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
376
    ignore_errors=0;    /* NO RETURN FROM db_error */
377
    db_error(drizzle);
1 by brian
clean slate
378
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
379
  drizzle->reconnect= 0;
1 by brian
clean slate
380
  if (verbose)
381
    fprintf(stdout, "Selecting database %s\n", database);
206.3.1 by Patrick Galbraith
Most everything working with client rename
382
  if (drizzle_select_db(drizzle, database))
1 by brian
clean slate
383
  {
384
    ignore_errors=0;
206.3.1 by Patrick Galbraith
Most everything working with client rename
385
    db_error(drizzle);
1 by brian
clean slate
386
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
387
  return drizzle;
1 by brian
clean slate
388
}
389
390
391
206.3.1 by Patrick Galbraith
Most everything working with client rename
392
static void db_disconnect(char *host, DRIZZLE *drizzle)
1 by brian
clean slate
393
{
394
  if (verbose)
395
    fprintf(stdout, "Disconnecting from %s\n", host ? host : "localhost");
206.3.1 by Patrick Galbraith
Most everything working with client rename
396
  drizzle_close(drizzle);
1 by brian
clean slate
397
}
398
399
400
206.3.1 by Patrick Galbraith
Most everything working with client rename
401
static void safe_exit(int error, DRIZZLE *drizzle)
1 by brian
clean slate
402
{
403
  if (ignore_errors)
404
    return;
206.3.1 by Patrick Galbraith
Most everything working with client rename
405
  if (drizzle)
406
    drizzle_close(drizzle);
1 by brian
clean slate
407
  exit(error);
408
}
409
410
411
206.3.1 by Patrick Galbraith
Most everything working with client rename
412
static void db_error_with_table(DRIZZLE *drizzle, char *table)
1 by brian
clean slate
413
{
414
  my_printf_error(0,"Error: %d, %s, when using table: %s",
206.3.1 by Patrick Galbraith
Most everything working with client rename
415
      MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle), table);
416
  safe_exit(1, drizzle);
1 by brian
clean slate
417
}
418
419
420
206.3.1 by Patrick Galbraith
Most everything working with client rename
421
static void db_error(DRIZZLE *drizzle)
1 by brian
clean slate
422
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
423
  my_printf_error(0,"Error: %d %s", MYF(0), drizzle_errno(drizzle), drizzle_error(drizzle));
424
  safe_exit(1, drizzle);
1 by brian
clean slate
425
}
426
427
428
static char *add_load_option(char *ptr, const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
429
           const char *statement)
1 by brian
clean slate
430
{
431
  if (object)
432
  {
433
    /* Don't escape hex constants */
434
    if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
435
      ptr= strxmov(ptr," ",statement," ",object,NullS);
436
    else
437
    {
438
      /* char constant; escape */
439
      ptr= strxmov(ptr," ",statement," '",NullS);
440
      ptr= field_escape(ptr,object,(uint) strlen(object));
441
      *ptr++= '\'';
442
    }
443
  }
444
  return ptr;
445
}
446
447
/*
448
** Allow the user to specify field terminator strings like:
449
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
450
** This is done by doubleing ' and add a end -\ if needed to avoid
451
** syntax errors from the SQL parser.
206.3.1 by Patrick Galbraith
Most everything working with client rename
452
*/
1 by brian
clean slate
453
454
static char *field_escape(char *to,const char *from,uint length)
455
{
456
  const char *end;
206.3.1 by Patrick Galbraith
Most everything working with client rename
457
  uint end_backslashes=0;
1 by brian
clean slate
458
459
  for (end= from+length; from != end; from++)
460
  {
461
    *to++= *from;
462
    if (*from == '\\')
463
      end_backslashes^=1;    /* find odd number of backslashes */
206.3.1 by Patrick Galbraith
Most everything working with client rename
464
    else
1 by brian
clean slate
465
    {
466
      if (*from == '\'' && !end_backslashes)
206.3.1 by Patrick Galbraith
Most everything working with client rename
467
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
1 by brian
clean slate
468
      end_backslashes=0;
469
    }
470
  }
471
  /* Add missing backslashes if user has specified odd number of backs.*/
472
  if (end_backslashes)
206.3.1 by Patrick Galbraith
Most everything working with client rename
473
    *to++= '\\';         
1 by brian
clean slate
474
  return to;
475
}
476
477
int exitcode= 0;
478
279.2.4 by Monty Taylor
Moved import, check and dump to C++... fixed errors.
479
static void * worker_thread(void *arg)
1 by brian
clean slate
480
{
481
  int error;
482
  char *raw_table_name= (char *)arg;
206.3.1 by Patrick Galbraith
Most everything working with client rename
483
  DRIZZLE *drizzle= 0;
1 by brian
clean slate
484
206.3.1 by Patrick Galbraith
Most everything working with client rename
485
  if (drizzle_thread_init())
1 by brian
clean slate
486
    goto error;
206.3.1 by Patrick Galbraith
Most everything working with client rename
487
 
488
  if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
489
  {
490
    goto error;
491
  }
492
206.3.1 by Patrick Galbraith
Most everything working with client rename
493
  if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
1 by brian
clean slate
494
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
495
    db_error(drizzle); /* We shall countinue here, if --force was given */
1 by brian
clean slate
496
    goto error;
497
  }
498
499
  /*
500
    We are not currently catching the error here.
501
  */
206.3.1 by Patrick Galbraith
Most everything working with client rename
502
  if((error= write_to_table(raw_table_name, drizzle)))
1 by brian
clean slate
503
    if (exitcode == 0)
504
      exitcode= error;
505
506
error:
206.3.1 by Patrick Galbraith
Most everything working with client rename
507
  if (drizzle)
508
    db_disconnect(current_host, drizzle);
1 by brian
clean slate
509
510
  pthread_mutex_lock(&counter_mutex);
511
  counter--;
512
  pthread_cond_signal(&count_threshhold);
513
  pthread_mutex_unlock(&counter_mutex);
514
  my_thread_end();
515
516
  return 0;
517
}
518
519
520
int main(int argc, char **argv)
521
{
522
  int error=0;
523
  char **argv_to_free;
524
  MY_INIT(argv[0]);
525
526
  load_defaults("my",load_default_groups,&argc,&argv);
527
  /* argv is changed in the program */
528
  argv_to_free= argv;
529
  if (get_options(&argc, &argv))
530
  {
531
    free_defaults(argv_to_free);
532
    return(1);
533
  }
534
535
#ifdef HAVE_LIBPTHREAD
536
  if (opt_use_threads && !lock_tables)
537
  {
538
    pthread_t mainthread;            /* Thread descriptor */
539
    pthread_attr_t attr;          /* Thread attributes */
540
    pthread_attr_init(&attr);
541
    pthread_attr_setdetachstate(&attr,
542
                                PTHREAD_CREATE_DETACHED);
543
544
    VOID(pthread_mutex_init(&counter_mutex, NULL));
545
    VOID(pthread_cond_init(&count_threshhold, NULL));
546
547
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
548
    {
549
      pthread_mutex_lock(&counter_mutex);
550
      while (counter == opt_use_threads)
551
      {
552
        struct timespec abstime;
553
554
        set_timespec(abstime, 3);
555
        pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
556
      }
557
      /* Before exiting the lock we set ourselves up for the next thread */
558
      counter++;
559
      pthread_mutex_unlock(&counter_mutex);
560
      /* now create the thread */
206.3.1 by Patrick Galbraith
Most everything working with client rename
561
      if (pthread_create(&mainthread, &attr, worker_thread,
1 by brian
clean slate
562
                         (void *)*argv) != 0)
563
      {
564
        pthread_mutex_lock(&counter_mutex);
565
        counter--;
566
        pthread_mutex_unlock(&counter_mutex);
567
        fprintf(stderr,"%s: Could not create thread\n",
568
                my_progname);
569
      }
570
    }
571
572
    /*
573
      We loop until we know that all children have cleaned up.
574
    */
575
    pthread_mutex_lock(&counter_mutex);
576
    while (counter)
577
    {
578
      struct timespec abstime;
579
580
      set_timespec(abstime, 3);
581
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
582
    }
583
    pthread_mutex_unlock(&counter_mutex);
584
    VOID(pthread_mutex_destroy(&counter_mutex));
585
    VOID(pthread_cond_destroy(&count_threshhold));
586
    pthread_attr_destroy(&attr);
587
  }
588
  else
589
#endif
590
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
591
    DRIZZLE *drizzle= 0;
592
    if (!(drizzle= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
593
    {
594
      free_defaults(argv_to_free);
595
      return(1); /* purecov: deadcode */
596
    }
597
206.3.1 by Patrick Galbraith
Most everything working with client rename
598
    if (drizzle_query(drizzle, "/*!40101 set @@character_set_database=binary */;"))
1 by brian
clean slate
599
    {
206.3.1 by Patrick Galbraith
Most everything working with client rename
600
      db_error(drizzle); /* We shall countinue here, if --force was given */
1 by brian
clean slate
601
      return(1);
602
    }
603
604
    if (lock_tables)
206.3.1 by Patrick Galbraith
Most everything working with client rename
605
      lock_table(drizzle, argc, argv);
1 by brian
clean slate
606
    for (; *argv != NULL; argv++)
206.3.1 by Patrick Galbraith
Most everything working with client rename
607
      if ((error= write_to_table(*argv, drizzle)))
1 by brian
clean slate
608
        if (exitcode == 0)
609
          exitcode= error;
206.3.1 by Patrick Galbraith
Most everything working with client rename
610
    db_disconnect(current_host, drizzle);
1 by brian
clean slate
611
  }
612
  my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
613
  free_defaults(argv_to_free);
614
  my_end(my_end_arg);
615
  return(exitcode);
616
}