18
18
#define CHECK_VERSION "2.5.0"
20
#include "client_priv.h"
22
#include "client_priv.h"
23
23
#include <mystrings/m_ctype.h>
25
template class std::vector<std::string>;
25
/* Added this for string translation. */
26
#include <drizzled/gettext.h>
27
29
using namespace std;
31
template class vector<string>;
31
36
#define EX_MYSQLERR 2
33
static DRIZZLE drizzle_connection, *sock = 0;
34
static bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
35
opt_compress = 0, opt_databases = 0, opt_fast = 0,
36
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
37
opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
38
tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0,
39
opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0,
41
static uint verbose = 0, opt_mysql_port=0;
38
static drizzle_st drizzle;
39
static drizzle_con_st dcon;
40
static bool opt_alldbs= false, opt_check_only_changed= false,
41
opt_extended= false, opt_databases= false,
42
opt_fast= false, opt_medium_check= false, opt_quick= false,
43
opt_all_in_1= false, opt_silent= false, opt_auto_repair= false,
44
ignore_errors= false, tty_password= false, opt_frm= false,
45
debug_info_flag= false, debug_check_flag= false,
46
opt_fix_table_names= false, opt_fix_db_names= false,
47
opt_upgrade= false, opt_write_binlog= true;
48
static uint32_t verbose= 0;
49
static uint32_t opt_drizzle_port= 0;
42
50
static int my_end_arg;
43
static char * opt_mysql_unix_port = 0;
44
static char *opt_password = 0, *current_user = 0,
45
*default_charset = (char *)DRIZZLE_DEFAULT_CHARSET_NAME,
47
static int first_error = 0;
51
static char * opt_drizzle_unix_port= NULL;
52
static char *opt_password= NULL, *current_user= NULL,
53
*default_charset= (char *)DRIZZLE_DEFAULT_CHARSET_NAME,
55
static int first_error= 0;
48
56
vector<string> tables4repair;
49
static uint opt_protocol=0;
50
static const CHARSET_INFO *charset_info= &my_charset_latin1;
57
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
52
59
enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
67
74
"If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
68
75
(char**) &opt_auto_repair, (char**) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
70
{"character-sets-dir", OPT_CHARSETS_DIR,
71
"Directory where character sets are.", (char**) &charsets_dir,
72
(char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
73
77
{"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
75
79
{"check-only-changed", 'C',
78
82
{"check-upgrade", 'g',
79
83
"Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.",
80
84
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
81
{"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
82
(char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
85
86
"To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
86
87
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG,
123
124
1, 0, 0, 0, 0, 0},
124
125
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
127
128
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
128
129
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
129
{"port", 'P', "Port number to use for connection or 0 for default to, in "
130
"order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
130
{"port", 'p', "Port number to use for connection or 0 for default to, in "
131
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
131
132
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
132
(char**) &opt_mysql_port,
133
(char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
133
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
135
134
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
136
135
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
144
143
{"silent", 's', "Print only error messages.", (char**) &opt_silent,
145
144
(char**) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
146
145
{"socket", 'S', "Socket file to use for connection.",
147
(char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
146
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
148
147
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
149
148
{"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
150
149
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
175
174
static int process_all_tables_in_db(char *database);
176
175
static int process_one_db(char *database);
177
176
static int use_db(char *database);
178
static int handle_request_for_tables(const char *tables, uint length);
177
static int handle_request_for_tables(const char *tables, uint32_t length);
179
178
static int dbConnect(char *host, char *user,char *passwd);
180
179
static void dbDisconnect(char *host);
181
static void DBerror(DRIZZLE *drizzle, const char *when);
180
static void DBerror(drizzle_con_st *con, const char *when);
182
181
static void safe_exit(int error);
183
static void print_result(void);
184
static uint fixed_name_length(const char *name);
182
static void print_result(drizzle_result_st *result);
183
static uint32_t fixed_name_length(const char *name);
185
184
static char *fix_table_name(char *dest, const char *src);
186
185
int what_to_do = 0;
188
187
static void print_version(void)
190
189
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
191
drizzle_get_client_info(), SYSTEM_TYPE, MACHINE_TYPE);
190
drizzle_version(), SYSTEM_TYPE, MACHINE_TYPE);
192
191
} /* print_version */
194
193
static void usage(void)
213
212
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
215
214
printf("OR %s [OPTIONS] --all-databases\n", my_progname);
216
print_defaults("my", load_default_groups);
215
print_defaults("drizzle", load_default_groups);
217
216
my_print_help(my_long_options);
218
217
my_print_variables(my_long_options);
222
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
221
bool get_one_option(int optid, const struct my_option *, char *argument)
224
uint64_t temp_drizzle_port= 0;
227
228
what_to_do = DO_ANALYZE;
254
255
default_charset= (char*) "utf8";
258
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
259
/* if there is an alpha character this is not a valid port */
260
if (strlen(endchar) != 0)
262
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
265
/* If the port number is > 65535 it is not a valid port
266
This also helps with potential data loss casting unsigned long to a
268
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
270
fprintf(stderr, _("Value supplied for port is not valid.\n"));
275
opt_drizzle_port= (uint32_t) temp_drizzle_port;
259
char *start = argument;
260
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
261
opt_password = my_strdup(argument, MYF(MY_FAE));
262
while (*argument) *argument++= 'x'; /* Destroy argument */
281
char *start= argument;
284
opt_password = strdup(argument);
285
if (opt_password == NULL)
287
fprintf(stderr, "Memory allocation error while copying password. "
293
/* Overwriting password with 'x' */
264
start[1] = 0; /* Cut length of argument */
298
/* Cut length of argument */
353
386
static int process_all_databases()
356
DRIZZLE_RES *tableres;
389
drizzle_result_st result;
390
drizzle_return_t ret;
359
if (drizzle_query(sock, "SHOW DATABASES") ||
360
!(tableres = drizzle_store_result(sock)))
393
if (drizzle_query_str(&dcon, &result, "SHOW DATABASES", &ret) == NULL ||
394
ret != DRIZZLE_RETURN_OK ||
395
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
362
my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
363
MYF(0), drizzle_error(sock));
397
if (ret == DRIZZLE_RETURN_ERROR_CODE)
399
fprintf(stderr, "Error: Couldn't execute 'SHOW DATABASES': %s",
400
drizzle_result_error(&result));
401
drizzle_result_free(&result);
405
fprintf(stderr, "Error: Couldn't execute 'SHOW DATABASES': %s",
406
drizzle_con_error(&dcon));
366
while ((row = drizzle_fetch_row(tableres)))
411
while ((row = drizzle_row_next(&result)))
368
if (process_one_db(row[0]))
413
if (process_one_db((char *)row[0]))
416
drizzle_result_free(&result);
373
419
/* process_all_databases */
403
449
tot_length+= fixed_name_length(*(table_names + i)) + 2;
405
451
if (!(table_names_comma_sep = (char *)
406
my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
452
malloc((sizeof(char) * tot_length) + 4)))
409
455
for (end = table_names_comma_sep + 1; tables > 0;
410
tables--, table_names++)
456
tables--, table_names++)
412
458
end= fix_table_name(end, *table_names);
416
462
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
417
my_free(table_names_comma_sep, MYF(0));
463
free(table_names_comma_sep);
420
466
for (; tables > 0; tables--, table_names++)
465
511
static int process_all_tables_in_db(char *database)
513
drizzle_result_st result;
515
drizzle_return_t ret;
516
uint32_t num_columns;
471
518
if (use_db(database))
473
if (drizzle_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
474
!((res= drizzle_store_result(sock))))
520
if (drizzle_query_str(&dcon, &result, "SHOW /*!50002 FULL*/ TABLES",
522
ret != DRIZZLE_RETURN_OK ||
523
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
525
if (ret == DRIZZLE_RETURN_ERROR_CODE)
526
drizzle_result_free(&result);
477
num_columns= drizzle_num_fields(res);
530
num_columns= drizzle_result_column_count(&result);
479
532
if (opt_all_in_1)
487
540
char *tables, *end;
490
while ((row = drizzle_fetch_row(res)))
491
tot_length+= fixed_name_length(row[0]) + 2;
492
drizzle_data_seek(res, 0);
494
if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
541
uint32_t tot_length = 0;
543
while ((row = drizzle_row_next(&result)))
544
tot_length+= fixed_name_length((char *)row[0]) + 2;
545
drizzle_row_seek(&result, 0);
547
if (!(tables=(char *) malloc(sizeof(char)*tot_length+4)))
496
drizzle_free_result(res);
549
drizzle_result_free(&result);
499
for (end = tables + 1; (row = drizzle_fetch_row(res)) ;)
552
for (end = tables + 1; (row = drizzle_row_next(&result)) ;)
501
if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
554
if ((num_columns == 2) && (strcmp((char *)row[1], "VIEW") == 0))
504
end= fix_table_name(end, row[0]);
557
end= fix_table_name(end, (char *)row[0]);
509
562
handle_request_for_tables(tables + 1, tot_length - 1);
510
my_free(tables, MYF(0));
514
while ((row = drizzle_fetch_row(res)))
567
while ((row = drizzle_row_next(&result)))
516
569
/* Skip views if we don't perform renaming. */
517
if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
570
if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp((char *)row[1], "VIEW") == 0))
520
handle_request_for_tables(row[0], fixed_name_length(row[0]));
573
handle_request_for_tables((char *)row[0],
574
fixed_name_length((char *)row[0]));
523
drizzle_free_result(res);
577
drizzle_result_free(&result);
525
579
} /* process_all_tables_in_db */
529
583
static int fix_table_storage_name(const char *name)
531
char qbuf[100 + NAME_LEN*4];
585
char qbuf[100 + DRIZZLE_MAX_COLUMN_NAME_SIZE*4];
586
drizzle_result_st result;
587
drizzle_return_t ret;
533
589
if (strncmp(name, "#mysql50#", 9))
535
591
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
536
if (drizzle_query(sock, qbuf))
592
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
593
ret != DRIZZLE_RETURN_OK)
538
595
fprintf(stderr, "Failed to %s\n", qbuf);
539
fprintf(stderr, "Error: %s\n", drizzle_error(sock));
596
if (ret == DRIZZLE_RETURN_ERROR_CODE)
598
fprintf(stderr, "Error: %s\n", drizzle_result_error(&result));
599
drizzle_result_free(&result);
602
fprintf(stderr, "Error: %s\n", drizzle_con_error(&dcon));
606
drizzle_result_free(&result);
543
608
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
547
612
static int fix_database_storage_name(const char *name)
549
char qbuf[100 + NAME_LEN*4];
614
char qbuf[100 + DRIZZLE_MAX_COLUMN_NAME_SIZE*4];
615
drizzle_result_st result;
616
drizzle_return_t ret;
551
618
if (strncmp(name, "#mysql50#", 9))
553
620
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
554
if (drizzle_query(sock, qbuf))
621
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
622
ret != DRIZZLE_RETURN_OK)
556
624
fprintf(stderr, "Failed to %s\n", qbuf);
557
fprintf(stderr, "Error: %s\n", drizzle_error(sock));
625
if (ret == DRIZZLE_RETURN_ERROR_CODE)
627
fprintf(stderr, "Error: %s\n", drizzle_result_error(&result));
628
drizzle_result_free(&result);
631
fprintf(stderr, "Error: %s\n", drizzle_con_error(&dcon));
635
drizzle_result_free(&result);
561
637
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
582
658
static int use_db(char *database)
584
if (drizzle_get_server_version(sock) >= 50003 &&
585
!my_strcasecmp(&my_charset_latin1, database, "information_schema"))
660
drizzle_result_st result;
661
drizzle_return_t ret;
662
if (drizzle_con_server_version_number(&dcon) >= 50003 &&
663
!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
587
if (drizzle_select_db(sock, database))
665
if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
666
ret != DRIZZLE_RETURN_OK)
589
DBerror(sock, "when selecting the database");
668
if (ret == DRIZZLE_RETURN_ERROR_CODE)
670
fprintf(stderr,"Got error: %s when selecting the database",
671
drizzle_result_error(&result));
672
safe_exit(EX_MYSQLERR);
673
drizzle_result_free(&result);
676
DBerror(&dcon, "when selecting the database");
679
drizzle_result_free(&result);
596
static int handle_request_for_tables(const char *tables, uint length)
684
static int handle_request_for_tables(const char *tables, uint32_t length)
598
686
char *query, *end, options[100], message[100];
599
uint query_length= 0;
687
uint32_t query_length= 0;
600
688
const char *op = 0;
689
drizzle_result_st result;
690
drizzle_return_t ret;
604
694
switch (what_to_do) {
607
if (opt_quick) end = stpcpy(end, " QUICK");
608
if (opt_fast) end = stpcpy(end, " FAST");
609
if (opt_medium_check) end = stpcpy(end, " MEDIUM"); /* Default */
610
if (opt_extended) end = stpcpy(end, " EXTENDED");
611
if (opt_check_only_changed) end = stpcpy(end, " CHANGED");
612
if (opt_upgrade) end = stpcpy(end, " FOR UPGRADE");
697
if (opt_quick) end = strcpy(end, " QUICK")+6;
698
if (opt_fast) end = strcpy(end, " FAST")+5;
699
if (opt_medium_check) end = strcpy(end, " MEDIUM")+7; /* Default */
700
if (opt_extended) end = strcpy(end, " EXTENDED")+9;
701
if (opt_check_only_changed) end = strcpy(end, " CHANGED")+8;
702
if (opt_upgrade) end = strcpy(end, " FOR UPGRADE")+12;
615
705
op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG";
616
if (opt_quick) end = stpcpy(end, " QUICK");
617
if (opt_extended) end = stpcpy(end, " EXTENDED");
618
if (opt_frm) end = stpcpy(end, " USE_FRM");
706
if (opt_quick) end = strcpy(end, " QUICK")+6;
707
if (opt_extended) end = strcpy(end, " EXTENDED")+9;
708
if (opt_frm) end = strcpy(end, " USE_FRM")+8;
621
711
op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
641
ptr= stpcpy(stpcpy(query, op), " TABLE ");
731
ptr= strcpy(query, op)+strlen(op);
732
ptr= strcpy(ptr, " TABLE ")+7;
642
733
ptr= fix_table_name(ptr, tables);
643
ptr= strxmov(ptr, " ", options, NullS);
644
query_length= (uint) (ptr - query);
734
ptr+= sprintf(ptr," %s",options);
735
query_length= (uint32_t) (ptr - query);
646
if (drizzle_real_query(sock, query, query_length))
737
if (drizzle_query(&dcon, &result, query, query_length, &ret) == NULL ||
738
ret != DRIZZLE_RETURN_OK ||
739
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
648
741
sprintf(message, "when executing '%s TABLE ... %s'", op, options);
649
DBerror(sock, message);
742
if (ret == DRIZZLE_RETURN_ERROR_CODE)
744
fprintf(stderr,"Got error: %s %s",
745
drizzle_result_error(&result), message);
746
safe_exit(EX_MYSQLERR);
747
drizzle_result_free(&result);
750
DBerror(&dcon, message);
653
my_free(query, MYF(0));
753
print_result(&result);
754
drizzle_result_free(&result);
658
static void print_result()
760
static void print_result(drizzle_result_st *result)
662
char prev[NAME_LEN*2+2];
763
char prev[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+2];
664
765
bool found_error=0;
666
res = drizzle_use_result(sock);
669
for (i = 0; (row = drizzle_fetch_row(res)); i++)
768
for (i = 0; (row = drizzle_row_next(result)); i++)
671
int changed = strcmp(prev, row[0]);
672
bool status = !strcmp(row[2], "status");
770
int changed = strcmp(prev, (char *)row[0]);
771
bool status = !strcmp((char *)row[2], "status");
681
780
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
781
strcmp((char *)row[3],"OK"))
683
782
tables4repair.push_back(string(prev));
688
787
if (status && changed)
689
788
printf("%-50s %s", row[0], row[3]);
690
789
else if (!status && changed)
692
791
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
693
if (strcmp(row[2],"note"))
792
if (strcmp((char *)row[2],"note"))
697
printf("%-9s: %s", row[2], row[3]);
698
stpcpy(prev, row[0]);
796
printf("%-9s: %s", (char *)row[2], (char *)row[3]);
797
strcpy(prev, (char *)row[0]);
701
800
/* add the last table to be repaired to the list */
702
801
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
703
802
tables4repair.push_back(string(prev));
704
drizzle_free_result(res);
713
811
fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
715
drizzle_create(&drizzle_connection);
717
drizzle_options(&drizzle_connection, DRIZZLE_OPT_COMPRESS, NullS);
719
drizzle_options(&drizzle_connection,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
720
if (!(sock = drizzle_connect(&drizzle_connection, host, user, passwd,
721
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
813
drizzle_create(&drizzle);
814
drizzle_con_create(&drizzle, &dcon);
815
drizzle_con_set_tcp(&dcon, host, opt_drizzle_port);
816
drizzle_con_set_auth(&dcon, user, passwd);
817
if (drizzle_con_connect(&dcon) != DRIZZLE_RETURN_OK)
723
DBerror(&drizzle_connection, "when trying to connect");
819
DBerror(&dcon, "when trying to connect");
726
drizzle_connection.reconnect= 1;
728
823
} /* dbConnect */
734
829
fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
830
drizzle_free(&drizzle);
736
831
} /* dbDisconnect */
739
static void DBerror(DRIZZLE *drizzle, const char *when)
834
static void DBerror(drizzle_con_st *con, const char *when)
741
my_printf_error(0,"Got error: %d: %s %s", MYF(0),
742
drizzle_errno(drizzle), drizzle_error(drizzle), when);
836
fprintf(stderr,"Got error: %s %s", drizzle_con_error(con), when);
743
837
safe_exit(EX_MYSQLERR);