~drizzle-trunk/drizzle/development

1615 by Brian Aker
MErge VJ
1
/* 
2
  Copyright (C) 2010 Vijay Samuel
1707.1.23 by Brian Aker
Cleanup of import.
3
  Copyright (C) 2010 Brian Aker
1615 by Brian Aker
MErge VJ
4
  Copyright (C) 2000-2006 MySQL AB
5
  Copyright (C) 2008-2009 Sun Microsystems, Inc
6
7
  This program is free software; you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation; version 2 of the License.
10
11
  This program is distributed in the hope that it will be useful,
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
  GNU General Public License for more details.
15
16
  You should have received a copy of the GNU General Public License
17
  along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
18
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
19
1707.1.23 by Brian Aker
Cleanup of import.
20
#define IMPORT_VERSION "4.0"
1 by brian
clean slate
21
612.2.4 by Monty Taylor
Moved some defines to config.h. Stopped including config.h directly anywhere.
22
#include "client_priv.h"
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
23
#include <string>
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
24
#include <sstream>
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
25
#include <iostream>
26
#include <fstream>
27
#include <boost/program_options.hpp>
279.2.4 by Monty Taylor
Moved import, check and dump to C++... fixed errors.
28
#include <pthread.h>
1 by brian
clean slate
29
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
30
/* Added this for string translation. */
31
#include <drizzled/gettext.h>
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
32
#include <drizzled/configmake.h>
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
33
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
34
namespace po= boost::program_options;
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
35
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
36
using namespace drizzled;
1 by brian
clean slate
37
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
38
extern "C" void * worker_thread(void *arg);
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
39
40
int exitcode= 0;
41
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
42
const char *program_name= "drizzlesimport";
43
1 by brian
clean slate
44
/* Global Thread counter */
893 by Brian Aker
First pass of stripping uint
45
uint32_t counter;
1 by brian
clean slate
46
pthread_mutex_t counter_mutex;
47
pthread_cond_t count_threshhold;
48
928.1.6 by Eric Day
All utilities done except slap.
49
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
50
                     drizzle_return_t ret, char *table);
893 by Brian Aker
First pass of stripping uint
51
static char *field_escape(char *to,const char *from,uint32_t length);
1 by brian
clean slate
52
static char *add_load_option(char *ptr,const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
53
           const char *statement);
1 by brian
clean slate
54
1707.1.23 by Brian Aker
Cleanup of import.
55
static bool verbose= false, ignore_errors= false,
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
56
            opt_delete= false, opt_replace= false, silent= false,
1235.3.7 by Stewart Smith
remove outdated --compress option from drizzleimport
57
            ignore_unique= false, opt_low_priority= false,
1745.2.1 by LinuxJedi
Remove the --mysql option and convert the --protocol option to do something similar.
58
            use_drizzle_protocol= false, opt_local_file;
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.
59
1707.1.23 by Brian Aker
Cleanup of import.
60
static uint32_t opt_use_threads;
673.5.13 by Andrew Hutchings
Apply -p means port changes to all client apps
61
static uint32_t opt_drizzle_port= 0;
152 by Brian Aker
longlong replacement
62
static int64_t opt_ignore_lines= -1;
1 by brian
clean slate
63
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
64
std::string opt_columns,
65
  opt_enclosed,
66
  escaped,
67
  password,
68
  current_db,
69
  lines_terminated,
70
  current_user,
71
  opt_password,
72
  enclosed,  
73
  current_host,
1745.2.1 by LinuxJedi
Remove the --mysql option and convert the --protocol option to do something similar.
74
  fields_terminated,
