~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzleimport.cc

  • Committer: Brian Aker
  • Date: 2010-07-15 23:18:11 UTC
  • mto: This revision was merged to the branch mainline in revision 1661.
  • Revision ID: brian@gaz-20100715231811-c5erivy1nvwf6bii
Merge in move identifier work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* 
2
2
  Copyright (C) 2010 Vijay Samuel
3
 
  Copyright (C) 2010 Brian Aker
4
3
  Copyright (C) 2000-2006 MySQL AB
5
4
  Copyright (C) 2008-2009 Sun Microsystems, Inc
6
5
 
15
14
 
16
15
  You should have received a copy of the GNU General Public License
17
16
  along with this program; if not, write to the Free Software
18
 
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
17
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19
18
 
20
 
#define IMPORT_VERSION "4.0"
 
19
/*
 
20
**     drizzleimport.c  - Imports all given files
 
21
**          into a table(s).
 
22
**
 
23
**         *************************
 
24
**         *         *
 
25
**         * AUTHOR: Monty & Jani  *
 
26
**         * DATE:   June 24, 1997 *
 
27
**         *         *
 
28
**         *************************
 
29
*/
 
30
#define IMPORT_VERSION "3.7"
21
31
 
22
32
#include "client_priv.h"
23
33
#include <string>
39
49
 
40
50
int exitcode= 0;
41
51
 
42
 
const char *program_name= "drizzlesimport";
43
 
 
44
52
/* Global Thread counter */
45
53
uint32_t counter;
46
54
pthread_mutex_t counter_mutex;
52
60
static char *add_load_option(char *ptr,const char *object,
53
61
           const char *statement);
54
62
 
55
 
static bool verbose= false, ignore_errors= false,
 
63
static bool verbose= false, lock_tables= false, ignore_errors= false,
56
64
            opt_delete= false, opt_replace= false, silent= false,
57
65
            ignore_unique= false, opt_low_priority= false,
58
 
            use_drizzle_protocol= false, opt_local_file;
 
66
            opt_mysql= false, opt_local_file;
59
67
 
60
 
static uint32_t opt_use_threads;
 
68
static uint32_t opt_use_threads= 0;
61
69
static uint32_t opt_drizzle_port= 0;
62
70
static int64_t opt_ignore_lines= -1;
63
71
 
71
79
  opt_password,
72
80
  enclosed,  
73
81
  current_host,
74
 
  fields_terminated,
75
 
  opt_protocol;
 
82
  fields_terminated;
76
83
 
77
84
 
78
85
static int get_options(void)
104
111
  drizzle_return_t ret;
105
112
 
106
113
  internal::fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */
107
 
  if (not opt_local_file)
 
114
  if (!opt_local_file)
108
115
    strcpy(hard_path,filename);
109
116
  else
110
117
    internal::my_load_path(hard_path, filename, NULL); /* filename includes the path */
189
196
}
190
197
 
191
198
 
 
199
static void lock_table(drizzle_con_st *con, int tablecount, char **raw_tablename)
 
200
{
 
201
  string query;
 
202
  int i;
 
203
  char tablename[FN_REFLEN];
 
204
  drizzle_result_st result;
 
205
  drizzle_return_t ret;
 
206
 
 
207
  if (verbose)
 
208
    fprintf(stdout, "Locking tables for write\n");
 
209
  query.append("LOCK TABLES ");
 
210
  for (i=0 ; i < tablecount ; i++)
 
211
  {
 
212
    internal::fn_format(tablename, raw_tablename[i], "", "", 1 | 2);
 
213
    query.append(tablename);
 
214
    query.append(" WRITE,");
 
215
  }
 
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);
 
225
}
 
226
 
 
227
 
192
228
static drizzle_con_st *db_connect(const string host, const string database,
193
229
                                  const string user, const string passwd)
194
230
{
197
233
  drizzle_return_t ret;
198
234
 
199
235
  if (verbose)
200
 
    fprintf(stdout, "Connecting to %s, using protocol %s...\n", ! host.empty() ? host.c_str() : "localhost", opt_protocol.c_str());
 
236
    fprintf(stdout, "Connecting to %s\n", ! host.empty() ? host.c_str() : "localhost");
201
237
  if (!(drizzle= drizzle_create(NULL)))
202
238
    return 0;
203
239
  if (!(con= drizzle_con_add_tcp(drizzle,NULL,(char *)host.c_str(),opt_drizzle_port,(char *)user.c_str(),(char *)passwd.c_str(),
204
 
                                 (char *)database.c_str(), use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL)))
 
240
                                 (char *)database.c_str(), opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE)))
205
241
  {
206
242
    return 0;
207
243
  }
