~drizzle-trunk/drizzle/development

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