~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzlecheck.c

Merged build changes from Antony.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB
 
1
/* Copyright (C) 2008 Drizzle development team
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
 
16
/* By Jani Tolonen, 2001-04-20, MySQL, DRIZZLE Development Team */
17
17
 
18
18
#define CHECK_VERSION "2.5.0"
19
19
 
20
20
#include "client_priv.h"
21
 
#include <m_ctype.h>
22
 
#include <drizzle_version.h>
23
 
#include <mysqld_error.h>
 
21
#include <mystrings/m_ctype.h>
24
22
 
25
23
/* Exit codes */
26
24
 
27
25
#define EX_USAGE 1
28
26
#define EX_MYSQLERR 2
29
27
 
30
 
static MYSQL mysql_connection, *sock = 0;
 
28
static DRIZZLE drizzle_connection, *sock = 0;
31
29
static bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
32
30
               opt_compress = 0, opt_databases = 0, opt_fast = 0,
33
31
               opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
38
36
static uint verbose = 0, opt_mysql_port=0;
39
37
static int my_end_arg;
40
38
static char * opt_mysql_unix_port = 0;
41
 
static char *opt_password = 0, *current_user = 0, 
42
 
            *default_charset = (char *)MYSQL_DEFAULT_CHARSET_NAME,
43
 
            *current_host = 0;
 
39
static char *opt_password = 0, *current_user = 0,
 
40
      *default_charset = (char *)MYSQL_DEFAULT_CHARSET_NAME,
 
41
      *current_host = 0;
44
42
static int first_error = 0;
45
43
DYNAMIC_ARRAY tables4repair;
46
44
static uint opt_protocol=0;
132
130
   (char**) &opt_mysql_port,
133
131
   (char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
134
132
   0},
135
 
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
133
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
136
134
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
137
135
  {"quick", 'q',
138
136
   "If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.",
178
176
static int handle_request_for_tables(char *tables, uint length);
179
177
static int dbConnect(char *host, char *user,char *passwd);
180
178
static void dbDisconnect(char *host);
181
 
static void DBerror(MYSQL *mysql, const char *when);
 
179
static void DBerror(DRIZZLE *drizzle, const char *when);
182
180
static void safe_exit(int error);
183
181
static void print_result(void);
184
182
static uint fixed_name_length(const char *name);
185
183
static char *fix_table_name(char *dest, char *src);
186
184
int what_to_do = 0;
187
185
 
188
 
#include <help_start.h>
189
 
 
190
186
static void print_version(void)
191
187
{
192
188
  printf("%s  Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
193
189
   MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
194
190
} /* print_version */
195
191
 
196
 
 
197
192
static void usage(void)
198
193
{
199
194
  print_version();
203
198
  puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
204
199
  puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
205
200
  puts("used at the same time. Not all options are supported by all storage engines.");
206
 
  puts("Please consult the MySQL manual for latest information about the");
 
201
  puts("Please consult the Drizzle manual for latest information about the");
207
202
  puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
208
203
  puts("means that the last option will be used, if several was specified.\n");
209
204
  puts("The option -c will be used by default, if none was specified. You");
214
209
  puts("mysqloptimize: The default option will be -o\n");
215
210
  printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
216
211
  printf("OR     %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
217
 
         my_progname);
 
212
   my_progname);
218
213
  printf("OR     %s [OPTIONS] --all-databases\n", my_progname);
219
214
  print_defaults("my", load_default_groups);
220
215
  my_print_help(my_long_options);
221
216
  my_print_variables(my_long_options);
222
217
} /* usage */
223
218
 
224
 
#include <help_end.h>
225
 
 
226
219
static bool
227
220
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
228
 
               char *argument)
 
221
         char *argument)