75
  opt_protocol;
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
76
77
78
static int get_options(void)
79
{
80
81
  if (! enclosed.empty() && ! opt_enclosed.empty())
1 by brian
clean slate
82
  {
83
    fprintf(stderr, "You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n");
84
    return(1);
85
  }
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
86
  if (opt_replace && ignore_unique)
1 by brian
clean slate
87
  {
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
88
    fprintf(stderr, "You can't use --ignore_unique (-i) and --replace (-r) at the same time.\n");
1 by brian
clean slate
89
    return(1);
90
  }
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
91
1 by brian
clean slate
92
  if (tty_password)
928.1.6 by Eric Day
All utilities done except slap.
93
    opt_password=client_get_tty_password(NULL);
1 by brian
clean slate
94
  return(0);
95
}
96
97
98
928.1.6 by Eric Day
All utilities done except slap.
99
static int write_to_table(char *filename, drizzle_con_st *con)
1 by brian
clean slate
100
{
101
  char tablename[FN_REFLEN], hard_path[FN_REFLEN],
102
       sql_statement[FN_REFLEN*16+256], *end;
928.1.6 by Eric Day
All utilities done except slap.
103
  drizzle_result_st result;
104
  drizzle_return_t ret;
1 by brian
clean slate
105
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
106
  internal::fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
107
  if (not opt_local_file)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
108
    strcpy(hard_path,filename);
1 by brian
clean slate
109
  else
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
110
    internal::my_load_path(hard_path, filename, NULL); /* filename includes the path */
1 by brian
clean slate
111
112
  if (opt_delete)
113
  {
114
    if (verbose)
115
      fprintf(stdout, "Deleting the old data from table %s\n", tablename);
116
#ifdef HAVE_SNPRINTF
1366.1.13 by Siddharth Prakash Singh
more sprintf->snprintf
117
    snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
1 by brian
clean slate
118
#else
1366.1.13 by Siddharth Prakash Singh
more sprintf->snprintf
119
    snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
1 by brian
clean slate
120
#endif
928.1.6 by Eric Day
All utilities done except slap.
121
    if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
122
        ret != DRIZZLE_RETURN_OK)
1 by brian
clean slate
123
    {
928.1.6 by Eric Day
All utilities done except slap.
124
      db_error(con, &result, ret, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
125
      return(1);
1 by brian
clean slate
126
    }
928.1.6 by Eric Day
All utilities done except slap.
127
    drizzle_result_free(&result);
1 by brian
clean slate
128
  }
129
  if (verbose)
130
  {
131
    if (opt_local_file)
132
      fprintf(stdout, "Loading data from LOCAL file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
133
        hard_path, tablename);
1 by brian
clean slate
134
    else
135
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
136
        hard_path, tablename);
1 by brian
clean slate
137
  }
1366.1.14 by Siddharth Prakash Singh
bug fixing
138
  snprintf(sql_statement, sizeof(sql_statement), "LOAD DATA %s %s INFILE '%s'",
206.3.1 by Patrick Galbraith
Most everything working with client rename
139
    opt_low_priority ? "LOW_PRIORITY" : "",
140
    opt_local_file ? "LOCAL" : "", hard_path);
376 by Brian Aker
strend remove
141
  end= strchr(sql_statement, '\0');
279.2.5 by Monty Taylor
Removed DYNAMIC_STRING from drizzleimport.
142
  if (opt_replace)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
143
    end= strcpy(end, " REPLACE")+8;
923.2.2 by Monty Taylor
Changed some names that conflict with c++0x reserved names.
144
  if (ignore_unique)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
145
    end= strcpy(end, " IGNORE")+7;
146
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
147
  end+= sprintf(end, " INTO TABLE %s", tablename);
1 by brian
clean slate
148
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
149
  if (! fields_terminated.empty() || ! enclosed.empty() || ! opt_enclosed.empty() || ! escaped.empty())
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
150
      end= strcpy(end, " FIELDS")+7;
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
151
  end= add_load_option(end, (char *)fields_terminated.c_str(), " TERMINATED BY");
152
  end= add_load_option(end, (char *)enclosed.c_str(), " ENCLOSED BY");
153
  end= add_load_option(end, (char *)opt_enclosed.c_str(),
206.3.1 by Patrick Galbraith
Most everything working with client rename
154
           " OPTIONALLY ENCLOSED BY");
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
155
  end= add_load_option(end, (char *)escaped.c_str(), " ESCAPED BY");
156
  end= add_load_option(end, (char *)lines_terminated.c_str(), " LINES TERMINATED BY");