245
281
{
246
282
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
247
283
  {
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 : "");
 
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 : "");
252
288
    drizzle_result_free(result);
253
289
  }
254
290
  else
255
291
  {
256
 
    fprintf(stdout, "Error: %d, %s%s%s", ret, drizzle_con_error(con),
257
 
            table ? ", when using table: " : "", table ? table : "");
 
292
    my_printf_error(0,"Error: %d, %s%s%s", MYF(0), ret, drizzle_con_error(con),
 
293
                    table ? ", when using table: " : "", table ? table : "");
258
294
  }
259
295
 
260
296
  safe_exit(1, con);
314
350
{
315
351
  int error;
316
352
  char *raw_table_name= (char *)arg;
317
 
  drizzle_con_st *con;
 
353
  drizzle_con_st *con= NULL;
 
354
  drizzle_result_st result;
 
355
  drizzle_return_t ret;
318
356
 
319
357
  if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
320
358
  {
321
 
    return 0;
 
359
    goto error;
 
360
  }
 
361
 
 
362
  if (drizzle_query_str(con, &result,
 
363
                        "/*!40101 set @@character_set_database=binary */;",
 
364
                        &ret) == NULL ||
 
365
      ret != DRIZZLE_RETURN_OK)
 
366
  {
 
367
    db_error(con, &result, ret, NULL);
 
368
    /* We shall countinue here, if --force was given */
 
369
    goto error;
322
370
  }
323
371
 
324
372
  /*
325
373
    We are not currently catching the error here.
326
374
  */
327
 
  if ((error= write_to_table(raw_table_name, con)))
328
 
  {
 
375
  if((error= write_to_table(raw_table_name, con)))
329
376
    if (exitcode == 0)
330
 
    {
331
377
      exitcode= error;
332
 
    }
333
 
  }
334
378
 
 
379
error:
335
380
  if (con)
336
 
  {
337
381
    db_disconnect(current_host, con);
338
 
  }
339
382
 
340
383
  pthread_mutex_lock(&counter_mutex);
341
384
  counter--;
342
385
  pthread_cond_signal(&count_threshhold);
343
386
  pthread_mutex_unlock(&counter_mutex);
 
387
  internal::my_thread_end();
344
388
 
345
389
  return 0;
346
390
}
362
406
  ("help,?", "Displays this help and exits.")
363
407
  ("ignore,i", po::value<bool>(&ignore_unique)->default_value(false)->zero_tokens(),
364
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).")
365
411
  ("low-priority", po::value<bool>(&opt_low_priority)->default_value(false)->zero_tokens(),
366
412
  "Use LOW_PRIORITY when updating the table.")
367
413
  ("replace,r", po::value<bool>(&opt_replace)->default_value(false)->zero_tokens(),
393
439
  "Read all files through the client.")
394
440
  ("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
395
441
  "Be more silent.")
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.")
 
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.")
398
444
  ;
399
445
 
400
446
  po::options_description client_options("Options specific to the client");
401
447
  client_options.add_options()
402
448
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
403
449
  "Connect to host.")
 
450
  ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
 
451
  N_("Use MySQL Protocol."))
404
452
  ("password,P", po::value<string>(&password),
405
453
  "Password to use when connecting to server. If password is not given it's asked from the tty." )
406
454
  ("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
407
455
  "Port number to use for connection") 
408
 
  ("protocol", po::value<string>(&opt_protocol)->default_value("mysql"),
409
 
  "The protocol of connection (mysql or drizzle).")
 
456
  ("protocol", po::value<string>(),
 
457
  "The protocol of connection (tcp,socket,pipe,memory).")
410
458
  ("user,u", po::value<string>(&current_user)->default_value(""),
411
459
  "User for login if not current user.")
412
460
  ;
420
468
  std::string system_config_dir_client(SYSCONFDIR); 
421
469
  system_config_dir_client.append("/drizzle/client.cnf");
422
470
  
423
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
424
 
 
425
 
  if (user_config_dir.compare(0, 2, "~/") == 0)
426
 
  {
427
 
    char *homedir;
428
 
    homedir= getenv("HOME");
429
 
    if (homedir != NULL)
430
 
      user_config_dir.replace(0, 1, homedir);
431
 
  }
432
 
 
433
471
  po::variables_map vm;
434
 
 
435
 
  // Disable allow_guessing
436
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
437
 
 
438
472
  po::store(po::command_line_parser(argc, argv).options(long_options).
439
 
            style(style).extra_parser(parse_password_arg).run(), vm);
440
 
 
441
 
  std::string user_config_dir_import(user_config_dir);
442
 
  user_config_dir_import.append("/drizzle/drizzleimport.cnf"); 
443
 
 
444
 
  std::string user_config_dir_client(user_config_dir);
