~drizzle-trunk/drizzle/development

206.3.1 by Patrick Galbraith
Most everything working with client rename
1
/* Copyright (C) 2008 Drizzle development team
1 by brian
clean slate
2
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.
6
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.
11
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 */
15
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
16
/* By Jani Tolonen, 2001-04-20, MySQL, MYSQL Development Team */
1 by brian
clean slate
17
18
#define CHECK_VERSION "2.5.0"
19
139.1.16 by Trond Norbye
Include config.h first to aviod redefining macro warning
20
#include "config.h"
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
21
#include <vector>
22
#include <string>
1 by brian
clean slate
23
#include "client_priv.h"
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
24
#include <mystrings/m_ctype.h>
1 by brian
clean slate
25
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
26
template class std::vector<std::string>;
27
28
using namespace std;
1 by brian
clean slate
29
/* Exit codes */
30
31
#define EX_USAGE 1
32
#define EX_MYSQLERR 2
33
206.3.1 by Patrick Galbraith
Most everything working with client rename
34
static DRIZZLE drizzle_connection, *sock = 0;
143 by Brian Aker
Bool cleanup.
35
static bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
1 by brian
clean slate
36
               opt_compress = 0, opt_databases = 0, opt_fast = 0,
37
               opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
38
               opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
39
               tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0,
40
               opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0,
41
               opt_write_binlog= 1;
42
static uint verbose = 0, opt_mysql_port=0;
43
static int my_end_arg;
44
static char * opt_mysql_unix_port = 0;
206.3.1 by Patrick Galbraith
Most everything working with client rename
45
static char *opt_password = 0, *current_user = 0,
319.1.1 by Grant Limberg
renamed all instances of MYSQL_ to DRIZZLE_
46
      *default_charset = (char *)DRIZZLE_DEFAULT_CHARSET_NAME,
206.3.1 by Patrick Galbraith
Most everything working with client rename
47
      *current_host = 0;
