~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
612.2.4 by Monty Taylor
Moved some defines to config.h. Stopped including config.h directly anywhere.
20
#include "client_priv.h"
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
21
#include <vector>
22
#include <string>
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
23
#include <mystrings/m_ctype.h>
1 by brian
clean slate
24
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
25
using namespace std;
670.3.3 by Toru Maesaka
Added namespacing for std to .cc files that needed it
26
27
template class vector<string>;
28
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 "
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
131
   "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
301 by Brian Aker
Clean up port startup
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);
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
217
  print_defaults("drizzle", load_default_groups);
1 by brian
clean slate
218
  my_print_help(my_long_options);
219
  my_print_variables(my_long_options);
220
} /* usage */
221
632.1.12 by Monty Taylor
Fixed more sun studio warnings.
222
extern "C"
637 by Brian Aker
Merge from Monty
223
bool get_one_option(int optid, const struct my_option *, char *argument)
1 by brian
clean slate
224
{
225
  switch(optid) {
226
  case 'a':
227
    what_to_do = DO_ANALYZE;
228
    break;
229
  case 'c':
230
    what_to_do = DO_CHECK;
231
    break;
232
  case 'C':
233
    what_to_do = DO_CHECK;
234
    opt_check_only_changed = 1;
235
    break;
236
  case 'I': /* Fall through */
237
  case '?':
238
    usage();
239
    exit(0);
240
  case 'm':
241
    what_to_do = DO_CHECK;
242
    opt_medium_check = 1;
243
    break;
244
  case 'o':
245
    what_to_do = DO_OPTIMIZE;
246
    break;
247
  case OPT_FIX_DB_NAMES:
248
    what_to_do= DO_UPGRADE;
249
    default_charset= (char*) "utf8";
250
    opt_databases= 1;
251
    break;
252
  case OPT_FIX_TABLE_NAMES:
253
    what_to_do= DO_UPGRADE;
254
    default_charset= (char*) "utf8";
255
    break;
256
  case 'p':
257
    if (argument)
258
    {
259
      char *start = argument;
656.1.51 by Monty Taylor
Fixed strdup return checking in client/
260
      if (opt_password)
261
        free(opt_password);
656.1.20 by Monty Taylor
Removed my_strdup, my_malloc, my_realloc from client/
262
      opt_password = strdup(argument);
656.1.51 by Monty Taylor
Fixed strdup return checking in client/
263
      if (opt_password == NULL)
264
      {
265
        fprintf(stderr, "Memory allocation error while copying password. "
266
                        "Aborting.\n");
267
        exit(ENOMEM);
268
      }
206.3.1 by Patrick Galbraith
Most everything working with client rename
269
      while (*argument) *argument++= 'x';    /* Destroy argument */
1 by brian
clean slate
270
      if (*start)
206.3.1 by Patrick Galbraith
Most everything working with client rename
271
  start[1] = 0;                             /* Cut length of argument */
1 by brian
clean slate
272
      tty_password= 0;
273
    }
274
    else
275
      tty_password = 1;
276
    break;
277
  case 'r':
278
    what_to_do = DO_REPAIR;
279
    break;
280
  case 'g':
281
    what_to_do= DO_CHECK;
282
    opt_upgrade= 1;
283
    break;
284
  case OPT_TABLES:
285
    opt_databases = 0;
286
    break;
287
  case 'v':
288
    verbose++;
289
    break;
290
  case 'V': print_version(); exit(0);
206.3.1 by Patrick Galbraith
Most everything working with client rename
291
  case OPT_DRIZZLE_PROTOCOL:
1 by brian
clean slate
292
    break;
293
  }
294
  return 0;
295
}
296
297
298
static int get_options(int *argc, char ***argv)
299
{
300
  int ho_error;
301
302
  if (*argc == 1)
303
  {
304
    usage();
305
    exit(0);
306
  }
307
520.4.28 by Monty Taylor
Changed my.cnf to drizzle.cnf and /etc/mysql to /etc/drizzle.
308
  load_defaults("drizzle", load_default_groups, argc, argv);
1 by brian
clean slate
309
310
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
311
    exit(ho_error);
312
313
  if (!what_to_do)
314
  {
315
    int pnlen = strlen(my_progname);
316
317
    if (pnlen < 6) /* name too short */
318
      what_to_do = DO_CHECK;
319
    else if (!strcmp("repair", my_progname + pnlen - 6))
320
      what_to_do = DO_REPAIR;
321
    else if (!strcmp("analyze", my_progname + pnlen - 7))
322
      what_to_do = DO_ANALYZE;
323
    else if  (!strcmp("optimize", my_progname + pnlen - 8))
324
      what_to_do = DO_OPTIMIZE;
325
    else
326
      what_to_do = DO_CHECK;
327
  }
328
329
  /* TODO: This variable is not yet used */
330
  if (strcmp(default_charset, charset_info->csname) &&
206.3.1 by Patrick Galbraith
Most everything working with client rename
331
      !(charset_info= get_charset_by_csname(default_charset,
332
                MY_CS_PRIMARY, MYF(MY_WME))))
1 by brian
clean slate
333
      exit(1);
334
  if (*argc > 0 && opt_alldbs)
335
  {
336
    printf("You should give only options, no arguments at all, with option\n");
337
    printf("--all-databases. Please see %s --help for more information.\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
338
     my_progname);
1 by brian
clean slate
339
    return 1;
340
  }
341
  if (*argc < 1 && !opt_alldbs)
342
  {
343
    printf("You forgot to give the arguments! Please see %s --help\n",
206.3.1 by Patrick Galbraith
Most everything working with client rename
344
     my_progname);
1 by brian
clean slate
345
    printf("for more information.\n");
346
    return 1;
347
  }
348
  if (tty_password)
461 by Monty Taylor
Removed NullS. bu-bye.
349
    opt_password = get_tty_password(NULL);
1 by brian
clean slate
350
  if (debug_info_flag)
351
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
352
  if (debug_check_flag)
353
    my_end_arg= MY_CHECK_ERROR;
354
  return(0);
355
} /* get_options */
356
357
358
static int process_all_databases()
359
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
360
  DRIZZLE_ROW row;
