~drizzle-trunk/drizzle/development

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