~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzlecheck.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB
 
1
/* Copyright (C) 2008 Drizzle development team
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
 
16
/* By Jani Tolonen, 2001-04-20, MySQL, MYSQL Development Team */
17
17
 
18
18
#define CHECK_VERSION "2.5.0"
19
19
 
 
20
#include "config.h"
 
21
#include <vector>
 
22
#include <string>
20
23
#include "client_priv.h"
21
 
#include <m_ctype.h>
22
 
#include <mysql_version.h>
23
 
#include <mysqld_error.h>
24
 
 
 
24
#include <mystrings/m_ctype.h>
 
25
 
 
26
template class std::vector<std::string>;
 
27
 
 
28
using namespace std;
25
29
/* Exit codes */
26
30
 
27
31
#define EX_USAGE 1
28
32
#define EX_MYSQLERR 2
29
33
 
30
 
static MYSQL mysql_connection, *sock = 0;
31
 
static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
 
34
static DRIZZLE drizzle_connection, *sock = 0;
 
35
static bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
32
36
               opt_compress = 0, opt_databases = 0, opt_fast = 0,
33
37
               opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
34
38
               opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
38
42
static uint verbose = 0, opt_mysql_port=0;
39
43
static int my_end_arg;
40
44
static char * opt_mysql_unix_port = 0;
41
 
static char *opt_password = 0, *current_user = 0, 
42
 
            *default_charset = (char *)MYSQL_DEFAULT_CHARSET_NAME,
43
 
            *current_host = 0;
 
45
static char *opt_password = 0, *current_user = 0,
 
46
      *default_charset = (char *)DRIZZLE_DEFAULT_CHARSET_NAME,
 
47
      *current_host = 0;
44
48
static int first_error = 0;
45
 
DYNAMIC_ARRAY tables4repair;
46
 
#ifdef HAVE_SMEM
47
 
static char *shared_memory_base_name=0;
48
 
#endif
 
49
vector<string> tables4repair;
49
50
static uint opt_protocol=0;
50
 
static CHARSET_INFO *charset_info= &my_charset_latin1;
 
51
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
51
52
 
52
53
enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
53
54
 