361
  DRIZZLE_RES *tableres;
1 by brian
clean slate
362
  int result = 0;
363
206.3.1 by Patrick Galbraith
Most everything working with client rename
364
  if (drizzle_query(sock, "SHOW DATABASES") ||
365
      !(tableres = drizzle_store_result(sock)))
1 by brian
clean slate
366
  {
367
    my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
206.3.1 by Patrick Galbraith
Most everything working with client rename
368
        MYF(0), drizzle_error(sock));
1 by brian
clean slate
369
    return 1;
370
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
371
  while ((row = drizzle_fetch_row(tableres)))
1 by brian
clean slate
372
  {
373
    if (process_one_db(row[0]))
374
      result = 1;
375
  }
376
  return result;
377
}
378
/* process_all_databases */
379
380
381
static int process_databases(char **db_names)
382
{
383
  int result = 0;
384
  for ( ; *db_names ; db_names++)
385
  {
386
    if (process_one_db(*db_names))
387
      result = 1;
388
  }
389
  return result;
390
} /* process_databases */
391
392
393
static int process_selected_tables(char *db, char **table_names, int tables)
394
{
395
  if (use_db(db))
396
    return 1;
397
  if (opt_all_in_1)
398
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
399
    /*
1 by brian
clean slate
400
      We need table list in form `a`, `b`, `c`
401
      that's why we need 2 more chars added to to each table name
402
      space is for more readable output in logs and in case of error
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
403
    */
1 by brian
clean slate
404
    char *table_names_comma_sep, *end;
405
    int i, tot_length = 0;
406
407
    for (i = 0; i < tables; i++)
408
      tot_length+= fixed_name_length(*(table_names + i)) + 2;
409
410
    if (!(table_names_comma_sep = (char *)
641.3.9 by Monty Taylor
More removal of my_malloc.
411
          malloc((sizeof(char) * tot_length) + 4)))
1 by brian
clean slate
412
      return 1;
413
414
    for (end = table_names_comma_sep + 1; tables > 0;
641.3.9 by Monty Taylor
More removal of my_malloc.
415
         tables--, table_names++)
1 by brian
clean slate
416
    {
417
      end= fix_table_name(end, *table_names);
418
      *end++= ',';
419
    }
420
    *--end = 0;
421
    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.
422
    free(table_names_comma_sep);
1 by brian
clean slate
423
  }