445
 
  user_config_dir_client.append("/drizzle/client.cnf");
446
 
 
447
 
  ifstream user_import_ifs(user_config_dir_import.c_str());
 
473
            extra_parser(parse_password_arg).run(), vm);
 
474
 
 
475
  ifstream user_import_ifs("~/.drizzle/drizzleimport.cnf");
448
476
  po::store(parse_config_file(user_import_ifs, import_options), vm);
449
 
 
450
 
  ifstream user_client_ifs(user_config_dir_client.c_str());
451
 
  po::store(parse_config_file(user_client_ifs, client_options), vm);
452
 
 
 
477
 
453
478
  ifstream system_import_ifs(system_config_dir_import.c_str());
454
479
  store(parse_config_file(system_import_ifs, import_options), vm);
 
480
 
 
481
  ifstream user_client_ifs("~/.drizzle/client.cnf");
 
482
  po::store(parse_config_file(user_client_ifs, client_options), vm);
455
483
 
456
484
  ifstream system_client_ifs(system_config_dir_client.c_str());
457
485
  po::store(parse_config_file(system_client_ifs, client_options), vm);
458
486
 
459
487
  po::notify(vm);
460
 
  if (vm.count("protocol"))
461
 
  {
462
 
    std::transform(opt_protocol.begin(), opt_protocol.end(),
463
 
      opt_protocol.begin(), ::tolower);
464
 
 
465
 
    if (not opt_protocol.compare("mysql"))
466
 
      use_drizzle_protocol=false;
467
 
    else if (not opt_protocol.compare("drizzle"))
468
 
      use_drizzle_protocol=true;
469
 
    else
470
 
    {
471
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
472
 
      exit(-1);
473
 
    }
474
 
  }
475
488
 
476
489
  if (vm.count("port"))
477
490
  {
508
521
 
509
522
  if (vm.count("version"))
510
523
  {
511
 
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
 
524
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n" ,internal::my_progname,
512
525
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
513
526
  }
514
527
  
515
528
  if (vm.count("help") || argc < 2)
516
529
  {
517
 
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n", program_name,
 
530
    printf("%s  Ver %s Distrib %s, for %s-%s (%s)\n" ,internal::my_progname,
518
531
    IMPORT_VERSION, drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
519
532
    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");
520
533
    printf("\
524
537
    read the text file directly. In other cases the client will open the text\n\
525
538
    file. The SQL command 'LOAD DATA INFILE' is used to import the rows.\n");
526
539
 
527
 
    printf("\nUsage: %s [OPTIONS] database textfile...", program_name);
 
540
    printf("\nUsage: %s [OPTIONS] database textfile...",internal::my_progname);
528
541
    cout<<long_options;
529
542
    exit(0);
530
543
  }
538
551
  current_db= (*argv)++;
539
552
  argc--;
540
553
 
541
 
  if (opt_use_threads)
 
554
#ifdef HAVE_LIBPTHREAD
 
555
  if (opt_use_threads && !lock_tables)
542
556
  {
543
557
    pthread_t mainthread;            /* Thread descriptor */
544
558
    pthread_attr_t attr;          /* Thread attributes */
569
583
        pthread_mutex_lock(&counter_mutex);
570
584
        counter--;
571
585
        pthread_mutex_unlock(&counter_mutex);
572
 
        fprintf(stderr,"%s: Could not create thread\n", program_name);
 
586
        fprintf(stderr,"%s: Could not create thread\n",
 
587
                internal::my_progname);
573
588
      }
574
589
    }
575
590
 
590
605
    pthread_attr_destroy(&attr);
591
606
  }
592
607
  else
 
608
#endif
593
609
  {
594
 
    drizzle_con_st *con;
595
 
 
 
610
    drizzle_con_st *con= 0;
 
611
    drizzle_result_st result;
 
612
    drizzle_return_t ret;
596
613
    if (!(con= db_connect(current_host,current_db,current_user,opt_password)))
597
614
    {
598
615
      return(1);
599
616
    }
600
617
 
 
618
    if (drizzle_query_str(con, &result,
 
619
                          "/*!40101 set @@character_set_database=binary */;",
 
620
                          &ret) == NULL ||
 
621
        ret != DRIZZLE_RETURN_OK)
 
622
    {
 
623
      db_error(con, &result, ret, NULL);
 
624
      /* We shall countinue here, if --force was given */
 
625
      return(1);
 
626
    }
 
627
 
 
628
    drizzle_result_free(&result);
 
629
 
 
630
    if (lock_tables)
 
631
      lock_table(con, argc, argv);
601
632
    for (; *argv != NULL; argv++)
602
633
      if ((error= write_to_table(*argv, con)))
603
634
        if (exitcode == 0)