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"
24
/* Added this for string translation. */
25
#include <drizzled/gettext.h>
30
template class vector<string>;
33
bool get_one_option(int optid, const struct my_option *, char *argument);
40
static drizzle_st drizzle;
41
static drizzle_con_st dcon;
42
static bool opt_alldbs= false, opt_check_only_changed= false,
43
opt_extended= false, opt_databases= false,
44
opt_fast= false, opt_medium_check= false, opt_quick= false,
45
opt_all_in_1= false, opt_silent= false,
46
ignore_errors= false, tty_password= false, opt_frm= false,
47
debug_info_flag= false, debug_check_flag= false,
48
opt_fix_table_names= false, opt_fix_db_names= false,
49
opt_upgrade= false, opt_write_binlog= true;
50
static uint32_t verbose= 0;
51
static uint32_t opt_drizzle_port= 0;
52
static int my_end_arg;
53
static char * opt_drizzle_unix_port= NULL;
54
static char *opt_password= NULL, *current_user= NULL,
56
static int first_error= 0;
58
enum operations { DO_CHECK, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
60
static struct my_option my_long_options[] =
62
{"all-databases", 'A',
63
"Check all the databases. This will be same as --databases with all databases selected.",
64
(char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
66
{"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
69
"Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.",
70
(char**) &opt_all_in_1, (char**) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
72
{"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
74
{"check-only-changed", 'C',
75
"Check only tables that have changed since last check or haven't been closed properly.",
76
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
77
{"check-upgrade", 'g',
78
"Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.",
79
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
81
"To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
82
(char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG,
84
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
85
(char**) &debug_check_flag, (char**) &debug_check_flag, 0,
86
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
87
{"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
88
(char**) &debug_info_flag, (char**) &debug_info_flag,
89
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
90
{"fast",'F', "Check only tables that haven't been closed properly.",
91
(char**) &opt_fast, (char**) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
93
{"fix-db-names", OPT_FIX_DB_NAMES, "Fix database names.",
94
(char**) &opt_fix_db_names, (char**) &opt_fix_db_names,
95
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
96
{"fix-table-names", OPT_FIX_TABLE_NAMES, "Fix table names.",
97
(char**) &opt_fix_table_names, (char**) &opt_fix_table_names,
98
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
99
{"force", 'f', "Continue even if we get an sql-error.",
100
(char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
103
"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.",
104
(char**) &opt_extended, (char**) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
106
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
107
NO_ARG, 0, 0, 0, 0, 0, 0},
108
{"host",'h', "Connect to host.", (char**) ¤t_host,
109
(char**) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
110
{"medium-check", 'm',
111
"Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
112
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
113
{"write-binlog", OPT_WRITE_BINLOG,
114
"Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog when commands should not be sent to replication slaves.",
115
(char**) &opt_write_binlog, (char**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
117
{"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
120
"Password to use when connecting to server. If password is not given it's solicited on the tty.",
121
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
122
{"port", 'p', "Port number to use for connection or 0 for default to, in "
123
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
124
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
125
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
126
{"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
127
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
129
"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.",
130
(char**) &opt_quick, (char**) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
132
{"silent", 's', "Print only error messages.", (char**) &opt_silent,
133
(char**) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
134
{"socket", 'S', "Socket file to use for connection.",
135
(char**) &opt_drizzle_unix_port, (char**) &opt_drizzle_unix_port, 0, GET_STR,
136
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
137
{"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
138
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
140
"When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.",
141
(char**) &opt_frm, (char**) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
143
{"user", 'u', "User for login if not current user.", (char**) ¤t_user,
144
(char**) ¤t_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
145
{"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
146
NO_ARG, 0, 0, 0, 0, 0, 0},
147
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
148
NO_ARG, 0, 0, 0, 0, 0, 0},
149
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
152
static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
155
static void print_version(void);
156
static void usage(void);
157
static int get_options(int *argc, char ***argv);
158
static int process_all_databases(void);
159
static int process_databases(char **db_names);
160
static int process_selected_tables(char *db, char **table_names, int tables);
161
static int process_all_tables_in_db(char *database);
162
static int process_one_db(char *database);
163
static int use_db(char *database);
164
static int handle_request_for_tables(const char *tables, uint32_t length);
165
static int dbConnect(char *host, char *user,char *passwd);
166
static void dbDisconnect(char *host);
167
static void DBerror(drizzle_con_st *con, const char *when);
168
static void safe_exit(int error);
169
static void print_result(drizzle_result_st *result);
170
static uint32_t fixed_name_length(const char *name);
171
static char *fix_table_name(char *dest, const char *src);
174
static void print_version(void)
176
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n", my_progname, CHECK_VERSION,
177
drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
178
} /* print_version */
180
static void usage(void)
183
puts("By Jani Tolonen, 2001-04-20, MySQL Development Team\n");
184
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
185
puts("and you are welcome to modify and redistribute it under the GPL license.\n");
186
puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
187
puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
188
puts("used at the same time. Not all options are supported by all storage engines.");
189
puts("Please consult the Drizzle manual for latest information about the");
190
puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
191
puts("means that the last option will be used, if several was specified.\n");
192
puts("The option -c will be used by default, if none was specified. You");
193
puts("can change the default behavior by making a symbolic link, or");
194
puts("copying this file somewhere with another name, the alternatives are:");
195
puts("mysqlrepair: The default option will be -r");
196
puts("mysqlanalyze: The default option will be -a");
197
puts("mysqloptimize: The default option will be -o\n");
198
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
199
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
201
printf("OR %s [OPTIONS] --all-databases\n", my_progname);
202
print_defaults("drizzle", load_default_groups);
203
my_print_help(my_long_options);
204
my_print_variables(my_long_options);
207
bool get_one_option(int optid, const struct my_option *, char *argument)
210
uint64_t temp_drizzle_port= 0;
214
what_to_do = DO_ANALYZE;
217
what_to_do = DO_CHECK;
220
what_to_do = DO_CHECK;
221
opt_check_only_changed = 1;
223
case 'I': /* Fall through */
228
what_to_do = DO_CHECK;
229
opt_medium_check = 1;
232
what_to_do = DO_OPTIMIZE;
234
case OPT_FIX_DB_NAMES:
235
what_to_do= DO_UPGRADE;
238
case OPT_FIX_TABLE_NAMES:
239
what_to_do= DO_UPGRADE;
242
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
243
/* if there is an alpha character this is not a valid port */
244
if (strlen(endchar) != 0)
246
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
249
/* If the port number is > 65535 it is not a valid port
250
This also helps with potential data loss casting unsigned long to a
252
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
254
fprintf(stderr, _("Value supplied for port is not valid.\n"));
259
opt_drizzle_port= (uint32_t) temp_drizzle_port;
265
char *start= argument;
268
opt_password = strdup(argument);
269
if (opt_password == NULL)
271
fprintf(stderr, "Memory allocation error while copying password. "
277
/* Overwriting password with 'x' */
282
/* Cut length of argument */
291
what_to_do= DO_CHECK;
300
case 'V': print_version(); exit(0);
301
case OPT_DRIZZLE_PROTOCOL:
308
static int get_options(int *argc, char ***argv)
318
load_defaults("drizzle", load_default_groups, argc, argv);
320
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
325
int pnlen = strlen(my_progname);
327
if (pnlen < 6) /* name too short */
328
what_to_do = DO_CHECK;
329
else if (!strcmp("analyze", my_progname + pnlen - 7))
330
what_to_do = DO_ANALYZE;
331
else if (!strcmp("optimize", my_progname + pnlen - 8))
332
what_to_do = DO_OPTIMIZE;
334
what_to_do = DO_CHECK;
337
if (*argc > 0 && opt_alldbs)
339
printf("You should give only options, no arguments at all, with option\n");
340
printf("--all-databases. Please see %s --help for more information.\n",
344
if (*argc < 1 && !opt_alldbs)
346
printf("You forgot to give the arguments! Please see %s --help\n",
348
printf("for more information.\n");
352
opt_password = client_get_tty_password(NULL);
354
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
355
if (debug_check_flag)
356
my_end_arg= MY_CHECK_ERROR;
361
static int process_all_databases()
364
drizzle_result_st result;
365
drizzle_return_t ret;
368
if (drizzle_query_str(&dcon, &result, "SHOW DATABASES", &ret) == NULL ||
369
ret != DRIZZLE_RETURN_OK ||
370
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
372
if (ret == DRIZZLE_RETURN_ERROR_CODE)
374
fprintf(stderr, "Error: Couldn't execute 'SHOW DATABASES': %s",
375
drizzle_result_error(&result));
376
drizzle_result_free(&result);
380
fprintf(stderr, "Error: Couldn't execute 'SHOW DATABASES': %s",
381
drizzle_con_error(&dcon));
386
while ((row = drizzle_row_next(&result)))
388
if (process_one_db((char *)row[0]))
391
drizzle_result_free(&result);
394
/* process_all_databases */
397
static int process_databases(char **db_names)
400
for ( ; *db_names ; db_names++)
402
if (process_one_db(*db_names))
406
} /* process_databases */
409
static int process_selected_tables(char *db, char **table_names, int tables)
416
We need table list in form `a`, `b`, `c`
417
that's why we need 2 more chars added to to each table name
418
space is for more readable output in logs and in case of error
420
char *table_names_comma_sep, *end;
421
int i, tot_length = 0;
423
for (i = 0; i < tables; i++)
424
tot_length+= fixed_name_length(*(table_names + i)) + 2;
426
if (!(table_names_comma_sep = (char *)
427
malloc((sizeof(char) * tot_length) + 4)))
430
for (end = table_names_comma_sep + 1; tables > 0;
431
tables--, table_names++)
433
end= fix_table_name(end, *table_names);
437
handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
438
free(table_names_comma_sep);
441
for (; tables > 0; tables--, table_names++)
442
handle_request_for_tables(*table_names, fixed_name_length(*table_names));
444
} /* process_selected_tables */
447
static uint32_t fixed_name_length(const char *name)
450
uint32_t extra_length= 2; /* count the first/last backticks */
452
for (p= name; *p; p++)
459
return (p - name) + extra_length;
463
static char *fix_table_name(char *dest, const char *src)
469
case '.': /* add backticks around '.' */
474
case '`': /* escape backtick character */
486
static int process_all_tables_in_db(char *database)
488
drizzle_result_st result;
490
drizzle_return_t ret;
491
uint32_t num_columns;
493
if (use_db(database))
495
if (drizzle_query_str(&dcon, &result, "SHOW /*!50002 FULL*/ TABLES",
497
ret != DRIZZLE_RETURN_OK ||
498
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
500
if (ret == DRIZZLE_RETURN_ERROR_CODE)
501
drizzle_result_free(&result);
505
num_columns= drizzle_result_column_count(&result);
510
We need table list in form `a`, `b`, `c`
511
that's why we need 2 more chars added to to each table name
512
space is for more readable output in logs and in case of error
516
uint32_t tot_length = 0;
518
while ((row = drizzle_row_next(&result)))
519
tot_length+= fixed_name_length((char *)row[0]) + 2;
520
drizzle_row_seek(&result, 0);
522
if (!(tables=(char *) malloc(sizeof(char)*tot_length+4)))
524
drizzle_result_free(&result);
527
for (end = tables + 1; (row = drizzle_row_next(&result)) ;)
529
if ((num_columns == 2) && (strcmp((char *)row[1], "VIEW") == 0))
532
end= fix_table_name(end, (char *)row[0]);
537
handle_request_for_tables(tables + 1, tot_length - 1);
542
while ((row = drizzle_row_next(&result)))
544
/* Skip views if we don't perform renaming. */
545
if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp((char *)row[1], "VIEW") == 0))
548
handle_request_for_tables((char *)row[0],
549
fixed_name_length((char *)row[0]));
552
drizzle_result_free(&result);
554
} /* process_all_tables_in_db */
558
static int fix_table_storage_name(const char *name)
560
char qbuf[100 + DRIZZLE_MAX_COLUMN_NAME_SIZE*4];
561
drizzle_result_st result;
562
drizzle_return_t ret;
564
if (strncmp(name, "#mysql50#", 9))
566
sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
567
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
568
ret != DRIZZLE_RETURN_OK)
570
fprintf(stderr, "Failed to %s\n", qbuf);
571
if (ret == DRIZZLE_RETURN_ERROR_CODE)
573
fprintf(stderr, "Error: %s\n", drizzle_result_error(&result));
574
drizzle_result_free(&result);
577
fprintf(stderr, "Error: %s\n", drizzle_con_error(&dcon));
581
drizzle_result_free(&result);
583
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
587
static int fix_database_storage_name(const char *name)
589
char qbuf[100 + DRIZZLE_MAX_COLUMN_NAME_SIZE*4];
590
drizzle_result_st result;
591
drizzle_return_t ret;
593
if (strncmp(name, "#mysql50#", 9))
595
sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
596
if (drizzle_query_str(&dcon, &result, qbuf, &ret) == NULL ||
597
ret != DRIZZLE_RETURN_OK)
599
fprintf(stderr, "Failed to %s\n", qbuf);
600
if (ret == DRIZZLE_RETURN_ERROR_CODE)
602
fprintf(stderr, "Error: %s\n", drizzle_result_error(&result));
603
drizzle_result_free(&result);
606
fprintf(stderr, "Error: %s\n", drizzle_con_error(&dcon));
610
drizzle_result_free(&result);
612
printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
616
static int process_one_db(char *database)
618
if (what_to_do == DO_UPGRADE)
621
if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
623
rc= fix_database_storage_name(database);
626
if (rc || !opt_fix_table_names)
629
return process_all_tables_in_db(database);
633
static int use_db(char *database)
635
drizzle_result_st result;
636
drizzle_return_t ret;
637
if (drizzle_con_server_version_number(&dcon) >= 50003 &&
638
!my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
640
if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
641
ret != DRIZZLE_RETURN_OK)
643
if (ret == DRIZZLE_RETURN_ERROR_CODE)
645
fprintf(stderr,"Got error: %s when selecting the database",
646
drizzle_result_error(&result));
647
safe_exit(EX_MYSQLERR);
648
drizzle_result_free(&result);
651
DBerror(&dcon, "when selecting the database");
654
drizzle_result_free(&result);
659
static int handle_request_for_tables(const char *tables, uint32_t length)
661
char *query, *end, options[100], message[100];
662
uint32_t query_length= 0;
664
drizzle_result_st result;
665
drizzle_return_t ret;
669
switch (what_to_do) {
672
if (opt_quick) end = strcpy(end, " QUICK")+6;
673
if (opt_fast) end = strcpy(end, " FAST")+5;
674
if (opt_medium_check) end = strcpy(end, " MEDIUM")+7; /* Default */
675
if (opt_extended) end = strcpy(end, " EXTENDED")+9;
676
if (opt_check_only_changed) end = strcpy(end, " CHANGED")+8;
677
if (opt_upgrade) end = strcpy(end, " FOR UPGRADE")+12;
680
op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
683
op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
686
return fix_table_storage_name(tables);
689
if (!(query =(char *) malloc((sizeof(char)*(length+110)))))
693
/* No backticks here as we added them before */
694
query_length= sprintf(query, "%s TABLE %s %s", op, tables, options);
700
ptr= strcpy(query, op)+strlen(op);
701
ptr= strcpy(ptr, " TABLE ")+7;
702
ptr= fix_table_name(ptr, tables);
703
ptr+= sprintf(ptr," %s",options);
704
query_length= (uint32_t) (ptr - query);
706
if (drizzle_query(&dcon, &result, query, query_length, &ret) == NULL ||
707
ret != DRIZZLE_RETURN_OK ||
708
drizzle_result_buffer(&result) != DRIZZLE_RETURN_OK)
710
sprintf(message, "when executing '%s TABLE ... %s'", op, options);
711
if (ret == DRIZZLE_RETURN_ERROR_CODE)
713
fprintf(stderr,"Got error: %s %s",
714
drizzle_result_error(&result), message);
715
safe_exit(EX_MYSQLERR);
716
drizzle_result_free(&result);
719
DBerror(&dcon, message);
722
print_result(&result);
723
drizzle_result_free(&result);
729
static void print_result(drizzle_result_st *result)
732
char prev[DRIZZLE_MAX_COLUMN_NAME_SIZE*2+2];
737
for (i = 0; (row = drizzle_row_next(result)); i++)
739
int changed = strcmp(prev, (char *)row[0]);
740
bool status = !strcmp((char *)row[2], "status");
748
if (status && changed)
749
printf("%-50s %s", row[0], row[3]);
750
else if (!status && changed)
752
printf("%s\n%-9s: %s", row[0], row[2], row[3]);
753
if (strcmp((char *)row[2],"note"))
757
printf("%-9s: %s", (char *)row[2], (char *)row[3]);
758
strcpy(prev, (char *)row[0]);
764
static int dbConnect(char *host, char *user, char *passwd)
769
fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
771
drizzle_create(&drizzle);
772
drizzle_con_create(&drizzle, &dcon);
773
drizzle_con_set_tcp(&dcon, host, opt_drizzle_port);
774
drizzle_con_set_auth(&dcon, user, passwd);
775
if (drizzle_con_connect(&dcon) != DRIZZLE_RETURN_OK)
777
DBerror(&dcon, "when trying to connect");
784
static void dbDisconnect(char *host)
787
fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
788
drizzle_free(&drizzle);
792
static void DBerror(drizzle_con_st *con, const char *when)
794
fprintf(stderr,"Got error: %s %s", drizzle_con_error(con), when);
795
safe_exit(EX_MYSQLERR);
800
static void safe_exit(int error)
806
drizzle_free(&drizzle);
811
int main(int argc, char **argv)
815
** Check out the args
817
if (get_options(&argc, &argv))
822
if (dbConnect(current_host, current_user, opt_password))
826
process_all_databases();
827
/* Only one database and selected table(s) */
828
else if (argc > 1 && !opt_databases)
829
process_selected_tables(*argv, (argv + 1), (argc - 1));
830
/* One or more databases, all tables */
832
process_databases(argv);
834
dbDisconnect(current_host);
837
return(first_error!=0);