424
  else
425
    for (; tables > 0; tables--, table_names++)
426
      handle_request_for_tables(*table_names, fixed_name_length(*table_names));
427
  return 0;
428
} /* process_selected_tables */
429
430
431
static uint fixed_name_length(const char *name)
432
{
433
  const char *p;
434
  uint extra_length= 2;  /* count the first/last backticks */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
435
1 by brian
clean slate
436
  for (p= name; *p; p++)
437
  {
438
    if (*p == '`')
439
      extra_length++;
440
    else if (*p == '.')
441
      extra_length+= 2;
442
  }
443
  return (p - name) + extra_length;
444
}
445
446
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
447
static char *fix_table_name(char *dest, const char *src)
1 by brian
clean slate
448
{
449
  *dest++= '`';
450
  for (; *src; src++)
451
  {
452
    switch (*src) {
453
    case '.':            /* add backticks around '.' */
454
      *dest++= '`';
455
      *dest++= '.';
456
      *dest++= '`';
457
      break;
458
    case '`':            /* escape backtick character */
459
      *dest++= '`';
460
      /* fall through */
461
    default:
462
      *dest++= *src;
463
    }
464
  }
465
  *dest++= '`';
466
  return dest;
467
}
468
469
470
static int process_all_tables_in_db(char *database)
471
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
472
  DRIZZLE_RES *res;
473
  DRIZZLE_ROW row;
1 by brian
clean slate
474
  uint num_columns;
475
476
  if (use_db(database))
477
    return 1;
206.3.1 by Patrick Galbraith
Most everything working with client rename
478
  if (drizzle_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
479
  !((res= drizzle_store_result(sock))))
1 by brian
clean slate
480
    return 1;
481
206.3.1 by Patrick Galbraith
Most everything working with client rename
482
  num_columns= drizzle_num_fields(res);
1 by brian
clean slate
483
484
  if (opt_all_in_1)
485
  {
486
    /*
487
      We need table list in form `a`, `b`, `c`
488
      that's why we need 2 more chars added to to each table name
489
      space is for more readable output in logs and in case of error
490
     */
491
492
    char *tables, *end;
493
    uint tot_length = 0;
494
206.3.1 by Patrick Galbraith
Most everything working with client rename
495
    while ((row = drizzle_fetch_row(res)))
1 by brian
clean slate
496
      tot_length+= fixed_name_length(row[0]) + 2;
206.3.1 by Patrick Galbraith
Most everything working with client rename
497
    drizzle_data_seek(res, 0);
1 by brian
clean slate
498
641.3.9 by Monty Taylor
More removal of my_malloc.
499
    if (!(tables=(char *) malloc(sizeof(char)*tot_length+4)))
1 by brian
clean slate
500
    {
206.3.1 by Patrick Galbraith
Most everything working with client rename
501
      drizzle_free_result(res);
1 by brian
clean slate
502
      return 1;
503
    }
206.3.1 by Patrick Galbraith
Most everything working with client rename
504
    for (end = tables + 1; (row = drizzle_fetch_row(res)) ;)
1 by brian
clean slate
505
    {
506
      if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
507
        continue;
508
509
      end= fix_table_name(end, row[0]);
510
      *end++= ',';
511
    }
512
    *--end = 0;
513
    if (tot_length)
514
      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.
515
    free(tables);
1 by brian
clean slate
516
  }
517
  else
518
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
519
    while ((row = drizzle_fetch_row(res)))
1 by brian
clean slate
520
    {
521
      /* Skip views if we don't perform renaming. */
522
      if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
523
        continue;
524
525
      handle_request_for_tables(row[0], fixed_name_length(row[0]));
526
    }
527
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
528
  drizzle_free_result(res);
1 by brian
clean slate
529
  return 0;