229
222
{
230
223
  switch(optid) {
231
224
  case 'a':
264
257
      char *start = argument;
265
258
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
266
259
      opt_password = my_strdup(argument, MYF(MY_FAE));
267
 
      while (*argument) *argument++= 'x';               /* Destroy argument */
 
260
      while (*argument) *argument++= 'x';    /* Destroy argument */
268
261
      if (*start)
269
 
        start[1] = 0;                             /* Cut length of argument */
 
262
  start[1] = 0;                             /* Cut length of argument */
270
263
      tty_password= 0;
271
264
    }
272
265
    else
286
279
    verbose++;
287
280
    break;
288
281
  case 'V': print_version(); exit(0);
289
 
  case OPT_MYSQL_PROTOCOL:
 
282
  case OPT_DRIZZLE_PROTOCOL:
290
283
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
291
284
                                    opt->name);
292
285
    break;
328
321
 
329
322
  /* TODO: This variable is not yet used */
330
323
  if (strcmp(default_charset, charset_info->csname) &&
331
 
      !(charset_info= get_charset_by_csname(default_charset, 
332
 
                                            MY_CS_PRIMARY, MYF(MY_WME))))
 
324
      !(charset_info= get_charset_by_csname(default_charset,
 
325
                MY_CS_PRIMARY, MYF(MY_WME))))
333
326
      exit(1);
334
327
  if (*argc > 0 && opt_alldbs)
335
328
  {
336
329
    printf("You should give only options, no arguments at all, with option\n");
337
330
    printf("--all-databases. Please see %s --help for more information.\n",
338
 
           my_progname);
 
331
     my_progname);
339
332
    return 1;
340
333
  }
341
334
  if (*argc < 1 && !opt_alldbs)
342
335
  {
343
336
    printf("You forgot to give the arguments! Please see %s --help\n",
344
 
           my_progname);
 
337
     my_progname);
345
338
    printf("for more information.\n");
346
339
    return 1;
347
340
  }
357
350
 
358
351
static int process_all_databases()
359
352
{
360
 
  MYSQL_ROW row;
361
 
  MYSQL_RES *tableres;
 
353
  DRIZZLE_ROW row;
 
354
  DRIZZLE_RES *tableres;
362
355
  int result = 0;
363
356
 
364
 
  if (mysql_query(sock, "SHOW DATABASES") ||
365
 
      !(tableres = mysql_store_result(sock)))
 
357
  if (drizzle_query(sock, "SHOW DATABASES") ||
 
358
      !(tableres = drizzle_store_result(sock)))
366
359
  {
367
360
    my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
368
 
                    MYF(0), mysql_error(sock));
 
361
        MYF(0), drizzle_error(sock));
369
362
    return 1;
370
363
  }
371
 
  while ((row = mysql_fetch_row(tableres)))
 
364
  while ((row = drizzle_fetch_row(tableres)))