55
56
{
56
57
  {"all-databases", 'A',
57
58
   "Check all the databases. This will be same as  --databases with all databases selected.",
58
 
   (uchar**) &opt_alldbs, (uchar**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
59
   (char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
59
60
   0, 0},
60
61
  {"analyze", 'a', "Analyze given tables.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
61
62
   0, 0, 0, 0},
62
63
  {"all-in-1", '1',
63
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.",
64
 
   (uchar**) &opt_all_in_1, (uchar**) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
65
   (char**) &opt_all_in_1, (char**) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
65
66
   0, 0, 0},
66
67
  {"auto-repair", OPT_AUTO_REPAIR,
67
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.",
68
 
   (uchar**) &opt_auto_repair, (uchar**) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
 
69
   (char**) &opt_auto_repair, (char**) &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
69
70
   0, 0, 0, 0, 0},
70
71
  {"character-sets-dir", OPT_CHARSETS_DIR,
71
 
   "Directory where character sets are.", (uchar**) &charsets_dir,
72
 
   (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
72
   "Directory where character sets are.", (char**) &charsets_dir,
 
73
   (char**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
73
74
  {"check", 'c', "Check table for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
74
75
   0, 0, 0, 0},
75
76
  {"check-only-changed", 'C',
79
80
   "Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.",
80
81
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
81
82
  {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
82
 
   (uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
83
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
83
84
   0, 0, 0},
84
85
  {"databases", 'B',
85
86
   "To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames.",
86
 
   (uchar**) &opt_databases, (uchar**) &opt_databases, 0, GET_BOOL, NO_ARG,
 
87
   (char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG,
87
88
   0, 0, 0, 0, 0, 0},
88
 
#ifdef DBUG_OFF
89
 
  {"debug", '#', "This is a non-debug version. Catch this and exit.",
90
 
   0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
91
 
#else
92
 
  {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
93
 
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
94
 
#endif
95
89
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
96
 
   (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
 
90
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
97
91
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
98
92
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
99
 
   (uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
 
93
   (char**) &debug_info_flag, (char**) &debug_info_flag,
100
94
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
101
95
  {"default-character-set", OPT_DEFAULT_CHARSET,
102
 
   "Set the default character set.", (uchar**) &default_charset,
103
 
   (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
96
   "Set the default character set.", (char**) &default_charset,
 
97
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
104
98
  {"fast",'F', "Check only tables that haven't been closed properly.",
105
 
   (uchar**) &opt_fast, (uchar**) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
99
   (char**) &opt_fast, (char**) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
106
100
   0},
107
101
  {"fix-db-names", OPT_FIX_DB_NAMES, "Fix database names.",
108
 
    (uchar**) &opt_fix_db_names, (uchar**) &opt_fix_db_names,
 
102
    (char**) &opt_fix_db_names, (char**) &opt_fix_db_names,
109
103
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
110
104
  {"fix-table-names", OPT_FIX_TABLE_NAMES, "Fix table names.",
111
 
    (uchar**) &opt_fix_table_names, (uchar**) &opt_fix_table_names,
 
105
    (char**) &opt_fix_table_names, (char**) &opt_fix_table_names,
112
106
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
113
107
  {"force", 'f', "Continue even if we get an sql-error.",
114
 
   (uchar**) &ignore_errors, (uchar**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
 
108
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
115
109
   0, 0, 0, 0},
116
110
  {"extended", 'e',
117
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.",
118
 
   (uchar**) &opt_extended, (uchar**) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
112
   (char**) &opt_extended, (char**) &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
119
113
   0, 0, 0},
120
114
  {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
121
115
   NO_ARG, 0, 0, 0, 0, 0, 0},
122
 
  {"host",'h', "Connect to host.", (uchar**) &current_host,
123
 
   (uchar**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
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},
124
118
  {"medium-check", 'm',
125
119
   "Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.",
126
120
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
127
121
  {"write-binlog", OPT_WRITE_BINLOG,
128
122
   "Log ANALYZE, OPTIMIZE and REPAIR TABLE commands. Use --skip-write-binlog when commands should not be sent to replication slaves.",
129
 
   (uchar**) &opt_write_binlog, (uchar**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
 
123
   (char**) &opt_write_binlog, (char**) &opt_write_binlog, 0, GET_BOOL, NO_ARG,
130
124
   1, 0, 0, 0, 0, 0},
131
125
  {"optimize", 'o', "Optimize table.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
132
126
   0, 0},
134
128
   "Password to use when connecting to server. If password is not given it's solicited on the tty.",
135
129
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
136
130
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
137
 
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
138
 
#if MYSQL_PORT_DEFAULT == 0
139
 
   "/etc/services, "
140
 
#endif
141
 
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
142
 
   (uchar**) &opt_mysql_port,
143
 
   (uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
 
131
   "order of preference, my.cnf, $DRIZZLE_TCP_PORT, "
 
132
   "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
133
   (char**) &opt_mysql_port,
 
134
   (char**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
144
135
   0},
145
 
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
136
  {"protocol", OPT_DRIZZLE_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
146
137
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
147
138
  {"quick", 'q',
148
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.",
149
 
   (uchar**) &opt_quick, (uchar**) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
140
   (char**) &opt_quick, (char**) &opt_quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
150
141
   0},
151
142
  {"repair", 'r',
152
143
   "Can fix almost anything except unique keys that aren't unique.",
153
144
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
154
 
#ifdef HAVE_SMEM
155
 
  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
156
 
   "Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
157
 
   0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
158
 
#endif
159
 
  {"silent", 's', "Print only error messages.", (uchar**) &opt_silent,
160
 
   (uchar**) &opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
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},
161
147
  {"socket", 'S', "Socket file to use for connection.",
162
 
   (uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
 
148
   (char**) &opt_mysql_unix_port, (char**) &opt_mysql_unix_port, 0, GET_STR,
163
149
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
164
150
  {"tables", OPT_TABLES, "Overrides option --databases (-B).", 0, 0, 0,
165
151
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
166
152
  {"use-frm", OPT_FRM,
167
153
   "When used with REPAIR, get table structure from .frm file, so the table can be repaired even if .MYI header is corrupted.",
168
 
   (uchar**) &opt_frm, (uchar**) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
154
   (char**) &opt_frm, (char**) &opt_frm, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
169
155
   0},
170
156
#ifndef DONT_ALLOW_USER_CHANGE
171
 
  {"user", 'u', "User for login if not current user.", (uchar**) &current_user,
172
 
   (uchar**) &current_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
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},
173
159
#endif
174
160
  {"verbose", 'v', "Print info about the various stages.", 0, 0, 0, GET_NO_ARG,
175
161
   NO_ARG, 0, 0, 0, 0, 0, 0},
184
170
static void print_version(void);
185
171
static void usage(void);
186
172
static int get_options(int *argc, char ***argv);
187
 
static int process_all_databases();
 
173
static int process_all_databases(void);
188
174
static int process_databases(char **db_names);
189
175
static int process_selected_tables(char *db, char **table_names, int tables);
190
176
static int process_all_tables_in_db(char *database);
191
177
static int process_one_db(char *database);
192
178
static int use_db(char *database);
193
 
static int handle_request_for_tables(char *tables, uint length);
 
179
static int handle_request_for_tables(const char *tables, uint length);
194
180
static int dbConnect(char *host, char *user,char *passwd);
195
181
static void dbDisconnect(char *host);
196
 
static void DBerror(MYSQL *mysql, const char *when);
 
182
static void DBerror(DRIZZLE *drizzle, const char *when);
197
183
static void safe_exit(int error);
198
 
static void print_result();
 
184
static void print_result(void);
199
185
static uint fixed_name_length(const char *name);
200
 
static char *fix_table_name(char *dest, char *src);
 
186
static char *fix_table_name(char *dest, const char *src);
201
187
int what_to_do = 0;
202
188
 
203
 
#include <help_start.h>
204
 
 
205
189
static void print_version(void)
206
190
{
207
191
  printf("%s  Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
208
 
   MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
 
192
   drizzle_get_client_info(), SYSTEM_TYPE, MACHINE_TYPE);
209
193
} /* print_version */
210
194
 
211
 
 
212
195
static void usage(void)
213
196
{
214
197
  print_version();
218
201
  puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
219
202
  puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
220
203
  puts("used at the same time. Not all options are supported by all storage engines.");
221
 
  puts("Please consult the MySQL manual for latest information about the");
 
204
  puts("Please consult the Drizzle manual for latest information about the");
222
205
  puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
223
206
  puts("means that the last option will be used, if several was specified.\n");
224
207
  puts("The option -c will be used by default, if none was specified. You");
229
212
  puts("mysqloptimize: The default option will be -o\n");
230
213
  printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
231
214
  printf("OR     %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
232
 
         my_progname);
 
215
   my_progname);
233
216
  printf("OR     %s [OPTIONS] --all-databases\n", my_progname);
234
217
  print_defaults("my", load_default_groups);
235
218
  my_print_help(my_long_options);
236
219
  my_print_variables(my_long_options);
237
220
} /* usage */
238
221
 
239
 
#include <help_end.h>
240
 
 
241
 
static my_bool
 
222
static bool
242
223
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
243
 
               char *argument)
 
224
         char *argument)
244
225
{
245
226
  switch(optid) {
246
227
  case 'a':
277
258
    if (argument)
278
259
    {
279
260
      char *start = argument;
280
 
      my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
 
261
      free(opt_password);
281
262
      opt_password = my_strdup(argument, MYF(MY_FAE));
282
 
      while (*argument) *argument++= 'x';               /* Destroy argument */
 
263
      while (*argument) *argument++= 'x';    /* Destroy argument */
283
264
      if (*start)
284
 
        start[1] = 0;                             /* Cut length of argument */
 
265
  start[1] = 0;                             /* Cut length of argument */
285
266
      tty_password= 0;
286
267
    }
287
268
    else
294
275
    what_to_do= DO_CHECK;
295
276
    opt_upgrade= 1;
296
277
    break;
297
 
  case '#':
298
 
    DBUG_PUSH(argument ? argument : "d:t:o");
299
 
    debug_check_flag= 1;
300
 
    break;
301
278
  case OPT_TABLES:
302
279
    opt_databases = 0;
303
280
    break;
305
282
    verbose++;
306
283
    break;
307
284
  case 'V': print_version(); exit(0);
308
 
  case OPT_MYSQL_PROTOCOL:
309
 
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
310
 
                                    opt->name);
 
285
  case OPT_DRIZZLE_PROTOCOL:
311
286
    break;
312
287
  }
313
288
  return 0;
347
322
 
348
323
  /* TODO: This variable is not yet used */
349
324
  if (strcmp(default_charset, charset_info->csname) &&
350
 
      !(charset_info= get_charset_by_csname(default_charset, 
351
 
                                            MY_CS_PRIMARY, MYF(MY_WME))))
 
325
      !(charset_info= get_charset_by_csname(default_charset,
 
326
                MY_CS_PRIMARY, MYF(MY_WME))))
352
327
      exit(1);
353
328
  if (*argc > 0 && opt_alldbs)
354
329
  {
355
330
    printf("You should give only options, no arguments at all, with option\n");
356
331
    printf("--all-databases. Please see %s --help for more information.\n",
357
 
           my_progname);
 
332
     my_progname);
358
333
    return 1;
359
334
  }
360
335
  if (*argc < 1 && !opt_alldbs)
361
336
  {
362
337
    printf("You forgot to give the arguments! Please see %s --help\n",
363
 
           my_progname);
 
338
     my_progname);
364
339
    printf("for more information.\n");
365
340
    return 1;
366
341
  }
367
342
  if (tty_password)
368
 
    opt_password = get_tty_password(NullS);
 
343
    opt_password = get_tty_password(NULL);
369
344
  if (debug_info_flag)
370
345
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
371
346
  if (debug_check_flag)
376
351
 
377
352
static int process_all_databases()
378
353
{
379
 
  MYSQL_ROW row;
380
 
  MYSQL_RES *tableres;
 
354
  DRIZZLE_ROW row;
 
355
  DRIZZLE_RES *tableres;
381
356
  int result = 0;
382
357
 
383
 
  if (mysql_query(sock, "SHOW DATABASES") ||
384
 
      !(tableres = mysql_store_result(sock)))
 
358
  if (drizzle_query(sock, "SHOW DATABASES") ||
 
359
      !(tableres = drizzle_store_result(sock)))
385
360
  {
386
361
    my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
387
 
                    MYF(0), mysql_error(sock));
 
362
        MYF(0), drizzle_error(sock));
388
363
    return 1;
389
364
  }
390
 
  while ((row = mysql_fetch_row(tableres)))
 
365
  while ((row = drizzle_fetch_row(tableres)))
391
366
  {
392
367
    if (process_one_db(row[0]))
393
368
      result = 1;
415
390
    return 1;
416
391
  if (opt_all_in_1)
417
392
  {
418
 
    /* 
 
393
    /*
419
394
      We need table list in form `a`, `b`, `c`
420
395
      that's why we need 2 more chars added to to each table name
421
396
      space is for more readable output in logs and in case of error
422
 
    */    
 
397
    */   
423
398
    char *table_names_comma_sep, *end;
424
399
    int i, tot_length = 0;
425
400
 
427
402
      tot_length+= fixed_name_length(*(table_names + i)) + 2;
428
403
 
429
404
    if (!(table_names_comma_sep = (char *)
430
 
          my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
 
405
    my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
431
406
      return 1;
432
407
 
433
408
    for (end = table_names_comma_sep + 1; tables > 0;
434
 
         tables--, table_names++)
 
409
   tables--, table_names++)
435
410
    {
436
411
      end= fix_table_name(end, *table_names);
437
412
      *end++= ',';
438
413
    }
439
414
    *--end = 0;
440
415
    handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
441
 
    my_free(table_names_comma_sep, MYF(0));
 
416
    free(table_names_comma_sep);
442
417
  }
443
418
  else
444
419
    for (; tables > 0; tables--, table_names++)
451
426
{
452
427
  const char *p;
453
428
  uint extra_length= 2;  /* count the first/last backticks */
454
 
  
 
429
 
455
430
  for (p= name; *p; p++)
456
431
  {
457
432
    if (*p == '`')
463
438
}
464
439
 
465
440
 
466
 
static char *fix_table_name(char *dest, char *src)
 
441
static char *fix_table_name(char *dest, const char *src)
467
442
{
468
443
  *dest++= '`';
469
444
  for (; *src; src++)
488
463
 
489
464
static int process_all_tables_in_db(char *database)
490
465
{
491
 
  MYSQL_RES *res;
492
 
  MYSQL_ROW row;
 
466
  DRIZZLE_RES *res;
 
467
  DRIZZLE_ROW row;
493
468
  uint num_columns;
494
469
 
495
470
  if (use_db(database))
496
471
    return 1;
497
 
  if (mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
498
 
        !((res= mysql_store_result(sock))))
 
472
  if (drizzle_query(sock, "SHOW /*!50002 FULL*/ TABLES") ||
 
473
  !((res= drizzle_store_result(sock))))
499
474
    return 1;
500
475
 
501
 
  num_columns= mysql_num_fields(res);
 
476
  num_columns= drizzle_num_fields(res);
502
477
 
503
478
  if (opt_all_in_1)
504
479
  {
511
486
    char *tables, *end;
512
487
    uint tot_length = 0;
513
488
 
514
 
    while ((row = mysql_fetch_row(res)))
 
489
    while ((row = drizzle_fetch_row(res)))
515
490
      tot_length+= fixed_name_length(row[0]) + 2;
516
 
    mysql_data_seek(res, 0);
 
491
    drizzle_data_seek(res, 0);
517
492
 
518
493
    if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
519
494
    {
520
 
      mysql_free_result(res);
 
495
      drizzle_free_result(res);
521
496
      return 1;
522
497
    }
523
 
    for (end = tables + 1; (row = mysql_fetch_row(res)) ;)
 
498
    for (end = tables + 1; (row = drizzle_fetch_row(res)) ;)
524
499
    {
525
500
      if ((num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
526
501
        continue;
531
506
    *--end = 0;
532
507
    if (tot_length)
533
508
      handle_request_for_tables(tables + 1, tot_length - 1);
534
 
    my_free(tables, MYF(0));
 
509
    free(tables);
535
510
  }
536
511
  else
537
512
  {
538
 
    while ((row = mysql_fetch_row(res)))
 
513
    while ((row = drizzle_fetch_row(res)))
539
514
    {
540
515
      /* Skip views if we don't perform renaming. */
541
516
      if ((what_to_do != DO_UPGRADE) && (num_columns == 2) && (strcmp(row[1], "VIEW") == 0))
544
519
      handle_request_for_tables(row[0], fixed_name_length(row[0]));
545
520
    }
546
521
  }
547
 
  mysql_free_result(res);
 
522
  drizzle_free_result(res);
548
523
  return 0;
549
524
} /* process_all_tables_in_db */
550
525
 
557
532
  if (strncmp(name, "#mysql50#", 9))
558
533
    return 1;
559
534
  sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9);
560
 
  if (mysql_query(sock, qbuf))
 
535
  if (drizzle_query(sock, qbuf))
561
536
  {
562
537
    fprintf(stderr, "Failed to %s\n", qbuf);
563
 
    fprintf(stderr, "Error: %s\n", mysql_error(sock));
 
538
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
564
539
    rc= 1;
565
540
  }
566
541
  if (verbose)
575
550
  if (strncmp(name, "#mysql50#", 9))
576
551
    return 1;
577
552
  sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name);
578
 
  if (mysql_query(sock, qbuf))
 
553
  if (drizzle_query(sock, qbuf))
579
554
  {
580
555
    fprintf(stderr, "Failed to %s\n", qbuf);
581
 
    fprintf(stderr, "Error: %s\n", mysql_error(sock));
 
556
    fprintf(stderr, "Error: %s\n", drizzle_error(sock));
582
557
    rc= 1;
583
558
  }
584
559
  if (verbose)
605
580
 
606
581
static int use_db(char *database)
607
582
{
608
 
  if (mysql_get_server_version(sock) >= 50003 &&
609
 
      !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
 
583
  if (drizzle_get_server_version(sock) >= 50003 &&
 
584
      !my_strcasecmp(&my_charset_utf8_general_ci, database, "information_schema"))
610
585
    return 1;
611
 
  if (mysql_select_db(sock, database))
 
586
  if (drizzle_select_db(sock, database))
612
587
  {
613
588
    DBerror(sock, "when selecting the database");
614
589
    return 1;
617
592
} /* use_db */
618
593
 
619
594
 
620
 
static int handle_request_for_tables(char *tables, uint length)
 
595
static int handle_request_for_tables(const char *tables, uint length)
621
596
{
622
597
  char *query, *end, options[100], message[100];
623
598
  uint query_length= 0;
628
603
  switch (what_to_do) {
629
604
  case DO_CHECK:
630
605
    op = "CHECK";
631
 
    if (opt_quick)              end = strmov(end, " QUICK");
632
 
    if (opt_fast)               end = strmov(end, " FAST");
633
 
    if (opt_medium_check)       end = strmov(end, " MEDIUM"); /* Default */
634
 
    if (opt_extended)           end = strmov(end, " EXTENDED");
635
 
    if (opt_check_only_changed) end = strmov(end, " CHANGED");
636
 
    if (opt_upgrade)            end = strmov(end, " FOR UPGRADE");
 
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");
637
612
    break;
638
613
  case DO_REPAIR:
639
614
    op= (opt_write_binlog) ? "REPAIR" : "REPAIR NO_WRITE_TO_BINLOG";
640
 
    if (opt_quick)              end = strmov(end, " QUICK");
641
 
    if (opt_extended)           end = strmov(end, " EXTENDED");
642
 
    if (opt_frm)                end = strmov(end, " USE_FRM");
 
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");
643
618
    break;
644
619
  case DO_ANALYZE:
645
620
    op= (opt_write_binlog) ? "ANALYZE" : "ANALYZE NO_WRITE_TO_BINLOG";
656
631
  if (opt_all_in_1)
657
632
  {
658
633
    /* No backticks here as we added them before */
659
 
    query_length= my_sprintf(query,
660
 
                             (query, "%s TABLE %s %s", op, tables, options));
 
634
    query_length= sprintf(query, "%s TABLE %s %s", op, tables, options);
661
635
  }
662
636
  else
663
637
  {
664
638
    char *ptr;
665
639
 
666
 
    ptr= strmov(strmov(query, op), " TABLE ");
 
640
    ptr= my_stpcpy(my_stpcpy(query, op), " TABLE ");
667
641
    ptr= fix_table_name(ptr, tables);
668
 
    ptr= strxmov(ptr, " ", options, NullS);
 
642
    ptr= strxmov(ptr, " ", options, NULL);
669
643
    query_length= (uint) (ptr - query);
670
644
  }
671
 
  if (mysql_real_query(sock, query, query_length))
 
645
  if (drizzle_real_query(sock, query, query_length))
672
646
  {
673
647
    sprintf(message, "when executing '%s TABLE ... %s'", op, options);
674
648
    DBerror(sock, message);
675
649
    return 1;
676
650
  }
677
651
  print_result();
678
 
  my_free(query, MYF(0));
 
652
  free(query);
679
653
  return 0;
680
654
}
681
655
 
682
656
 
683
657
static void print_result()
684
658
{
685
 
  MYSQL_RES *res;
686
 
  MYSQL_ROW row;
 
659
  DRIZZLE_RES *res;
 
660
  DRIZZLE_ROW row;
687
661
  char prev[NAME_LEN*2+2];
688
662
  uint i;
689
 
  my_bool found_error=0;
 
663
  bool found_error=0;
690
664
 
691
 
  res = mysql_use_result(sock);
 
665
  res = drizzle_use_result(sock);
692
666
 
693
667
  prev[0] = '\0';
694
 
  for (i = 0; (row = mysql_fetch_row(res)); i++)
 
668
  for (i = 0; (row = drizzle_fetch_row(res)); i++)
695
669
  {
696
670
    int changed = strcmp(prev, row[0]);
697
 
    my_bool status = !strcmp(row[2], "status");
 
671
    bool status = !strcmp(row[2], "status");
698
672
 
699
673
    if (status)
700
674
    {
704
678
        list
705
679
      */
706
680
      if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
707
 
          strcmp(row[3],"OK"))
708
 
        insert_dynamic(&tables4repair, (uchar*) prev);
 
681
          strcmp(row[3],"OK"))
 
682
        tables4repair.push_back(string(prev));
709
683
      found_error=0;
710
684
      if (opt_silent)
711
 
        continue;
 
685
  continue;
712
686
    }
713
687
    if (status && changed)
714
688
      printf("%-50s %s", row[0], row[3]);
716
690
    {
717
691
      printf("%s\n%-9s: %s", row[0], row[2], row[3]);
718
692
      if (strcmp(row[2],"note"))
719
 
        found_error=1;
 
693
  found_error=1;
720
694
    }
721
695
    else
722
696
      printf("%-9s: %s", row[2], row[3]);
723
 
    strmov(prev, row[0]);
 
697
    my_stpcpy(prev, row[0]);
724
698
    putchar('\n');
725
699
  }
726
700
  /* add the last table to be repaired to the list */
727
701
  if (found_error && opt_auto_repair && what_to_do != DO_REPAIR)
728
 
    insert_dynamic(&tables4repair, (uchar*) prev);
729
 
  mysql_free_result(res);
 
702
    tables4repair.push_back(string(prev));
 
703
  drizzle_free_result(res);
730
704
}
731
705
 
732
706
 
733
707
static int dbConnect(char *host, char *user, char *passwd)
734
708
{
735
 
  DBUG_ENTER("dbConnect");
 
709
 
736
710
  if (verbose)
737
711
  {
738
712
    fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
739
713
  }
740
 
  mysql_init(&mysql_connection);
 
714
  drizzle_create(&drizzle_connection);
741
715
  if (opt_compress)
742
 
    mysql_options(&mysql_connection, MYSQL_OPT_COMPRESS, NullS);
743
 
#ifdef HAVE_OPENSSL
744
 
  if (opt_use_ssl)
745
 
    mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
746
 
                  opt_ssl_capath, opt_ssl_cipher);
747
 
#endif
 
716
    drizzle_options(&drizzle_connection, DRIZZLE_OPT_COMPRESS, NULL);
748
717
  if (opt_protocol)
749
 
    mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
750
 
#ifdef HAVE_SMEM
751
 
  if (shared_memory_base_name)
752
 
    mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
753
 
#endif
754
 
  if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
 
718
    drizzle_options(&drizzle_connection,DRIZZLE_OPT_PROTOCOL,(char*)&opt_protocol);
 
719
  if (!(sock = drizzle_connect(&drizzle_connection, host, user, passwd,
755
720
         NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
756
721
  {
757
 
    DBerror(&mysql_connection, "when trying to connect");
 
722
    DBerror(&drizzle_connection, "when trying to connect");
758
723
    return 1;
759
724
  }
760
 
  mysql_connection.reconnect= 1;
 
725
  drizzle_connection.reconnect= 1;
761
726
  return 0;
762
727
} /* dbConnect */
763
728
 
766
731
{
767
732
  if (verbose)
768
733
    fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
769
 
  mysql_close(sock);
 
734
  drizzle_close(sock);
770
735
} /* dbDisconnect */
771
736
 
772
737
 
773
 
static void DBerror(MYSQL *mysql, const char *when)
 
738
static void DBerror(DRIZZLE *drizzle, const char *when)
774
739
{
775
 
  DBUG_ENTER("DBerror");
776
740
  my_printf_error(0,"Got error: %d: %s %s", MYF(0),
777
 
                  mysql_errno(mysql), mysql_error(mysql), when);
 
741
      drizzle_errno(drizzle), drizzle_error(drizzle), when);
778
742
  safe_exit(EX_MYSQLERR);
779
 
  DBUG_VOID_RETURN;
 
743
  return;
780
744
} /* DBerror */
781
745
 
782
746
 
787
751
  if (ignore_errors)
788
752
    return;
789
753
  if (sock)
790
 
    mysql_close(sock);
 
754
    drizzle_close(sock);
791
755
  exit(error);
792
756
}
793
757
 
806
770
  if (dbConnect(current_host, current_user, opt_password))
807
771
    exit(EX_MYSQLERR);
808
772
 
809
 
  if (opt_auto_repair &&
810
 
      my_init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
 
773
  if (opt_auto_repair)
811
774
  {
812
 
    first_error = 1;
813
 
    goto end;
 
775
    tables4repair.reserve(64);
 
776
    if (tables4repair.capacity() == 0)
 
777
    {
 
778
      first_error = 1;
 
779
      goto end;
 
780
    }
814
781
  }
815
782
 
 
783
 
816
784
  if (opt_alldbs)
817
785
    process_all_databases();
818
786
  /* Only one database and selected table(s) */
823
791
    process_databases(argv);
824
792
  if (opt_auto_repair)
825
793
  {
826
 
    uint i;
827
794
 
828
 
    if (!opt_silent && tables4repair.elements)
 
795
    if (!opt_silent && (tables4repair.size() > 0))
829
796
      puts("\nRepairing tables");
830
797
    what_to_do = DO_REPAIR;
831
 
    for (i = 0; i < tables4repair.elements ; i++)
 
798
    vector<string>::iterator i;
 
799
    for ( i= tables4repair.begin() ; i < tables4repair.end() ; i++)
832
800
    {
833
 
      char *name= (char*) dynamic_array_ptr(&tables4repair, i);
 
801
      const char *name= (*i).c_str();
834
802
      handle_request_for_tables(name, fixed_name_length(name));
835
803
    }
836
804
  }
837
805
 end:
838
806
  dbDisconnect(current_host);
839
 
  if (opt_auto_repair)
840
 
    delete_dynamic(&tables4repair);
841
 
  my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
842
 
#ifdef HAVE_SMEM
843
 
  my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
844
 
#endif
 
807
  free(opt_password);
845
808
  my_end(my_end_arg);
846
809
  return(first_error!=0);
847
810
} /* main */