~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleimport.cc

  • Committer: Monty Taylor
  • Date: 2009-04-25 20:45:19 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 1003.
  • Revision ID: mordred@inaugust.com-20090425204519-lgrl7mz2r66v0jby
Blackhole.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
   Copyright (C) 2008-2009 Sun Microsystems, Inc
 
1
/* Copyright (C) 2008 Drizzle Open Source Development Team
3
2
 
4
3
   This program is free software; you can redistribute it and/or modify
5
4
   it under the terms of the GNU General Public License as published by
29
28
 
30
29
#include "client_priv.h"
31
30
#include <string>
32
 
#include <sstream>
33
31
 
34
32
#include <pthread.h>
35
33
 
37
35
#include <drizzled/gettext.h>
38
36
 
39
37
using namespace std;
40
 
using namespace drizzled;
41
 
 
42
 
extern "C" void * worker_thread(void *arg);
43
 
 
44
 
int exitcode= 0;
45
38
 
46
39
/* Global Thread counter */
47
40
uint32_t counter;
56
49
 
57
50
static bool verbose= false, lock_tables= false, ignore_errors= false,
58
51
            opt_delete= false, opt_replace= false, silent= false,
59
 
            ignore_unique= false, opt_low_priority= false,
60
 
            tty_password= false, opt_mysql= false;
61
 
 
62
 
static uint32_t opt_use_threads= 0, opt_local_file= 0;
 
52
            ignore_unique= false, opt_compress= false, opt_low_priority= false,
 
53
            tty_password= false;
 
54
static bool debug_info_flag= false, debug_check_flag= false;
 
55
static uint32_t opt_use_threads= 0, opt_local_file= 0, my_end_arg= 0;
63
56
static char  *opt_password= NULL, *current_user= NULL,
64
57
    *current_host= NULL, *current_db= NULL, *fields_terminated= NULL,
65
58
    *lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
66
 
    *escaped= NULL, *opt_columns= NULL;
 
59
    *escaped= NULL, *opt_columns= NULL,
 
60
    *default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
67
61
static uint32_t opt_drizzle_port= 0;
 
62
static char * opt_drizzle_unix_port= 0;
68
63
static int64_t opt_ignore_lines= -1;
 
64
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
69
65
 
70
 
static struct option my_long_options[] =
 