372
365
  {
373
366
    if (process_one_db(row[0]))
374
367
      result = 1;
396
389
    return 1;
397
390
  if (opt_all_in_1)
398
391
  {
399
 
    /* 
 
392
    /*
400
393
      We need table list in form `a`, `b`, `c`
401
394
      that's why we need 2 more chars added to to each table name
402
395
      space is for more readable output in logs and in case of error
403
 
    */    
 
396
    */   
404
397
    char *table_names_comma_sep, *end;
405
398
    int i, tot_length = 0;
406
399
 
408
401
      tot_length+= fixed_name_length(*(table_names + i)) + 2;
409
402
 
410
403
    if (!(table_names_comma_sep = (char *)
411
 
          my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
 
404
    my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
412
405
      return 1;
413
406
 
414
407
    for (end = table_names_comma_sep + 1; tables > 0;
415
 
         tables--, table_names++)
 
408
   tables--, table_names++)
416
409
    {
417
410
      end= fix_table_name(end, *table_names);
418
411
      *end++= ',';
432
425
{
433
426
  const char *p;
434
427
  uint extra_length= 2;  /* count the first/last backticks */
435
 
  
 
428
 
436
429
  for (p= name; *p; p++)
437
430
  {
438
431
    if (*p == '`')
469
462
 
470
463
static int process_all_tables_in_db(char *database)
471
464
{
472
 
  MYSQL_RES *res;
473
 
  MYSQL_ROW row;
 
465
  DRIZZLE_RES *res;
 
466
  DRIZZLE_ROW row;
474
467
  uint num_columns;
475
468
 
476
469
  if (use_db(database))
477
470
    return 1;
478
 
  if (mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
479
 
        !((res= mysql_store_result(sock))))
 
471
  if (drizzle_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
 
472
  !((res= drizzle_store_result(sock))))
480
473
    return 1;
481
474
 
482
 
  num_columns= mysql_num_fields(res);
 
475
  num_columns= drizzle_num_fields(res);
483
476
 
484
477
  if (opt_all_in_1)
485
478
  {
492
485
    char *tables, *end;
493
486
    uint tot_length = 0;
494
487
 
495
 
    while ((row = mysql_fetch_row(res)))
 
488
    while ((row = drizzle_fetch_row(res)))
496
489
      tot_length+= fixed_name_length(row[0]) + 2;
497
 
    mysql_data_seek(res, 0);
 
490
    drizzle_data_seek(res, 0);
498
491
 
499
492
    if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
500
493
    {
501
 
      mysql_free_result(res);
 
494
      drizzle_free_result(res);
502
495
      return 1;
503
496
    }
504
 
    for (end = tables + 1; (row = mysql_fetch_row(res)) ;)
 
497
    for (end = tables + 1; (row = drizzle_fetch_row(res)) ;)
505
498
    {
506
499
      if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
507
500
        continue;
516
509
  }
517
510
  else
518
511
  {
519
 
    while ((row = mysql_fetch_row(res)))
 
512
    while ((row = drizzle_fetch_row(res)))
520
513
    {
521
514
      /* Skip views if we don't perform renaming. */
522
515
      if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
525
518
      handle_request_for_tables(row[0], fixed_name_length(row[0]));
526
519
    }
527
520
  }
528
 
  mysql_free_result(res);
 
521
  drizzle_free_result(res);
529
522
  return 0;
530
523
} /* process_all_tables_in_db */
531
524
 
538
531
  if (strncmp(name, "#mysql50#", 9))
539
532
    return 1;
540
533
  sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
541
 
  if (mysql_query(sock, qbuf))
 
534
  if (drizzle_query(sock, qbuf))
542
535
  {
543
536
    fprintf(stderr, "Failed to %s\n", qbuf);
544
 
    fprintf(stderr, "Error: %s\n", mysql_error(sock));
 
537
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
545
538
    rc= 1;
546
539
  }
547
540
  if (verbose)
556
549
  if (strncmp(name, "#mysql50#", 9))
557
550
    return 1;
558
551
  sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
559
 
  if (mysql_query(sock, qbuf))
 
552
  if (drizzle_query(sock, qbuf))
560
553
  {
561
554
    fprintf(stderr, "Failed to %s\n", qbuf);
562
 
    fprintf(stderr, "Error: %s\n", mysql_error(sock));
 
555
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
563
556
    rc= 1;
564
557
  }
565
558
  if (verbose)
586
579
 
587
580
static int use_db(char *database)
588
581
{
589
 
  if (mysql_get_server_version(sock) >= 50003 &&
 
582
  if (drizzle_get_server_version(sock) >= 50003 &&
590
583
      !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
591
584
    return 1;
592
 
  if (mysql_select_db(sock, database))
 
585
  if (drizzle_select_db(sock, database))
593
586
  {
594
587
    DBerror(sock, "when selecting the database");
595
588
    return 1;
648
641
    ptr= strxmov(ptr, " ", options, NullS);
649
642
    query_length= (uint) (ptr - query);
650
643
  }
651
 
  if (mysql_real_query(sock, query, query_length))
 
644
  if (drizzle_real_query(sock, query, query_length))
652
645
  {
653
646
    sprintf(message, "when executing '%s TABLE ... %s'", op, options);
654
647
    DBerror(sock, message);
662
655
 
663
656
static void print_result()
664
657
{
665
 
  MYSQL_RES *res;
666
 
  MYSQL_ROW row;
 
658
  DRIZZLE_RES *res;
 
659
  DRIZZLE_ROW row;
667
660
  char prev[NAME_LEN*2+2];
668
661
  uint i;
669
662
  bool found_error=0;
670
663
 
671
 
  res = mysql_use_result(sock);
 
664
  res = drizzle_use_result(sock);
672
665
 
673
666
  prev[0] = '\0';
674
 
  for (i = 0; (row = mysql_fetch_row(res)); i++)
 
667
  for (i = 0; (row = drizzle_fetch_row(res)); i++)
675
668
  {
676
669
    int changed = strcmp(prev, row[0]);
677
670
    bool status = !strcmp(row[2], "status");
684
677
        list
685
678
      */
686
679
      if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
687
 
          strcmp(row[3],"OK"))
688
 
        insert_dynamic(&tables4repair, (uchar*) prev);
 
680
    strcmp(row[3],"OK"))
 
681
  insert_dynamic(&tables4repair, (uchar*) prev);
689
682
      found_error=0;
690
683
      if (opt_silent)
691
 
        continue;
 
684
  continue;
692
685
    }
693
686
    if (status && changed)
694
687
      printf("%-50s %s", row[0], row[3]);
696
689
    {
697
690
      printf("%s\n%-9s: %s", row[0], row[2], row[3]);
698
691
      if (strcmp(row[2],"note"))
699
 
        found_error=1;
 
692
  found_error=1;
700
693
    }
701
694
    else
702
695
      printf("%-9s: %s", row[2], row[3]);
706
699
  /* add the last table to be repaired to the list */
707
700
  if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
708
701
    insert_dynamic(&tables4repair, (uchar*) prev);
709
 
  mysql_free_result(res);
 
702
  drizzle_free_result(res);
710
703
}
711
704
 
712
705
 
717
710
  {
718
711
    fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
719
712
  }
720
 
  mysql_init(&mysql_connection);
 
713
  drizzle_create(&drizzle_connection);
721
714
  if (opt_compress)
722
 
    mysql_options(&mysql_connection, MYSQL_OPT_COMPRESS, NullS);
 
715
    drizzle_options(&drizzle_connection, DRIZZLE_OPT_COMPRESS, NullS);
723
716
  if (opt_protocol)
724
 
    mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
725
 
  if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
 
717
    drizzle_options(&drizzle_connection,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
 
718
  if (!(sock = drizzle_connect(&drizzle_connection, host, user, passwd,
726
719
         NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
727
720
  {
728
 
    DBerror(&mysql_connection, "when trying to connect");
 
721
    DBerror(&drizzle_connection, "when trying to connect");
729
722
    return 1;
730
723
  }
731
 
  mysql_connection.reconnect= 1;
 
724
  drizzle_connection.reconnect= 1;
732
725
  return 0;
733
726
} /* dbConnect */
734
727
 
737
730
{
738
731
  if (verbose)
739
732
    fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
740
 
  mysql_close(sock);
 
733
  drizzle_close(sock);
741
734
} /* dbDisconnect */
742
735
 
743
736
 
744
 
static void DBerror(MYSQL *mysql, const char *when)
 
737
static void DBerror(DRIZZLE *drizzle, const char *when)
745
738
{
746
739
  my_printf_error(0,"Got error: %d: %s %s", MYF(0),
747
 
                  mysql_errno(mysql), mysql_error(mysql), when);
 
740
      drizzle_errno(drizzle), drizzle_error(drizzle), when);
748
741
  safe_exit(EX_MYSQLERR);
749
742
  return;
750
743
} /* DBerror */
757
750
  if (ignore_errors)
758
751
    return;
759
752
  if (sock)
760
 
    mysql_close(sock);
 
753
    drizzle_close(sock);
761
754
  exit(error);
762
755
}
763
756