1 by brian
clean slate
157
  if (opt_ignore_lines >= 0)
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
158
  {
159
    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.
160
    ostringstream buffer;
161
    buffer << opt_ignore_lines;
162
    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
163
    end= strcpy(end, " LINES")+6;
164
  }
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
165
  if (! opt_columns.empty())
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
166
  {
167
    end= strcpy(end, " (")+2;
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
168
    end= strcpy(end, (char *)opt_columns.c_str()+opt_columns.length());
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
169
    end= strcpy(end, ")")+1;
170
  }
1 by brian
clean slate
171
  *end= '\0';
172
928.1.6 by Eric Day
All utilities done except slap.
173
  if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
174
      ret != DRIZZLE_RETURN_OK)
1 by brian
clean slate
175
  {
928.1.6 by Eric Day
All utilities done except slap.
176
    db_error(con, &result, ret, tablename);
142.1.2 by Patrick
All DBUG_x removed from client/
177
    return(1);
1 by brian
clean slate
178
  }
179
  if (!silent)
180
  {
928.1.6 by Eric Day
All utilities done except slap.
181
    if (strcmp(drizzle_result_info(&result), ""))
1 by brian
clean slate
182
    {
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
183
      fprintf(stdout, "%s.%s: %s\n", current_db.c_str(), tablename,
928.1.6 by Eric Day
All utilities done except slap.
184
        drizzle_result_info(&result));
1 by brian
clean slate
185
    }
186
  }
928.1.6 by Eric Day
All utilities done except slap.
187
  drizzle_result_free(&result);
142.1.2 by Patrick
All DBUG_x removed from client/
188
  return(0);
1 by brian
clean slate
189
}
190
191
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
192
static drizzle_con_st *db_connect(const string host, const string database,
193
                                  const string user, const string passwd)
1 by brian
clean slate
194
{
928.1.6 by Eric Day
All utilities done except slap.
195
  drizzle_st *drizzle;
196
  drizzle_con_st *con;
197
  drizzle_return_t ret;
198
1 by brian
clean slate
199
  if (verbose)
1745.2.1 by LinuxJedi
Remove the --mysql option and convert the --protocol option to do something similar.
200
    fprintf(stdout, "Connecting to %s, using protocol %s...\n", ! host.empty() ? host.c_str() : "localhost", opt_protocol.c_str());
928.1.6 by Eric Day
All utilities done except slap.
201
  if (!(drizzle= drizzle_create(NULL)))
202
    return 0;
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
203
  if (!(con= drizzle_con_add_tcp(drizzle,NULL,(char *)host.c_str(),opt_drizzle_port,(char *)user.c_str(),(char *)passwd.c_str(),
1745.2.1 by LinuxJedi
Remove the --mysql option and convert the --protocol option to do something similar.
204
                                 (char *)database.c_str(), use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL)))
928.1.6 by Eric Day
All utilities done except slap.
205
  {
206
    return 0;
207
  }
208
209
  if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
1 by brian
clean slate
210
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
211
    ignore_errors=0;    /* NO RETURN FROM db_error */
928.1.6 by Eric Day
All utilities done except slap.
212
    db_error(con, NULL, ret, NULL);
1 by brian
clean slate
213
  }
928.1.6 by Eric Day
All utilities done except slap.
214
1 by brian
clean slate
215
  if (verbose)
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
216
    fprintf(stdout, "Selecting database %s\n", database.c_str());
928.1.6 by Eric Day
All utilities done except slap.
217
218
  return con;
1 by brian
clean slate
219
}
220
221
222
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
223
static void db_disconnect(const string host, drizzle_con_st *con)
1 by brian
clean slate
224
{
225
  if (verbose)
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
226
    fprintf(stdout, "Disconnecting from %s\n", ! host.empty() ? host.c_str() : "localhost");
928.1.6 by Eric Day
All utilities done except slap.
227
  drizzle_free(drizzle_con_drizzle(con));
1 by brian
clean slate
228
}
229
230
231
928.1.6 by Eric Day
All utilities done except slap.
232
static void safe_exit(int error, drizzle_con_st *con)
1 by brian
clean slate
233
{
234
  if (ignore_errors)
235
    return;
928.1.6 by Eric Day
All utilities done except slap.
236
  if (con)
237
    drizzle_free(drizzle_con_drizzle(con));
1 by brian
clean slate
238
  exit(error);
239
}
240
241
242
928.1.6 by Eric Day
All utilities done except slap.
243
static void db_error(drizzle_con_st *con, drizzle_result_st *result,
244
                     drizzle_return_t ret, char *table)
