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