530
} /* process_all_tables_in_db */
531
532
533
534
static int fix_table_storage_name(const char *name)
535
{
536
  char qbuf[100 + NAME_LEN*4];
537
  int rc= 0;
538
  if (strncmp(name, "#mysql50#", 9))
539
    return 1;
540
  sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
206.3.1 by Patrick Galbraith
Most everything working with client rename
541
  if (drizzle_query(sock, qbuf))
1 by brian
clean slate
542
  {
543
    fprintf(stderr, "Failed to %s\n", qbuf);
206.3.1 by Patrick Galbraith
Most everything working with client rename
544
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
1 by brian
clean slate
545
    rc= 1;
546
  }
547
  if (verbose)
548
    printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
549
  return rc;
550
}
551
552
static int fix_database_storage_name(const char *name)
553
{
554
  char qbuf[100 + NAME_LEN*4];
555
  int rc= 0;
556
  if (strncmp(name, "#mysql50#", 9))
557
    return 1;
558
  sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
206.3.1 by Patrick Galbraith
Most everything working with client rename
559
  if (drizzle_query(sock, qbuf))
1 by brian
clean slate
560
  {
561
    fprintf(stderr, "Failed to %s\n", qbuf);
206.3.1 by Patrick Galbraith
Most everything working with client rename
562
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
1 by brian
clean slate
563
    rc= 1;
564
  }
565
  if (verbose)
566
    printf("%-50s %s\n", name, rc ? "FAILED" : "OK");
567
  return rc;
568
}
569
570
static int process_one_db(char *database)
571
{
572
  if (what_to_do == DO_UPGRADE)
573
  {
574
    int rc= 0;
575
    if (opt_fix_db_names && !strncmp(database,"#mysql50#", 9))
576
    {
577
      rc= fix_database_storage_name(database);
578
      database+= 9;
579
    }
580
    if (rc || !opt_fix_table_names)
581
      return rc;
582
  }
583
  return process_all_tables_in_db(database);
584
}
585
586
587
static int use_db(char *database)
588
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
589
  if (drizzle_get_server_version(sock) >= 50003 &&
383.1.12 by Brian Aker
Much closer toward UTF8 being around all the time...
590
      !my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
1 by brian
clean slate
591
    return 1;
206.3.1 by Patrick Galbraith
Most everything working with client rename
592
  if (drizzle_select_db(sock, database))
1 by brian
clean slate
593
  {
594
    DBerror(sock, "when selecting the database");
595
    return 1;
596
  }
597
  return 0;
598
} /* use_db */
599
600
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
601
static int handle_request_for_tables(const char *tables, uint length)
1 by brian
clean slate
602
{
603
  char *query, *end, options[100], message[100];
604
  uint query_length= 0;
605
  const char *op = 0;
606
607
  options[0] = 0;
608
  end = options;
609
  switch (what_to_do) {
610
  case DO_CHECK:
611
    op = "CHECK";
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
612
    if (opt_quick)              end = strcpy(end, " QUICK")+6;
613
    if (opt_fast)               end = strcpy(end, " FAST")+5;
614
    if (opt_medium_check)       end = strcpy(end, " MEDIUM")+7; /* Default */
615
    if (opt_extended)           end = strcpy(end, " EXTENDED")+9;
616
    if (opt_check_only_changed) end = strcpy(end, " CHANGED")+8;
617
    if (opt_upgrade)            end = strcpy(end, " FOR UPGRADE")+12;
1 by brian
clean slate
618
    break;
619
  case DO_REPAIR:
620
    op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG";
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
621
    if (opt_quick)              end = strcpy(end, " QUICK")+6;
622
    if (opt_extended)           end = strcpy(end, " EXTENDED")+9;
623
    if (opt_frm)                end = strcpy(end, " USE_FRM")+8;
1 by brian
clean slate
624
    break;
625
  case DO_ANALYZE:
626
    op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
627
    break;
628
  case DO_OPTIMIZE:
629
    op= (opt_write_binlog) ? "OPTIMIZE" : "OPTIMIZE NO_WRITE_TO_BINLOG";
630
    break;
631
  case DO_UPGRADE:
632
    return fix_table_storage_name(tables);
633
  }
634
641.3.9 by Monty Taylor
More removal of my_malloc.
635
  if (!(query =(char *) malloc((sizeof(char)*(length+110)))))
1 by brian
clean slate
636
    return 1;
637
  if (opt_all_in_1)
638
  {
639
    /* No backticks here as we added them before */
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
640
    query_length= sprintf(query, "%s TABLE %s %s", op, tables, options);
1 by brian
clean slate
641
  }
642
  else
643
  {
644
    char *ptr;
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
645
    ptr= query;
646
    ptr= strcpy(query, op)+strlen(op);
647
    ptr= strcpy(ptr, " TABLE ")+7;
1 by brian
clean slate
648
    ptr= fix_table_name(ptr, tables);
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
649
    ptr+= sprintf(ptr," %s",options);
1 by brian
clean slate
650
    query_length= (uint) (ptr - query);
651
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
652
  if (drizzle_real_query(sock, query, query_length))
1 by brian
clean slate
653
  {
654
    sprintf(message, "when executing '%s TABLE ... %s'", op, options);
655
    DBerror(sock, message);
656
    return 1;
657
  }
658
  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.
659
  free(query);
1 by brian
clean slate
660
  return 0;
661
}
662
663
664
static void print_result()
665
{
206.3.1 by Patrick Galbraith
Most everything working with client rename
666
  DRIZZLE_RES *res;
667
  DRIZZLE_ROW row;
1 by brian
clean slate
668
  char prev[NAME_LEN*2+2];
669
  uint i;
143 by Brian Aker
Bool cleanup.
670
  bool found_error=0;
1 by brian
clean slate
671
206.3.1 by Patrick Galbraith
Most everything working with client rename
672
  res = drizzle_use_result(sock);
1 by brian
clean slate
673
674
  prev[0] = '\0';
206.3.1 by Patrick Galbraith
Most everything working with client rename
675
  for (i = 0; (row = drizzle_fetch_row(res)); i++)
1 by brian
clean slate
676
  {
677
    int changed = strcmp(prev, row[0]);
143 by Brian Aker
Bool cleanup.
678
    bool status = !strcmp(row[2], "status");
1 by brian
clean slate
679
680
    if (status)
681
    {
682
      /*
683
        if there was an error with the table, we have --auto-repair set,
684
        and this isn't a repair op, then add the table to the tables4repair
685
        list
686
      */
687
      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>
688
          strcmp(row[3],"OK"))
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
689
        tables4repair.push_back(string(prev));
1 by brian
clean slate
690
      found_error=0;
691
      if (opt_silent)
206.3.1 by Patrick Galbraith
Most everything working with client rename
692
  continue;
1 by brian
clean slate
693
    }
694
    if (status && changed)
695
      printf("%-50s %s", row[0], row[3]);
696
    else if (!status && changed)
697
    {
698
      printf("%s\n%-9s: %s", row[0], row[2], row[3]);
699
      if (strcmp(row[2],"note"))
206.3.1 by Patrick Galbraith
Most everything working with client rename
700
  found_error=1;
1 by brian
clean slate
701
    }
702
    else
703
      printf("%-9s: %s", row[2], row[3]);
641.4.2 by Toru Maesaka
Second pass of replacing MySQL's my_stpcpy() with appropriate libc calls
704
    strcpy(prev, row[0]);
1 by brian
clean slate
705
    putchar('\n');
706
  }
707
  /* add the last table to be repaired to the list */
708
  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
709
    tables4repair.push_back(string(prev));
206.3.1 by Patrick Galbraith
Most everything working with client rename
710
  drizzle_free_result(res);
1 by brian
clean slate
711
}
712
713
714
static int dbConnect(char *host, char *user, char *passwd)
715
{
142.1.2 by Patrick
All DBUG_x removed from client/
716
1 by brian
clean slate
717
  if (verbose)
718
  {
719
    fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
720
  }
202.2.4 by Monty Taylor
Merged from Patrick.
721
  drizzle_create(&drizzle_connection);
1 by brian
clean slate
722
  if (opt_compress)
461 by Monty Taylor
Removed NullS. bu-bye.
723
    drizzle_options(&drizzle_connection, DRIZZLE_OPT_COMPRESS, NULL);
1 by brian
clean slate
724
  if (opt_protocol)
206.3.1 by Patrick Galbraith
Most everything working with client rename
725
    drizzle_options(&drizzle_connection,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
726
  if (!(sock = drizzle_connect(&drizzle_connection, host, user, passwd,
1 by brian
clean slate
727
         NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
728
  {
206.3.1 by Patrick Galbraith
Most everything working with client rename
729
    DBerror(&drizzle_connection, "when trying to connect");
1 by brian
clean slate
730
    return 1;
731
  }
206.3.1 by Patrick Galbraith
Most everything working with client rename
732
  drizzle_connection.reconnect= 1;
1 by brian
clean slate
733
  return 0;
734
} /* dbConnect */
735
736
737
static void dbDisconnect(char *host)
738
{
739
  if (verbose)
740
    fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
206.3.1 by Patrick Galbraith
Most everything working with client rename
741
  drizzle_close(sock);
1 by brian
clean slate
742
} /* dbDisconnect */
743
744
206.3.1 by Patrick Galbraith
Most everything working with client rename
745
static void DBerror(DRIZZLE *drizzle, const char *when)
1 by brian
clean slate
746
{
747
  my_printf_error(0,"Got error: %d: %s %s", MYF(0),
206.3.1 by Patrick Galbraith
Most everything working with client rename
748
      drizzle_errno(drizzle), drizzle_error(drizzle), when);
1 by brian
clean slate
749
  safe_exit(EX_MYSQLERR);
142.1.2 by Patrick
All DBUG_x removed from client/
750
  return;
1 by brian
clean slate
751
} /* DBerror */
752
753
754
static void safe_exit(int error)
755
{
756
  if (!first_error)
757
    first_error= error;
758
  if (ignore_errors)
759
    return;
760
  if (sock)
206.3.1 by Patrick Galbraith
Most everything working with client rename
761
    drizzle_close(sock);
1 by brian
clean slate
762
  exit(error);
763
}
764
765
766
int main(int argc, char **argv)
767
{
768
  MY_INIT(argv[0]);
769
  /*
770
  ** Check out the args
771
  */
772
  if (get_options(&argc, &argv))
773
  {
774
    my_end(my_end_arg);
775
    exit(EX_USAGE);
776
  }
777
  if (dbConnect(current_host, current_user, opt_password))
778
    exit(EX_MYSQLERR);
779
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
780
  if (opt_auto_repair)
1 by brian
clean slate
781
  {
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
782
    tables4repair.reserve(64);
783
    if (tables4repair.capacity() == 0)
784
    {
785
      first_error = 1;
786
      goto end;
787
    }
1 by brian
clean slate
788
  }
789
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
790
1 by brian
clean slate
791
  if (opt_alldbs)
792
    process_all_databases();
793
  /* Only one database and selected table(s) */
794
  else if (argc > 1 && !opt_databases)
795
    process_selected_tables(*argv, (argv + 1), (argc - 1));
796
  /* One or more databases, all tables */
797
  else
798
    process_databases(argv);
799
  if (opt_auto_repair)
800
  {
801
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
802
    if (!opt_silent && (tables4repair.size() > 0))
1 by brian
clean slate
803
      puts("\nRepairing tables");
804
    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
805
    vector<string>::iterator i;
279.2.7 by Monty Taylor
Replaced DYNAMIC_ARRAY in drizzlecheck with vector<string>
806
    for ( i= tables4repair.begin() ; i < tables4repair.end() ; i++)
1 by brian
clean slate
807
    {
287.3.15 by Monty Taylor
Undid string->string* change. Re-read the vector destructor and the free-by-hand
808
      const char *name= (*i).c_str();
1 by brian
clean slate
809
      handle_request_for_tables(name, fixed_name_length(name));
810
    }
811
  }
812
 end:
813
  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.
814
  free(opt_password);
1 by brian
clean slate
815
  my_end(my_end_arg);
816
  return(first_error!=0);
817
} /* main */