245
{
246
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
247
  {
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
248
    fprintf(stdout, "Error: %d, %s%s%s",
249
            drizzle_result_error_code(result),
250
            drizzle_result_error(result),
251
            table ? ", when using table: " : "", table ? table : "");
928.1.6 by Eric Day
All utilities done except slap.
252
    drizzle_result_free(result);
253
  }
254
  else
255
  {
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
256
    fprintf(stdout, "Error: %d, %s%s%s", ret, drizzle_con_error(con),
257
            table ? ", when using table: " : "", table ? table : "");
928.1.6 by Eric Day
All utilities done except slap.
258
  }
259
260
  safe_exit(1, con);
1 by brian
clean slate
261
}
262
263
264
static char *add_load_option(char *ptr, const char *object,
206.3.1 by Patrick Galbraith
Most everything working with client rename
265
           const char *statement)
1 by brian
clean slate
266
{
267
  if (object)
268
  {
269
    /* Don't escape hex constants */
270
    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
271
      ptr+= sprintf(ptr, " %s %s", statement, object);
1 by brian
clean slate
272
    else
273
    {
274
      /* char constant; escape */
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
275
      ptr+= sprintf(ptr, " %s '", statement); 
895 by Brian Aker
Completion (?) of uint conversion.
276
      ptr= field_escape(ptr,object,(uint32_t) strlen(object));
1 by brian
clean slate
277
      *ptr++= '\'';
278
    }
279
  }
280
  return ptr;
281
}
282
283
/*
284
** Allow the user to specify field terminator strings like:
285
** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline)
286
** This is done by doubleing ' and add a end -\ if needed to avoid
287
** syntax errors from the SQL parser.
206.3.1 by Patrick Galbraith
Most everything working with client rename
288
*/
1 by brian
clean slate
289
893 by Brian Aker
First pass of stripping uint
290
static char *field_escape(char *to,const char *from,uint32_t length)
1 by brian
clean slate
291
{
292
  const char *end;
893 by Brian Aker
First pass of stripping uint
293
  uint32_t end_backslashes=0;
1 by brian
clean slate
294
295
  for (end= from+length; from != end; from++)
296
  {
297
    *to++= *from;
298
    if (*from == '\\')
299
      end_backslashes^=1;    /* find odd number of backslashes */
206.3.1 by Patrick Galbraith
Most everything working with client rename
300
    else
1 by brian
clean slate
301
    {
302
      if (*from == '\'' && !end_backslashes)
206.3.1 by Patrick Galbraith
Most everything working with client rename
303
  *to++= *from;      /* We want a dublicate of "'" for DRIZZLE */
1 by brian
clean slate
304
      end_backslashes=0;
305
    }
306
  }
307
  /* Add missing backslashes if user has specified odd number of backs.*/
308
  if (end_backslashes)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
309
    *to++= '\\';
1 by brian
clean slate
310
  return to;
311
}
312
632.1.12 by Monty Taylor
Fixed more sun studio warnings.
313
void * worker_thread(void *arg)
1 by brian
clean slate
314
{
315
  int error;
316
  char *raw_table_name= (char *)arg;
1707.1.23 by Brian Aker
Cleanup of import.
317
  drizzle_con_st *con;
1 by brian
clean slate
318
928.1.6 by Eric Day
All utilities done except slap.
319
  if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
320
  {
1707.1.23 by Brian Aker
Cleanup of import.
321
    return 0;
1 by brian
clean slate
322
  }
323
324
  /*
325
    We are not currently catching the error here.
326
  */
1707.1.23 by Brian Aker
Cleanup of import.
327
  if ((error= write_to_table(raw_table_name, con)))
328
  {
1 by brian
clean slate
329
    if (exitcode == 0)
1707.1.23 by Brian Aker
Cleanup of import.
330
    {
1 by brian
clean slate
331
      exitcode= error;
1707.1.23 by Brian Aker
Cleanup of import.
332
    }
333
  }
1 by brian
clean slate
334
928.1.6 by Eric Day
All utilities done except slap.
335
  if (con)
1707.1.23 by Brian Aker
Cleanup of import.
336
  {
928.1.6 by Eric Day
All utilities done except slap.
337
    db_disconnect(current_host, con);
1707.1.23 by Brian Aker
Cleanup of import.
338
  }
1 by brian
clean slate
339
340
  pthread_mutex_lock(&counter_mutex);
341
  counter--;
342
  pthread_cond_signal(&count_threshhold);
343
  pthread_mutex_unlock(&counter_mutex);
344
345
  return 0;
346
}
347
348
349
int main(int argc, char **argv)
350
{
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
351
try
352
{
1 by brian
clean slate
353
  int error=0;
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
354
355
  po::options_description commandline_options("Options used only in command line");
356
  commandline_options.add_options()
357
358
  ("debug,#", po::value<string>(),
359
  "Output debug log. Often this is 'd:t:o,filename'.")
360
  ("delete,d", po::value<bool>(&opt_delete)->default_value(false)->zero_tokens(),
361
  "First delete all rows from table.")
362
  ("help,?", "Displays this help and exits.")
363
  ("ignore,i", po::value<bool>(&ignore_unique)->default_value(false)->zero_tokens(),
364
  "If duplicate unique key was found, keep old row.")
365
  ("low-priority", po::value<bool>(&opt_low_priority)->default_value(false)->zero_tokens(),
366
  "Use LOW_PRIORITY when updating the table.")
367
  ("replace,r", po::value<bool>(&opt_replace)->default_value(false)->zero_tokens(),
368
  "If duplicate unique key was found, replace old row.")
369
  ("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
370
  "Print info about the various stages.")
371
  ("version,V", "Output version information and exit.")
372
  ;
373
374
  po::options_description import_options("Options specific to the drizzleimport");
375
  import_options.add_options()
376
  ("columns,C", po::value<string>(&opt_columns)->default_value(""),
377
  "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.")
378
  ("fields-terminated-by", po::value<string>(&fields_terminated)->default_value(""),
379
  "Fields in the textfile are terminated by ...")
380
  ("fields-enclosed-by", po::value<string>(&enclosed)->default_value(""),
381
  "Fields in the importfile are enclosed by ...")
382
  ("fields-optionally-enclosed-by", po::value<string>(&opt_enclosed)->default_value(""),
383
  "Fields in the i.file are opt. enclosed by ...")
384
  ("fields-escaped-by", po::value<string>(&escaped)->default_value(""),
385
  "Fields in the i.file are escaped by ...")
386
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
387
  "Continue even if we get an sql-error.")
388
  ("ignore-lines", po::value<int64_t>(&opt_ignore_lines)->default_value(0),
389
  "Ignore first n lines of data infile.")
390
  ("lines-terminated-by", po::value<string>(&lines_terminated)->default_value(""),
391
  "Lines in the i.file are terminated by ...")
392
  ("local,L", po::value<bool>(&opt_local_file)->default_value(false)->zero_tokens(),
393
  "Read all files through the client.")
394
  ("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
395
  "Be more silent.")
1707.1.23 by Brian Aker
Cleanup of import.
396
  ("use-threads", po::value<uint32_t>(&opt_use_threads)->default_value(4),
397
  "Load files in parallel. The argument is the number of threads to use for loading data (default is 4.")
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
398
  ;
399
400
  po::options_description client_options("Options specific to the client");
401
  client_options.add_options()
402
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
403
  "Connect to host.")