1 by brian
clean slate
48
static int first_error = 0;
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
49
vector<string> tables4repair;
1 by brian
clean slate
50
static uint opt_protocol=0;
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
51
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
1 by brian
clean slate
52
53
enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
54
55
static struct my_option my_long_options[] =
56
{
57
  {"all-databases", 'A',
58
   "Check all the databases. This will be same as  --databases with all databases selected.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
59
   (char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1 by brian
clean slate
60
   0, 0},
61
  {"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
62
   0, 0, 0, 0},
63
  {"all-in-1", '1',
64
   "Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
65
   (char**) &opt_all_in_1, (char**) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1 by brian
clean slate
66
   0, 0, 0},
67
  {"auto-repair", OPT_AUTO_REPAIR,
68
   "If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
69
   (char**) &opt_auto_repair, (char**) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
1 by brian
clean slate
70
   0, 0, 0, 0, 0},
71
  {"character-sets-dir", OPT_CHARSETS_DIR,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
72
   "Directory where character sets are.", (char**) &charsets_dir,
73
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
74
  {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
75
   0, 0, 0, 0},
76
  {"check-only-changed", 'C',
77
   "Check only tables that have changed since last check or haven't been closed properly.",
78
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
79
  {"check-upgrade", 'g',
80
   "Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.",
81
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
82
  {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
83
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1 by brian
clean slate
84
   0, 0, 0},
85
  {"databases", 'B',
86
   "To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
87
   (char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG,
1 by brian
clean slate
88
   0, 0, 0, 0, 0, 0},
89
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
90
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
1 by brian
clean slate
91
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
92
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
93
   (char**) &debug_info_flag, (char**) &debug_info_flag,
1 by brian
clean slate
94
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
95
  {"default-character-set", OPT_DEFAULT_CHARSET,
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
96
   "Set the default character set.", (char**) &default_charset,
97
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
98
  {"fast",'F', "Check only tables that haven't been closed properly.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
99
   (char**) &opt_fast, (char**) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
1 by brian
clean slate
100
   0},
101
  {"fix-db-names", OPT_FIX_DB_NAMES, "Fix database names.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
102
    (char**) &opt_fix_db_names, (char**) &opt_fix_db_names,
1 by brian
clean slate
103
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
104
  {"fix-table-names", OPT_FIX_TABLE_NAMES, "Fix table names.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
105
    (char**) &opt_fix_table_names, (char**) &opt_fix_table_names,
1 by brian
clean slate
106
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
107
  {"force", 'f', "Continue even if we get an sql-error.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
108
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
1 by brian
clean slate
109
   0, 0, 0, 0},
110
  {"extended", 'e',
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.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
112
   (char**) &opt_extended, (char**) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
1 by brian
clean slate
113
   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},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
116
  {"host",'h', "Connect to host.", (char**) &current_host,
117
   (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
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.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
123
   (char**) &opt_write_binlog, (char**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
1 by brian
clean slate
124
   1, 0, 0, 0, 0, 0},
125
  {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
126
   0, 0},
127
  {"password", 'p',
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 "
301 by Brian Aker
Clean up port startup
131
   "order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
132
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
133
   (char**) &opt_mysql_port,
134
   (char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
1 by brian
clean slate
135
   0},
206.3.1 by Patrick Galbraith
Most everything working with client rename
136
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
1 by brian
clean slate
137
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
138
  {"quick", 'q',
139
   "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.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
140
   (char**) &opt_quick, (char**) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
1 by brian
clean slate
141
   0},
142
  {"repair", 'r',
143
   "Can fix almost anything except unique keys that aren't unique.",
144
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
145
  {"silent", 's', "Print only error messages.", (char**) &opt_silent,
146
   (char**) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
147
  {"socket", 'S', "Socket file to use for connection.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
148
   (char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
1 by brian
clean slate
149
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
150
  {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
151
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
152
  {"use-frm", OPT_FRM,
153
   "When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.",
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
154
   (char**) &opt_frm, (char**) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
1 by brian
clean slate
155
   0},
156
#ifndef DONT_ALLOW_USER_CHANGE
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
157
  {"user", 'u', "User for login if not current user.", (char**) &current_user,
158
   (char**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1 by brian
clean slate
159
#endif
160
  {"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
161
   NO_ARG, 0, 0, 0, 0, 0, 0},
162
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
163
   NO_ARG, 0, 0, 0, 0, 0, 0},
164
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
165
};
166
167
static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
168
169
170
static void print_version(void);
171
static void usage(void);
172
static int get_options(int *argc, char ***argv);
53.2.4 by Monty Taylor
Changes so that client/ builds cleanly with no warnings.
173
static int process_all_databases(void);
1 by brian
clean slate
174
static int process_databases(char **db_names);
175
static int process_selected_tables(char *db, char **table_names, int tables);
176
static int process_all_tables_in_db(char *database);
177
static int process_one_db(char *database);
178
static int use_db(char *database);
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
179
static int handle_request_for_tables(const char *tables, uint length);
1 by brian
clean slate
180
static int dbConnect(char *host, char *user,char *passwd);
181
static void dbDisconnect(char *host);
206.3.1 by Patrick Galbraith
Most everything working with client rename
182
static void DBerror(DRIZZLE *drizzle, const char *when);
1 by brian
clean slate
183
static void safe_exit(int error);
53.2.4 by Monty Taylor
Changes so that client/ builds cleanly with no warnings.
184
static void print_result(void);
1 by brian
clean slate
185
static uint fixed_name_length(const char *name);
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
186
static char *fix_table_name(char *dest, const char *src);
1 by brian
clean slate
187
int what_to_do = 0;
188
189
static void print_version(void)
190
{
191
  printf("%s  Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
264.1.10 by Monty Taylor
Removed client insistence on version.h stuff.
192
   drizzle_get_client_info(), SYSTEM_TYPE, MACHINE_TYPE);
1 by brian
clean slate
193
} /* print_version */
194
195
static void usage(void)
196
{
197
  print_version();
198
  puts("By Jani Tolonen, 2001-04-20, MySQL Development Team\n");
199
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
200
  puts("and you are welcome to modify and redistribute it under the GPL license.\n");
201
  puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
202
  puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
203
  puts("used at the same time. Not all options are supported by all storage engines.");
206.3.1 by Patrick Galbraith
Most everything working with client rename
204
  puts("Please consult the Drizzle manual for latest information about the");
1 by brian
clean slate
205
  puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
206
  puts("means that the last option will be used, if several was specified.\n");
207
  puts("The option -c will be used by default, if none was specified. You");
208
  puts("can change the default behavior by making a symbolic link, or");
209
  puts("copying this file somewhere with another name, the alternatives are:");
210
  puts("mysqlrepair:   The default option will be -r");
211
  puts("mysqlanalyze:  The default option will be -a");
212
  puts("mysqloptimize: The default option will be -o\n");
213
  printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
214
  printf("OR     %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
215
   my_progname);
1 by brian
clean slate
216
  printf("OR     %s [OPTIONS] --all-databases\n", my_progname);
217
  print_defaults("my", load_default_groups);
218
  my_print_help(my_long_options);
219
  my_print_variables(my_long_options);
220
} /* usage */
221
143 by Brian Aker
Bool cleanup.
222
static bool
1 by brian
clean slate
223
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
206.3.1 by Patrick Galbraith
Most everything working with client rename
224
         char *argument)
1 by brian
clean slate
225
{
226
  switch(optid) {
227
  case 'a':
228
    what_to_do = DO_ANALYZE;
229
    break;
230
  case 'c':
231
    what_to_do = DO_CHECK;
232
    break;
233
  case 'C':
234
    what_to_do = DO_CHECK;
235
    opt_check_only_changed = 1;
236
    break;
237
  case 'I': /* Fall through */
238
  case '?':
239
    usage();
240
    exit(0);
241
  case 'm':
242
    what_to_do = DO_CHECK;
243
    opt_medium_check = 1;
244
    break;
245
  case 'o':
246
    what_to_do = DO_OPTIMIZE;
247
    break;
248
  case OPT_FIX_DB_NAMES:
249
    what_to_do= DO_UPGRADE;
250
    default_charset= (char*) "utf8";
251
    opt_databases= 1;
252
    break;
253
  case OPT_FIX_TABLE_NAMES:
254
    what_to_do= DO_UPGRADE;
255
    default_charset= (char*) "utf8";
256
    break;
257
  case 'p':
258
    if (argument)
259
    {
260
      char *start = argument;
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
261
      free(opt_password);
1 by brian
clean slate
262
      opt_password = my_strdup(argument, MYF(MY_FAE));
206.3.1 by Patrick Galbraith
Most everything working with client rename
263
      while (*argument) *argument++= 'x';    /* Destroy argument */
1 by brian
clean slate
264
      if (*start)
206.3.1 by Patrick Galbraith
Most everything working with client rename
265
  start[1] = 0;                             /* Cut length of argument */
1 by brian
clean slate
266
      tty_password= 0;
267
    }
268
    else
269
      tty_password = 1;
270
    break;
271
  case 'r':
272
    what_to_do = DO_REPAIR;
273
    break;
274
  case 'g':
275
    what_to_do= DO_CHECK;
276
    opt_upgrade= 1;
277
    break;
278
  case OPT_TABLES:
279
    opt_databases = 0;
280
    break;
281
  case 'v':
282
    verbose++;
283
    break;
284
  case 'V': print_version(); exit(0);
206.3.1 by Patrick Galbraith
Most everything working with client rename
285
  case OPT_DRIZZLE_PROTOCOL:
1 by brian
clean slate
286
    break;
287
  }
288
  return 0;
289
}
290
291
292
static int get_options(int *argc, char ***argv)
293
{
294
  int ho_error;
295
296
  if (*argc == 1)
297
  {
298
    usage();
299
    exit(0);
300
  }
301
302
  load_defaults("my", load_default_groups, argc, argv);
303
304
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
305
    exit(ho_error);
306
307
  if (!what_to_do)
308
  {
309
    int pnlen = strlen(my_progname);
310
311
    if (pnlen < 6) /* name too short */
312
      what_to_do = DO_CHECK;
313
    else if (!strcmp("repair", my_progname + pnlen - 6))
314
      what_to_do = DO_REPAIR;
315
    else if (!strcmp("analyze", my_progname + pnlen - 7))
316
      what_to_do = DO_ANALYZE;
317
    else if  (!strcmp("optimize", my_progname + pnlen - 8))
318
      what_to_do = DO_OPTIMIZE;
319
    else
320
      what_to_do = DO_CHECK;
321
  }
322
323
  /* TODO: This variable is not yet used */
324
  if (strcmp(default_charset, charset_info->csname) &&
206.3.1 by Patrick Galbraith
Most everything working with client rename
325
      !(charset_info= get_charset_by_csname(default_charset,
326
                MY_CS_PRIMARY, MYF(MY_WME))))
1 by brian
clean slate
327
      exit(1);
328
  if (*argc > 0 && opt_alldbs)
329
  {
330
    printf("You should give only options, no arguments at all, with option\n");
331
    printf("--all-databases. Please see %s --help for more information.\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
332
     my_progname);
1 by brian
clean slate
333
    return 1;
334
  }
335
  if (*argc < 1 && !opt_alldbs)
336
  {
337
    printf("You forgot to give the arguments! Please see %s --help\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
338
     my_progname);
1 by brian
clean slate
339
    printf("for more information.\n");
340
    return 1;
341
  }
342
  if (tty_password)
461 by Monty Taylor
Removed NullS. bu-bye.
343
    opt_password = get_tty_password(NULL);
1 by brian
clean slate
344
  if (debug_info_flag)
345
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
346
  if (debug_check_flag)
347
    my_end_arg= MY_CHECK_ERROR;
348
  return(0);
349
} /* get_options */
350
351
352
static int process_all_databases()
353
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
354
  DRIZZLE_ROW row;
355
  DRIZZLE_RES *tableres;
1 by brian
clean slate
356
  int result = 0;
357
206.3.1 by Patrick Galbraith
Most everything working with client rename
358
  if (drizzle_query(sock, "SHOW DATABASES") ||
359
      !(tableres = drizzle_store_result(sock)))
1 by brian
clean slate
360
  {
361
    my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
206.3.1 by Patrick Galbraith
Most everything working with client rename
362
        MYF(0), drizzle_error(sock));
1 by brian
clean slate
363
    return 1;
364
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
365
  while ((row = drizzle_fetch_row(tableres)))
1 by brian
clean slate
366
  {
367
    if (process_one_db(row[0]))
368
      result = 1;
369
  }
370
  return result;
371
}
372
/* process_all_databases */
373
374
375
static int process_databases(char **db_names)
376
{
377
  int result = 0;
378
  for ( ; *db_names ; db_names++)
379
  {
380
    if (process_one_db(*db_names))
381
      result = 1;
382
  }
383
  return result;
384
} /* process_databases */
385
386
387
static int process_selected_tables(char *db, char **table_names, int tables)
388
{
389
  if (use_db(db))
390
    return 1;
391
  if (opt_all_in_1)
392
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
393
    /*
1 by brian
clean slate
394
      We need table list in form `a`, `b`, `c`
395
      that's why we need 2 more chars added to to each table name
396
      space is for more readable output in logs and in case of error
206.3.1 by Patrick Galbraith
Most everything working with client rename
397
    */   
1 by brian
clean slate
398
    char *table_names_comma_sep, *end;
399
    int i, tot_length = 0;
400
401
    for (i = 0; i < tables; i++)
402
      tot_length+= fixed_name_length(*(table_names + i)) + 2;
403
404
    if (!(table_names_comma_sep = (char *)
206.3.1 by Patrick Galbraith
Most everything working with client rename
405
    my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
1 by brian
clean slate
406
      return 1;
407
408
    for (end = table_names_comma_sep + 1; tables > 0;
206.3.1 by Patrick Galbraith
Most everything working with client rename
409
   tables--, table_names++)
1 by brian
clean slate
410
    {
411
      end= fix_table_name(end, *table_names);
412
      *end++= ',';
413
    }
414
    *--end = 0;
415
    handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
416
    free(table_names_comma_sep);
1 by brian
clean slate
417
  }
418
  else
419
    for (; tables > 0; tables--, table_names++)
420
      handle_request_for_tables(*table_names, fixed_name_length(*table_names));
421
  return 0;
422
} /* process_selected_tables */
423
424
425
static uint fixed_name_length(const char *name)
426
{
427
  const char *p;
428
  uint extra_length= 2;  /* count the first/last backticks */
206.3.1 by Patrick Galbraith
Most everything working with client rename
429
 
1 by brian
clean slate
430
  for (p= name; *p; p++)
431
  {
432
    if (*p == '`')
433
      extra_length++;
434
    else if (*p == '.')
435
      extra_length+= 2;
436
  }
437
  return (p - name) + extra_length;
438
}
439
440
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
441
static char *fix_table_name(char *dest, const char *src)
1 by brian
clean slate
442
{
443
  *dest++= '`';
444
  for (; *src; src++)
445
  {
446
    switch (*src) {
447
    case '.':            /* add backticks around '.' */
448
      *dest++= '`';
449
      *dest++= '.';
450
      *dest++= '`';
451
      break;
452
    case '`':            /* escape backtick character */
453
      *dest++= '`';
454
      /* fall through */
455
    default:
456
      *dest++= *src;
457
    }
458
  }
459
  *dest++= '`';
460
  return dest;
461
}
462
463
464
static int process_all_tables_in_db(char *database)
465
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
466
  DRIZZLE_RES *res;
467
  DRIZZLE_ROW row;
1 by brian
clean slate
468
  uint num_columns;
469
470
  if (use_db(database))
471
    return 1;
206.3.1 by Patrick Galbraith
Most everything working with client rename
472
  if (drizzle_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
473
  !((res= drizzle_store_result(sock))))
1 by brian
clean slate
474
    return 1;
475
206.3.1 by Patrick Galbraith
Most everything working with client rename
476
  num_columns= drizzle_num_fields(res);
1 by brian
clean slate
477
478
  if (opt_all_in_1)
479
  {
480
    /*
481
      We need table list in form `a`, `b`, `c`
482
      that's why we need 2 more chars added to to each table name
483
      space is for more readable output in logs and in case of error
484
     */
485
486
    char *tables, *end;
487
    uint tot_length = 0;
488
206.3.1 by Patrick Galbraith
Most everything working with client rename
489
    while ((row = drizzle_fetch_row(res)))
1 by brian
clean slate
490
      tot_length+= fixed_name_length(row[0]) + 2;
206.3.1 by Patrick Galbraith
Most everything working with client rename
491
    drizzle_data_seek(res, 0);
1 by brian
clean slate
492
493
    if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
494
    {
206.3.1 by Patrick Galbraith
Most everything working with client rename
495
      drizzle_free_result(res);
1 by brian
clean slate
496
      return 1;
497
    }
206.3.1 by Patrick Galbraith
Most everything working with client rename
498
    for (end = tables + 1; (row = drizzle_fetch_row(res)) ;)
1 by brian
clean slate
499
    {
500
      if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
501
        continue;
502
503
      end= fix_table_name(end, row[0]);
504
      *end++= ',';
505
    }
506
    *--end = 0;
507
    if (tot_length)
508
      handle_request_for_tables(tables + 1, tot_length - 1);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
509
    free(tables);
1 by brian
clean slate
510
  }
511
  else
512
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
513
    while ((row = drizzle_fetch_row(res)))
1 by brian
clean slate
514
    {
515
      /* Skip views if we don't perform renaming. */
516
      if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
517
        continue;
518
519
      handle_request_for_tables(row[0], fixed_name_length(row[0]));
520
    }
521
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
522
  drizzle_free_result(res);
1 by brian
clean slate
523
  return 0;
524
} /* process_all_tables_in_db */
525
526
527
528
static int fix_table_storage_name(const char *name)
529
{
530
  char qbuf[100 + NAME_LEN*4];
531
  int rc= 0;
532
  if (strncmp(name, "#mysql50#", 9))
533
    return 1;
534
  sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
206.3.1 by Patrick Galbraith
Most everything working with client rename
535
  if (drizzle_query(sock, qbuf))
1 by brian
clean slate
536
  {
537
    fprintf(stderr, "Failed to %s\n", qbuf);
206.3.1 by Patrick Galbraith
Most everything working with client rename
538
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
1 by brian
clean slate
539
    rc= 1;
540
  }
541
  if (verbose)
542
    printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
543
  return rc;
544
}
545
546
static int fix_database_storage_name(const char *name)
547
{
548
  char qbuf[100 + NAME_LEN*4];
549
  int rc= 0;
550
  if (strncmp(name, "#mysql50#", 9))
551
    return 1;
552
  sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
206.3.1 by Patrick Galbraith
Most everything working with client rename
553
  if (drizzle_query(sock, qbuf))
1 by brian
clean slate
554
  {
555
    fprintf(stderr, "Failed to %s\n", qbuf);
206.3.1 by Patrick Galbraith
Most everything working with client rename
556
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
1 by brian
clean slate
557
    rc= 1;
558
  }
559
  if (verbose)
560
    printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
561
  return rc;
562
}
563
564
static int process_one_db(char *database)
565
{
566
  if (what_to_do == DO_UPGRADE)
567
  {
568
    int rc= 0;
569
    if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
570
    {
571
      rc= fix_database_storage_name(database);
572
      database+= 9;
573
    }
574
    if (rc || !opt_fix_table_names)
575
      return rc;
576
  }
577
  return process_all_tables_in_db(database);
578
}
579
580
581
static int use_db(char *database)
582
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
583
  if (drizzle_get_server_version(sock) >= 50003 &&
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
584
      !my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
1 by brian
clean slate
585
    return 1;
206.3.1 by Patrick Galbraith
Most everything working with client rename
586
  if (drizzle_select_db(sock, database))
1 by brian
clean slate
587
  {
588
    DBerror(sock, "when selecting the database");
589
    return 1;
590
  }
591
  return 0;
592
} /* use_db */
593
594
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
595
static int handle_request_for_tables(const char *tables, uint length)
1 by brian
clean slate
596
{
597
  char *query, *end, options[100], message[100];
598
  uint query_length= 0;
599
  const char *op = 0;
600
601
  options[0] = 0;
602
  end = options;
603
  switch (what_to_do) {
604
  case DO_CHECK:
605
    op = "CHECK";
411.1.1 by Brian Aker
Work on removing GNU specific calls.
606
    if (opt_quick)              end = my_stpcpy(end, " QUICK");
607
    if (opt_fast)               end = my_stpcpy(end, " FAST");
608
    if (opt_medium_check)       end = my_stpcpy(end, " MEDIUM"); /* Default */
609
    if (opt_extended)           end = my_stpcpy(end, " EXTENDED");
610
    if (opt_check_only_changed) end = my_stpcpy(end, " CHANGED");
611
    if (opt_upgrade)            end = my_stpcpy(end, " FOR UPGRADE");
1 by brian
clean slate
612
    break;
613
  case DO_REPAIR:
614
    op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG";
411.1.1 by Brian Aker
Work on removing GNU specific calls.
615
    if (opt_quick)              end = my_stpcpy(end, " QUICK");
616
    if (opt_extended)           end = my_stpcpy(end, " EXTENDED");
617
    if (opt_frm)                end = my_stpcpy(end, " USE_FRM");
1 by brian
clean slate
618
    break;
619
  case DO_ANALYZE:
620
    op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
621
    break;
622
  case DO_OPTIMIZE:
623
    op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
624
    break;
625
  case DO_UPGRADE:
626
    return fix_table_storage_name(tables);
627
  }
628
629
  if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
630
    return 1;
631
  if (opt_all_in_1)
632
  {
633
    /* No backticks here as we added them before */
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
634
    query_length= sprintf(query, "%s TABLE %s %s", op, tables, options);
1 by brian
clean slate
635
  }
636
  else
637
  {
638
    char *ptr;
639
411.1.1 by Brian Aker
Work on removing GNU specific calls.
640
    ptr= my_stpcpy(my_stpcpy(query, op), " TABLE ");
1 by brian
clean slate
641
    ptr= fix_table_name(ptr, tables);
461 by Monty Taylor
Removed NullS. bu-bye.
642
    ptr= strxmov(ptr, " ", options, NULL);
1 by brian
clean slate
643
    query_length= (uint) (ptr - query);
644
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
645
  if (drizzle_real_query(sock, query, query_length))
1 by brian
clean slate
646
  {
647
    sprintf(message, "when executing '%s TABLE ... %s'", op, options);
648
    DBerror(sock, message);
649
    return 1;
650
  }
651
  print_result();
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
652
  free(query);
1 by brian
clean slate
653
  return 0;
654
}
655
656
657
static void print_result()
658
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
659
  DRIZZLE_RES *res;
660
  DRIZZLE_ROW row;
1 by brian
clean slate
661
  char prev[NAME_LEN*2+2];
662
  uint i;
143 by Brian Aker
Bool cleanup.
663
  bool found_error=0;
1 by brian
clean slate
664
206.3.1 by Patrick Galbraith
Most everything working with client rename
665
  res = drizzle_use_result(sock);
1 by brian
clean slate
666
667
  prev[0] = '\0';
206.3.1 by Patrick Galbraith
Most everything working with client rename
668
  for (i = 0; (row = drizzle_fetch_row(res)); i++)
1 by brian
clean slate
669
  {
670
    int changed = strcmp(prev, row[0]);
143 by Brian Aker
Bool cleanup.
671
    bool status = !strcmp(row[2], "status");
1 by brian
clean slate
672
673
    if (status)
674
    {
675
      /*
676
        if there was an error with the table, we have --auto-repair set,
677
        and this isn't a repair op, then add the table to the tables4repair
678
        list
679
      */
680
      if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
681
          strcmp(row[3],"OK"))
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
682
        tables4repair.push_back(string(prev));
1 by brian
clean slate
683
      found_error=0;
684
      if (opt_silent)
206.3.1 by Patrick Galbraith
Most everything working with client rename
685
  continue;
1 by brian
clean slate
686
    }
687
    if (status && changed)
688
      printf("%-50s %s", row[0], row[3]);
689
    else if (!status && changed)
690
    {
691
      printf("%s\n%-9s: %s", row[0], row[2], row[3]);
692
      if (strcmp(row[2],"note"))
206.3.1 by Patrick Galbraith
Most everything working with client rename
693
  found_error=1;
1 by brian
clean slate
694
    }
695
    else
696
      printf("%-9s: %s", row[2], row[3]);
411.1.1 by Brian Aker
Work on removing GNU specific calls.
697
    my_stpcpy(prev, row[0]);
1 by brian
clean slate
698
    putchar('\n');
699
  }
700
  /* add the last table to be repaired to the list */
701
  if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
702
    tables4repair.push_back(string(prev));
206.3.1 by Patrick Galbraith
Most everything working with client rename
703
  drizzle_free_result(res);
1 by brian
clean slate
704
}
705
706
707
static int dbConnect(char *host, char *user, char *passwd)
708
{
142.1.2 by Patrick
All DBUG_x removed from client/
709
1 by brian
clean slate
710
  if (verbose)
711
  {
712
    fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
713
  }
202.2.4 by Monty Taylor
Merged from Patrick.
714
  drizzle_create(&drizzle_connection);
1 by brian
clean slate
715
  if (opt_compress)
461 by Monty Taylor
Removed NullS. bu-bye.
716
    drizzle_options(&drizzle_connection, DRIZZLE_OPT_COMPRESS, NULL);
1 by brian
clean slate
717
  if (opt_protocol)
206.3.1 by Patrick Galbraith
Most everything working with client rename
718
    drizzle_options(&drizzle_connection,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
719
  if (!(sock = drizzle_connect(&drizzle_connection, host, user, passwd,
1 by brian
clean slate
720
         NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
721
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
722
    DBerror(&drizzle_connection, "when trying to connect");
1 by brian
clean slate
723
    return 1;
724
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
725
  drizzle_connection.reconnect= 1;
1 by brian
clean slate
726
  return 0;
727
} /* dbConnect */
728
729
730
static void dbDisconnect(char *host)
731
{
732
  if (verbose)
733
    fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
206.3.1 by Patrick Galbraith
Most everything working with client rename
734
  drizzle_close(sock);
1 by brian
clean slate
735
} /* dbDisconnect */
736
737
206.3.1 by Patrick Galbraith
Most everything working with client rename
738
static void DBerror(DRIZZLE *drizzle, const char *when)
1 by brian
clean slate
739
{
740
  my_printf_error(0,"Got error: %d: %s %s", MYF(0),
206.3.1 by Patrick Galbraith
Most everything working with client rename
741
      drizzle_errno(drizzle), drizzle_error(drizzle), when);
1 by brian
clean slate
742
  safe_exit(EX_MYSQLERR);
142.1.2 by Patrick
All DBUG_x removed from client/
743
  return;
1 by brian
clean slate
744
} /* DBerror */
745
746
747
static void safe_exit(int error)
748
{
749
  if (!first_error)
750
    first_error= error;
751
  if (ignore_errors)
752
    return;
753
  if (sock)
206.3.1 by Patrick Galbraith
Most everything working with client rename
754
    drizzle_close(sock);
1 by brian
clean slate
755
  exit(error);
756
}
757
758
759
int main(int argc, char **argv)
760
{
761
  MY_INIT(argv[0]);
762
  /*
763
  ** Check out the args
764
  */
765
  if (get_options(&argc, &argv))
766
  {
767
    my_end(my_end_arg);
768
    exit(EX_USAGE);
769
  }
770
  if (dbConnect(current_host, current_user, opt_password))
771
    exit(EX_MYSQLERR);
772
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
773
  if (opt_auto_repair)
1 by brian
clean slate
774
  {
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
775
    tables4repair.reserve(64);
776
    if (tables4repair.capacity() == 0)
777
    {
778
      first_error = 1;
779
      goto end;
780
    }
1 by brian
clean slate
781
  }
782
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
783
1 by brian
clean slate
784
  if (opt_alldbs)
785
    process_all_databases();
786
  /* Only one database and selected table(s) */
787
  else if (argc > 1 && !opt_databases)
788
    process_selected_tables(*argv, (argv + 1), (argc - 1));
789
  /* One or more databases, all tables */
790
  else
791
    process_databases(argv);
792
  if (opt_auto_repair)
793
  {
794
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
795
    if (!opt_silent && (tables4repair.size() > 0))
1 by brian
clean slate
796
      puts("\nRepairing tables");
797
    what_to_do = DO_REPAIR;
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
798
    vector<string>::iterator i;
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
799
    for ( i= tables4repair.begin() ; i < tables4repair.end() ; i++)
1 by brian
clean slate
800
    {
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
801
      const char *name= (*i).c_str();
1 by brian
clean slate
802
      handle_request_for_tables(name, fixed_name_length(name));
803
    }
804
  }
805
 end:
806
  dbDisconnect(current_host);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
807
  free(opt_password);
1 by brian
clean slate
808
  my_end(my_end_arg);
809
  return(first_error!=0);
810
} /* main */