1
/* Copyright (C) 2008 Drizzle development team
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* By Jani Tolonen, 2001-04-20, MySQL, MYSQL Development Team */
18
#define CHECK_VERSION "2.5.0"
20
#include "client_priv.h"
23
#include <mystrings/m_ctype.h>
25
/* Added this for string translation. */
26
#include <drizzled/gettext.h>
31
template class vector<string>;
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;
50
static int my_end_arg;
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;
56
vector<string> tables4repair;
57
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
59
enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
61
static struct my_option my_long_options[] =
63
{"all-databases", 'A',
64
"Check all the databases. This will be same as --databases with all databases selected.",
65
(char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
67
{"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
70
"Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.",
71
(char**) &opt_all_in_1, (char**) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
73
{"auto-repair", OPT_AUTO_REPAIR,
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.",
75
(char**) &opt_auto_repair, (char**) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
77
{"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
79
{"check-only-changed", 'C',
80
"Check only tables that have changed since last check or haven't been closed properly.",
81
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
82
{"check-upgrade", 'g',
83
"Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.",
84
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
86
"To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
87
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG,
89
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
90
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
91
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
92
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
93
(char**) &debug_info_flag, (char**) &debug_info_flag,
94
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
95
{"default-character-set", OPT_DEFAULT_CHARSET,
96
"Set the default character set.", (char**) &default_charset,
97
(char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
98
{"fast",'F', "Check only tables that haven't been closed properly.",
99
(char**) &opt_fast, (char**) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
101
{"fix-db-names", OPT_FIX_DB_NAMES, "Fix database names.",
102
(char**) &opt_fix_db_names, (char**) &opt_fix_db_names,
103
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
104
{"fix-table-names", OPT_FIX_TABLE_NAMES, "Fix table names.",
105
(char**) &opt_fix_table_names, (char**) &opt_fix_table_names,
106
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
107
{"force", 'f', "Continue even if we get an sql-error.",
108
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
111
"If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.",
112
(char**) &opt_extended, (char**) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
114
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
115
NO_ARG, 0, 0, 0, 0, 0, 0},
116
{"host",'h', "Connect to host.", (char**) ¤t_host,
117
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
118
{"medium-check", 'm',
119
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
120
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
121
{"write-binlog", OPT_WRITE_BINLOG,
122
"Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog when commands should not be sent to replication slaves.",
123
(char**) &opt_write_binlog, (char**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
125
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
128
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
129
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
130
{"port", 'p', "Port number to use for connection or 0 for default to, in "
131
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
132
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
133
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
134
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
135
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
137
"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.",
138
(char**) &opt_quick, (char**) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
141
"Can fix almost anything except unique keys that aren't unique.",
142
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
143
{"silent", 's', "Print only error messages.", (char**) &opt_silent,
144
(char**) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
145
{"socket", 'S', "Socket file to use for connection.",
146
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
147
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
148
{"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
149
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
151
"When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.",
152
(char**) &opt_frm, (char**) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
154
#ifndef DONT_ALLOW_USER_CHANGE
155
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
156
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
158
{"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
159
NO_ARG, 0, 0, 0, 0, 0, 0},
160
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
161
NO_ARG, 0, 0, 0, 0, 0, 0},
162
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
165
static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
168
static void print_version(void);
169
static void usage(void);
170
static int get_options(int *argc, char ***argv);
171
static int process_all_databases(void);
172
static int process_databases(char **db_names);
173
static int process_selected_tables(char *db, char **table_names, int tables);
174
static int process_all_tables_in_db(char *database);
175
static int process_one_db(char *database);
176
static int use_db(char *database);
177
static int handle_request_for_tables(const char *tables, uint32_t length);
178
static int dbConnect(char *host, char *user,char *passwd);
179
static void dbDisconnect(char *host);
180
static void DBerror(drizzle_con_st *con, const char *when);
181
static void safe_exit(int error);
182
static void print_result(drizzle_result_st *result);
183
static uint32_t fixed_name_length(const char *name);
184
static char *fix_table_name(char *dest, const char *src);
187
static void print_version(void)
189
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
190
drizzle_version(), SYSTEM_TYPE, MACHINE_TYPE);
191
} /* print_version */
193
static void usage(void)
196
puts("By Jani Tolonen, 2001-04-20, MySQL Development Team\n");
197
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
198
puts("and you are welcome to modify and redistribute it under the GPL license.\n");
199
puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
200
puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
201
puts("used at the same time. Not all options are supported by all storage engines.");
202
puts("Please consult the Drizzle manual for latest information about the");
203
puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
204
puts("means that the last option will be used, if several was specified.\n");
205
puts("The option -c will be used by default, if none was specified. You");
206
puts("can change the default behavior by making a symbolic link, or");
207
puts("copying this file somewhere with another name, the alternatives are:");
208
puts("mysqlrepair: The default option will be -r");
209
puts("mysqlanalyze: The default option will be -a");
210
puts("mysqloptimize: The default option will be -o\n");
211
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
212
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
214
printf("OR %s [OPTIONS] --all-databases\n", my_progname);
215
print_defaults("drizzle", load_default_groups);
216
my_print_help(my_long_options);
217
my_print_variables(my_long_options);
221
bool get_one_option(int optid, const struct my_option *, char *argument)
224
uint64_t temp_drizzle_port= 0;
228
what_to_do = DO_ANALYZE;
231
what_to_do = DO_CHECK;
234
what_to_do = DO_CHECK;
235
opt_check_only_changed = 1;
237
case 'I': /* Fall through */
242
what_to_do = DO_CHECK;
243
opt_medium_check = 1;
246
what_to_do = DO_OPTIMIZE;
248
case OPT_FIX_DB_NAMES:
249
what_to_do= DO_UPGRADE;
250
default_charset= (char*) "utf8";
253
case OPT_FIX_TABLE_NAMES:
254
what_to_do= DO_UPGRADE;
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;
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' */
298
/* Cut length of argument */
307
what_to_do = DO_REPAIR;
310
what_to_do= DO_CHECK;
319
case 'V': print_version(); exit(0);
320
case OPT_DRIZZLE_PROTOCOL:
327
static int get_options(int *argc, char ***argv)
337
load_defaults("drizzle", load_default_groups, argc, argv);
339
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
344
int pnlen = strlen(my_progname);
346
if (pnlen < 6) /* name too short */
347
what_to_do = DO_CHECK;
348
else if (!strcmp("repair", my_progname + pnlen - 6))
349
what_to_do = DO_REPAIR;
350
else if (!strcmp("analyze", my_progname + pnlen - 7))
351
what_to_do = DO_ANALYZE;
352
else if (!strcmp("optimize", my_progname + pnlen - 8))
353
what_to_do = DO_OPTIMIZE;
355
what_to_do = DO_CHECK;
358
/* TODO: This variable is not yet used */
359
if (strcmp(default_charset, charset_info->csname) &&
360
!(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY)))
362
if (*argc > 0 && opt_alldbs)
364
printf("You should give only options, no arguments at all, with option\n");
365
printf("--all-databases. Please see %s --help for more information.\n",
369
if (*argc < 1 && !opt_alldbs)
371
printf("You forgot to give the arguments! Please see %s --help\n",
373
printf("for more information.\n");
377
opt_password = client_get_tty_password(NULL);
379
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
380
if (debug_check_flag)
381
my_end_arg= MY_CHECK_ERROR;
386
static int process_all_databases()
389
drizzle_result_st result;
390
drizzle_return_t ret;
393
if (drizzle_query_str(&dcon, &result, "SHOW DATABASES", &ret) == NULL ||
394
ret != DRIZZLE_RETURN_OK ||
395
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
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));
411
while ((row = drizzle_row_next(&result)))
413
if (process_one_db((char *)row[0]))
416
drizzle_result_free(&result);
419
/* process_all_databases */
422
static int process_databases(char **db_names)
425
for ( ; *db_names ; db_names++)
427
if (process_one_db(*db_names))
431
} /* process_databases */
434
static int process_selected_tables(char *db, char **table_names, int tables)
441
We need table list in form `a`, `b`, `c`
442
that's why we need 2 more chars added to to each table name
443
space is for more readable output in logs and in case of error
445
char *table_names_comma_sep, *end;
446
int i, tot_length = 0;
448
for (i = 0; i < tables; i++)
449
tot_length+= fixed_name_length(*(table_names + i)) + 2;
451
if (!(table_names_comma_sep = (char *)
452
malloc((sizeof(char) * tot_length) + 4)))
455
for (end = table_names_comma_sep + 1; tables > 0;
456
tables--, table_names++)
458
end= fix_table_name(end, *table_names);
462
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
463
free(table_names_comma_sep);
466
for (; tables > 0; tables--, table_names++)
467
handle_request_for_tables(*table_names, fixed_name_length(*table_names));
469
} /* process_selected_tables */
472
static uint32_t fixed_name_length(const char *name)
475
uint32_t extra_length= 2; /* count the first/last backticks */
477
for (p= name; *p; p++)
484
return (p - name) + extra_length;
488
static char *fix_table_name(char *dest, const char *src)
494
case '.': /* add backticks around '.' */
499
case '`': /* escape backtick character */
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;
518
if (use_db(database))
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);
530
num_columns= drizzle_result_column_count(&result);
535
We need table list in form `a`, `b`, `c`
536
that's why we need 2 more chars added to to each table name
537
space is for more readable output in logs and in case of error
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)))
549
drizzle_result_free(&result);
552
for (end = tables + 1; (row = drizzle_row_next(&result)) ;)
554
if ((num_columns == 2) && (strcmp((char *)row[1], "VIEW") == 0))
557
end= fix_table_name(end, (char *)row[0]);
562
handle_request_for_tables(tables + 1, tot_length - 1);
567
while ((row = drizzle_row_next(&result)))
569
/* Skip views if we don't perform renaming. */
570
if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp((char *)row[1], "VIEW") == 0))
573
handle_request_for_tables((char *)row[0],
574
fixed_name_length((char *)row[0]));
577
drizzle_result_free(&result);
579
} /* process_all_tables_in_db */
583
static int fix_table_storage_name(const char *name)
585
char qbuf[100 + DRIZZLE_MAX_COLUMN_NAME_SIZE*4];
586
drizzle_result_st result;
587
drizzle_return_t ret;
589
if (strncmp(name, "#mysql50#", 9))
591
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
592
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
593
ret != DRIZZLE_RETURN_OK)
595
fprintf(stderr, "Failed to %s\n", qbuf);
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);
608
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
612
static int fix_database_storage_name(const char *name)
614
char qbuf[100 + DRIZZLE_MAX_COLUMN_NAME_SIZE*4];
615
drizzle_result_st result;
616
drizzle_return_t ret;
618
if (strncmp(name, "#mysql50#", 9))
620
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
621
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
622
ret != DRIZZLE_RETURN_OK)
624
fprintf(stderr, "Failed to %s\n", qbuf);
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);
637
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
641
static int process_one_db(char *database)
643
if (what_to_do == DO_UPGRADE)
646
if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
648
rc= fix_database_storage_name(database);
651
if (rc || !opt_fix_table_names)
654
return process_all_tables_in_db(database);
658
static int use_db(char *database)
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"))
665
if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
666
ret != DRIZZLE_RETURN_OK)
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);
684
static int handle_request_for_tables(const char *tables, uint32_t length)
686
char *query, *end, options[100], message[100];
687
uint32_t query_length= 0;
689
drizzle_result_st result;
690
drizzle_return_t ret;
694
switch (what_to_do) {
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;
705
op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG";
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;
711
op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
714
op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
717
return fix_table_storage_name(tables);
720
if (!(query =(char *) malloc((sizeof(char)*(length+110)))))
724
/* No backticks here as we added them before */
725
query_length= sprintf(query, "%s TABLE %s %s", op, tables, options);
731
ptr= strcpy(query, op)+strlen(op);
732
ptr= strcpy(ptr, " TABLE ")+7;
733
ptr= fix_table_name(ptr, tables);
734
ptr+= sprintf(ptr," %s",options);
735
query_length= (uint32_t) (ptr - query);
737
if (drizzle_query(&dcon, &result, query, query_length, &ret) == NULL ||
738
ret != DRIZZLE_RETURN_OK ||
739
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
741
sprintf(message, "when executing '%s TABLE ... %s'", op, options);
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);
753
print_result(&result);
754
drizzle_result_free(&result);
760
static void print_result(drizzle_result_st *result)
763
char prev[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+2];
768
for (i = 0; (row = drizzle_row_next(result)); i++)
770
int changed = strcmp(prev, (char *)row[0]);
771
bool status = !strcmp((char *)row[2], "status");
776
if there was an error with the table, we have --auto-repair set,
777
and this isn't a repair op, then add the table to the tables4repair
780
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
781
strcmp((char *)row[3],"OK"))
782
tables4repair.push_back(string(prev));
787
if (status && changed)
788
printf("%-50s %s", row[0], row[3]);
789
else if (!status && changed)
791
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
792
if (strcmp((char *)row[2],"note"))
796
printf("%-9s: %s", (char *)row[2], (char *)row[3]);
797
strcpy(prev, (char *)row[0]);
800
/* add the last table to be repaired to the list */
801
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
802
tables4repair.push_back(string(prev));
806
static int dbConnect(char *host, char *user, char *passwd)
811
fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
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)
819
DBerror(&dcon, "when trying to connect");
826
static void dbDisconnect(char *host)
829
fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
830
drizzle_free(&drizzle);
834
static void DBerror(drizzle_con_st *con, const char *when)
836
fprintf(stderr,"Got error: %s %s", drizzle_con_error(con), when);
837
safe_exit(EX_MYSQLERR);
842
static void safe_exit(int error)
848
drizzle_free(&drizzle);
853
int main(int argc, char **argv)
857
** Check out the args
859
if (get_options(&argc, &argv))
864
if (dbConnect(current_host, current_user, opt_password))
869
tables4repair.reserve(64);
870
if (tables4repair.capacity() == 0)
879
process_all_databases();
880
/* Only one database and selected table(s) */
881
else if (argc > 1 && !opt_databases)
882
process_selected_tables(*argv, (argv + 1), (argc - 1));
883
/* One or more databases, all tables */
885
process_databases(argv);
889
if (!opt_silent && (tables4repair.size() > 0))
890
puts("\nRepairing tables");
891
what_to_do = DO_REPAIR;
892
vector<string>::iterator i;
893
for ( i= tables4repair.begin() ; i < tables4repair.end() ; i++)
895
const char *name= (*i).c_str();
896
handle_request_for_tables(name, fixed_name_length(name));
900
dbDisconnect(current_host);
903
return(first_error!=0);