404
  ("password,P", po::value<string>(&password),
405
  "Password to use when connecting to server. If password is not given it's asked from the tty." )
406
  ("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
407
  "Port number to use for connection") 
1745.2.1 by LinuxJedi
Remove the --mysql option and convert the --protocol option to do something similar.
408
  ("protocol", po::value<string>(&opt_protocol)->default_value("mysql"),
409
  "The protocol of connection (mysql or drizzle).")
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
410
  ("user,u", po::value<string>(&current_user)->default_value(""),
411
  "User for login if not current user.")
412
  ;
413
414
  po::options_description long_options("Allowed Options");
415
  long_options.add(commandline_options).add(import_options).add(client_options);
416
417
  std::string system_config_dir_import(SYSCONFDIR); 
418
  system_config_dir_import.append("/drizzle/drizzleimport.cnf");
419
420
  std::string system_config_dir_client(SYSCONFDIR); 
421
  system_config_dir_client.append("/drizzle/client.cnf");
422
  
1671.2.1 by Vijay Samuel
Merge new user config file processing system.
423
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
424
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
425
  po::variables_map vm;
1671.2.1 by Vijay Samuel
Merge new user config file processing system.
426
1793.3.1 by Andrew Hutchings
Disable boost:po allow_guessing which was making some wrong assumptions
427
  // Disable allow_guessing
