~drizzle-trunk/drizzle/development

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