66
static struct my_option my_long_options[] =
71
67
{
 
68
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
69
   "Set the default character set.", (char**) &default_charset,
 
70
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
72
71
  {"columns", 'c',
73
72
   "Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to LOAD DATA INFILE.",
74
73
   (char**) &opt_columns, (char**) &opt_columns, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
75
74
   0, 0, 0},
 
75
  {"compress", 'C', "Use compression in server/client protocol.",
 
76
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
77
   0, 0, 0},
76
78
  {"debug",'#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0,
77
79
   GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
80
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
 
81
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
82
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
83
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
84
   (char**) &debug_info_flag, (char**) &debug_info_flag,
 
85
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
78
86
  {"delete", 'd', "First delete all rows from table.", (char**) &opt_delete,
79
87
   (char**) &opt_delete, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
80
88
  {"fields-terminated-by", OPT_FTB,
112
120
  {"low-priority", OPT_LOW_PRIORITY,
113
121
   "Use LOW_PRIORITY when updating the table.", (char**) &opt_low_priority,
114
122
   (char**) &opt_low_priority, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
115
 
  {"mysql", 'm', N_("Use MySQL Protocol."),
116
 
   (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
117
 
   0, 0, 0},
118
123
  {"password", 'P',
119
124
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
120
125
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
128
133
   (char**) &opt_replace, (char**) &opt_replace, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
129
134
  {"silent", 's', "Be more silent.", (char**) &silent, (char**) &silent, 0,
130
135
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
136
  {"socket", 'S', "Socket file to use for connection.",
 
137
   (char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
 
138
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
131
139
  {"use-threads", OPT_USE_THREADS,
132
140
   "Load files in parallel. The argument is the number "
133
141
   "of threads to use for loading data.",
134
142
   (char**) &opt_use_threads, (char**) &opt_use_threads, 0,
135
143
   GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
144
#ifndef DONT_ALLOW_USER_CHANGE
136
145
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
137
146
   (char**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
147
#endif
138
148
  {"verbose", 'v', "Print info about the various stages.", (char**) &verbose,
139
149
   (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
140
150
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
147
157
 
148
158
static void print_version(void)
149
159
{
150
 
  printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n" ,internal::my_progname,
151
 
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
 
160
  printf("%s  Ver %s Distrib %s, for %s (%s)\n" ,my_progname,
 
161
    IMPORT_VERSION, drizzle_version(),SYSTEM_TYPE,MACHINE_TYPE);
152
162
}
153
163
 
154
164
 
164
174
read the text file directly. In other cases the client will open the text\n\
165
175
file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
166
176
 
167
 
  printf("\nUsage: %s [OPTIONS] database textfile...",internal::my_progname);
168
 
  internal::print_defaults("drizzle",load_default_groups);
 
177
  printf("\nUsage: %s [OPTIONS] database textfile...",my_progname);
 
178
  print_defaults("drizzle",load_default_groups);
169
179
  my_print_help(my_long_options);
170
180
  my_print_variables(my_long_options);
171
181
}
172
182
 
173
 
static int get_one_option(int optid, const struct option *, char *argument)
 
183
extern "C"
 
184
bool get_one_option(int optid, const struct my_option *, char *argument)
174
185
{
175
186
  char *endchar= NULL;
176
187
  uint64_t temp_drizzle_port= 0;
182
193
    if (strlen(endchar) != 0)
183
194
    {
184
195
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
185
 
      return EXIT_ARGUMENT_INVALID;
 
196
      exit(1);
186
197
    }
187
198
    /* If the port number is > 65535 it is not a valid port
188
199
       This also helps with potential data loss casting unsigned long to a
190
201
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
191
202
    {
192
203
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
193
 
      return EXIT_ARGUMENT_INVALID;
 
204
      exit(1);
194
205
    }
195
206
    else
196
207
    {
208
219
      {
209
220
        fprintf(stderr, "Memory allocation error while copying password. "
210
221
                        "Aborting.\n");
211
 
        return EXIT_OUT_OF_MEMORY;
 
222
        exit(ENOMEM);
212
223
      }
213
224
      while (*argument)
214
225
      {
243
254
 
244
255
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
245
256
    exit(ho_error);
 
257
  if (debug_info_flag)
 
258
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
259
  if (debug_check_flag)
 
260
    my_end_arg= MY_CHECK_ERROR;
246
261
 
247
262
  if (enclosed && opt_enclosed)
248
263
  {
254
269
    fprintf(stderr, "You can't use --ignore_unique (-i) and --replace (-r) at the same time.\n");
255
270
    return(1);
256
271
  }
 
272
  if (strcmp(default_charset, charset_info->csname) &&
 
273
      !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY)))
 
274
    exit(1);
257
275
  if (*argc < 2)
258
276
  {
259
277
    usage();
275
293
  drizzle_result_st result;
276
294
  drizzle_return_t ret;
277
295
 
278
 
  internal::fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
 
296
  fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
279
297
  if (!opt_local_file)
280
298
    strcpy(hard_path,filename);
281
299
  else
282
 
    internal::my_load_path(hard_path, filename, NULL); /* filename includes the path */
 
300
    my_load_path(hard_path, filename, NULL); /* filename includes the path */
283
301
 
284
302
  if (opt_delete)
285
303
  {
286
304
    if (verbose)
287
305
      fprintf(stdout, "Deleting the old data from table %s\n", tablename);
288
306
#ifdef HAVE_SNPRINTF
289
 
    snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
 
307
    snprintf(sql_statement, FN_REFLEN*16+256, "DELETE FROM %s", tablename);
290
308
#else
291
 
    snprintf(sql_statement, sizeof(sql_statement), "DELETE FROM %s", tablename);
 
309
    sprintf(sql_statement, "DELETE FROM %s", tablename);
292
310
#endif
293
311
    if (drizzle_query_str(con, &result, sql_statement, &ret) == NULL ||
294
312
        ret != DRIZZLE_RETURN_OK)
307
325
      fprintf(stdout, "Loading data from SERVER file: %s into %s\n",
308
326
        hard_path, tablename);
309
327
  }
310
 
  snprintf(sql_statement, sizeof(sql_statement), "LOAD DATA %s %s INFILE '%s'",
 
328
  sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'",
311
329
    opt_low_priority ? "LOW_PRIORITY" : "",
312
330
    opt_local_file ? "LOCAL" : "", hard_path);
313
331
  end= strchr(sql_statement, '\0');
374
392
  query.append("LOCK TABLES ");
375
393
  for (i=0 ; i < tablecount ; i++)
376
394
  {
377
 
    internal::fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
 
395
    fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
378
396
    query.append(tablename);
379
397
    query.append(" WRITE,");
380
398
  }
402
420
  if (!(drizzle= drizzle_create(NULL)))
403
421
    return 0;
404
422
  if (!(con= drizzle_con_add_tcp(drizzle,NULL,host,opt_drizzle_port,user,passwd,
405
 
                                 database, opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE)))
 
423
                                 database, DRIZZLE_CON_NONE)))
406
424
  {
407
425
    return 0;
408
426
  }
511
529
  return to;
512
530
}
513
531
 
 
532
int exitcode= 0;
 
533
 
 
534
extern "C"
514
535
void * worker_thread(void *arg)
515
536
{
516
537
  int error;
549
570
  counter--;
550
571
  pthread_cond_signal(&count_threshhold);
551
572
  pthread_mutex_unlock(&counter_mutex);
552
 
  internal::my_thread_end();
 
573
  my_thread_end();
553
574
 
554
575
  return 0;
555
576
}
561
582
  char **argv_to_free;
562
583
  MY_INIT(argv[0]);
563
584
 
564
 
  internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
 
585
  load_defaults("drizzle",load_default_groups,&argc,&argv);
565
586
  /* argv is changed in the program */
566
587
  argv_to_free= argv;
567
588
  if (get_options(&argc, &argv))
568
589
  {
569
 
    internal::free_defaults(argv_to_free);
 
590
    free_defaults(argv_to_free);
570
591
    return(1);
571
592
  }
572
593
 
603
624
        counter--;
604
625
        pthread_mutex_unlock(&counter_mutex);
605
626
        fprintf(stderr,"%s: Could not create thread\n",
606
 
                internal::my_progname);
 
627
                my_progname);
607
628
      }
608
629
    }
609
630
 
631
652
    drizzle_return_t ret;
632
653
    if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
633
654
    {
634
 
      internal::free_defaults(argv_to_free);
635
 
      return(1);
 
655
      free_defaults(argv_to_free);
 
656
      return(1); /* purecov: deadcode */
636
657
    }
637
658
 
638
659
    if (drizzle_query_str(con, &result,
656
677
    db_disconnect(current_host, con);
657
678
  }
658
679
  free(opt_password);
659
 
  internal::free_defaults(argv_to_free);
660
 
  internal::my_end();
 
680
  free_defaults(argv_to_free);
 
681
  my_end(my_end_arg);
661
682
  return(exitcode);
662
683
}