428
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
429
1633.5.2 by Vijay Samuel
Merge fix for password in client/
430
  po::store(po::command_line_parser(argc, argv).options(long_options).
1793.3.1 by Andrew Hutchings
Disable boost:po allow_guessing which was making some wrong assumptions
431
            style(style).extra_parser(parse_password_arg).run(), vm);
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
432
1671.2.1 by Vijay Samuel
Merge new user config file processing system.
433
  std::string user_config_dir_import(user_config_dir);
434
  user_config_dir_import.append("/drizzle/drizzleimport.cnf"); 
435
436
  std::string user_config_dir_client(user_config_dir);
437
  user_config_dir_client.append("/drizzle/client.cnf");
438
439
  ifstream user_import_ifs(user_config_dir_import.c_str());
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
440
  po::store(parse_config_file(user_import_ifs, import_options), vm);
1671.2.1 by Vijay Samuel
Merge new user config file processing system.
441
442
  ifstream user_client_ifs(user_config_dir_client.c_str());
443
  po::store(parse_config_file(user_client_ifs, client_options), vm);
444
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
445
  ifstream system_import_ifs(system_config_dir_import.c_str());
446
  store(parse_config_file(system_import_ifs, import_options), vm);
447
 
448
  ifstream system_client_ifs(system_config_dir_client.c_str());
449
  po::store(parse_config_file(system_client_ifs, client_options), vm);
450
451
  po::notify(vm);
1745.2.1 by LinuxJedi
Remove the --mysql option and convert the --protocol option to do something similar.
452
  if (vm.count("protocol"))
453
  {
454
    std::transform(opt_protocol.begin(), opt_protocol.end(),
455
      opt_protocol.begin(), ::tolower);
456
457
    if (not opt_protocol.compare("mysql"))
458
      use_drizzle_protocol=false;
459
    else if (not opt_protocol.compare("drizzle"))
460
      use_drizzle_protocol=true;
461
    else
462
    {
463
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
464
      exit(-1);
465
    }
466
  }
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
467
468
  if (vm.count("port"))
469
  {
470
    
471
    /* If the port number is > 65535 it is not a valid port
472
       This also helps with potential data loss casting unsigned long to a
473
       uint32_t. */
474
    if (opt_drizzle_port > 65535)
475
    {
476
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
477
      exit(EXIT_ARGUMENT_INVALID);
478
    }
479
  }
480
1633.5.2 by Vijay Samuel
Merge fix for password in client/
481
  if( vm.count("password") )
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
482
  {
483
    if (!opt_password.empty())
484
      opt_password.erase();
1633.5.2 by Vijay Samuel
Merge fix for password in client/
485
    if (password == PASSWORD_SENTINEL)
486
    {
487
      opt_password= "";
488
    }
489
    else
490
    {
491
      opt_password= password;
492
      tty_password= false;
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
493
    }
494
  }
495
  else
496
  {
497
      tty_password= true;
498
  }
499
1633.5.2 by Vijay Samuel
Merge fix for password in client/
500
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
501
  if (vm.count("version"))
502
  {
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
503
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
504
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
505
  }
506
  
507
  if (vm.count("help") || argc < 2)
508
  {
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
509
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
510
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
511
    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");
512
    printf("\
513
    Loads tables from text files in various formats.  The base name of the\n\
514
    text file must be the name of the table that should be used.\n\
515
    If one uses sockets to connect to the Drizzle server, the server will open and\n\
516
    read the text file directly. In other cases the client will open the text\n\
517
    file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
518
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
519
    printf("\nUsage: %s [OPTIONS] database textfile...", program_name);
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
520
    cout<<long_options;
521
    exit(0);
522
  }
523
524
525
  if (get_options())
526
  {
1 by brian
clean slate
527
    return(1);
528
  }
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
529
  
530
  current_db= (*argv)++;
531
  argc--;
1 by brian
clean slate
532
1707.1.23 by Brian Aker
Cleanup of import.
533
  if (opt_use_threads)
1 by brian
clean slate
534
  {
535
    pthread_t mainthread;            /* Thread descriptor */
536
    pthread_attr_t attr;          /* Thread attributes */
537
    pthread_attr_init(&attr);
538
    pthread_attr_setdetachstate(&attr,
539
                                PTHREAD_CREATE_DETACHED);
540
398.1.10 by Monty Taylor
Actually removed VOID() this time.
541
    pthread_mutex_init(&counter_mutex, NULL);
542
    pthread_cond_init(&count_threshhold, NULL);
1 by brian
clean slate
543
544
    for (counter= 0; *argv != NULL; argv++) /* Loop through tables */
545
    {
546
      pthread_mutex_lock(&counter_mutex);
547
      while (counter == opt_use_threads)
548
      {
549
        struct timespec abstime;
550
551
        set_timespec(abstime, 3);
552
        pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
553
      }
554
      /* Before exiting the lock we set ourselves up for the next thread */
555
      counter++;
556
      pthread_mutex_unlock(&counter_mutex);
557
      /* now create the thread */
206.3.1 by Patrick Galbraith
Most everything working with client rename
558
      if (pthread_create(&mainthread, &attr, worker_thread,
1 by brian
clean slate
559
                         (void *)*argv) != 0)
560
      {
561
        pthread_mutex_lock(&counter_mutex);
562
        counter--;
563
        pthread_mutex_unlock(&counter_mutex);
1707.1.24 by Brian Aker
Merge in small fixes around drizzleimport.
564
        fprintf(stderr,"%s: Could not create thread\n", program_name);
1 by brian
clean slate
565
      }
566
    }
567
568
    /*
569
      We loop until we know that all children have cleaned up.
570
    */
571
    pthread_mutex_lock(&counter_mutex);
572
    while (counter)
573
    {
574
      struct timespec abstime;
575
576
      set_timespec(abstime, 3);
577
      pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
578
    }
579
    pthread_mutex_unlock(&counter_mutex);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
580
    pthread_mutex_destroy(&counter_mutex);
581
    pthread_cond_destroy(&count_threshhold);
1 by brian
clean slate
582
    pthread_attr_destroy(&attr);
583
  }
584
  else
585
  {
1707.1.23 by Brian Aker
Cleanup of import.
586
    drizzle_con_st *con;
587
928.1.6 by Eric Day
All utilities done except slap.
588
    if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
1 by brian
clean slate
589
    {
971.6.11 by Eric Day
Removed purecov messages.
590
      return(1);
1 by brian
clean slate
591
    }
592
593
    for (; *argv != NULL; argv++)
928.1.6 by Eric Day
All utilities done except slap.
594
      if ((error= write_to_table(*argv, con)))
1 by brian
clean slate
595
        if (exitcode == 0)
596
          exitcode= error;
928.1.6 by Eric Day
All utilities done except slap.
597
    db_disconnect(current_host, con);
1 by brian
clean slate
598
  }
1593.1.2 by Vijay Samuel
Merge re factored commandline option and configuration file processing using boost::program_options.
599
  opt_password.empty();
600
}
601
  catch(exception &err)
602
  {
603
    cerr<<err.what()<<endl;
604
  }
1 by brian
clean slate
605
  return(exitcode);
606
}