summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorunknown <sasha@mysql.sashanet.com>2001-05-10 15:06:35 -0600
committerunknown <sasha@mysql.sashanet.com>2001-05-10 15:06:35 -0600
commit9192600eb7c52f2675a67548849409dec2364165 (patch)
tree32fd0eb2c34334b7806726cf2dc9f8a893ea6fc8 /client
parent9afb49f53cb7b8da7519f45f588a78b559013de3 (diff)
parentb59b5f4b6ec6bd5b0eb8cee832b6d4f51fa646fc (diff)
downloadmariadb-git-9192600eb7c52f2675a67548849409dec2364165.tar.gz
Merged with 3.23, needs further fix-up
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union acconfig.h: Auto merged acinclude.m4: Auto merged include/myisam.h: Auto merged mysql-test/mysql-test-run.sh: Auto merged BitKeeper/deleted/.del-ib_config.h.in~9e57db8504e55b7: Auto merged BitKeeper/deleted/.del-ib_config.h~7539e26ffc614439: Auto merged client/mysqltest.c: Auto merged sql/lex.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.h: Auto merged sql/sql_show.cc: Auto merged sql/table.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_class.h: Auto merged Docs/manual.texi: merged client/errmsg.c: merged configure.in: merged sql/mysqld.cc: merged sql/sql_select.cc: merged, needs manual fixing sql/sql_yacc.yy: merged, needs manual fixing
Diffstat (limited to 'client')
-rw-r--r--client/Makefile.am3
-rw-r--r--client/mysqladmin.c15
-rw-r--r--client/mysqlcheck.c685
-rw-r--r--client/mysqldump.c175
-rw-r--r--client/mysqltest.c3
5 files changed, 789 insertions, 92 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 77f6cb72ff1..24221dcab74 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -21,13 +21,14 @@ INCLUDES = -I$(srcdir)/../include \
-I..
LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la
-bin_PROGRAMS = mysql mysqladmin mysqlshow mysqldump mysqlimport mysqltest
+bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow mysqldump mysqlimport mysqltest
noinst_PROGRAMS = insert_test select_test thread_test
noinst_HEADERS = sql_string.h completion_hash.h my_readline.h
mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc
mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqladmin_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlshow_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index bda86c881e3..1e6bf3c5219 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -28,7 +28,7 @@
#include <my_pthread.h> /* because of signal() */
#endif
-#define ADMIN_VERSION "8.19"
+#define ADMIN_VERSION "8.20"
#define MAX_MYSQL_VAR 64
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
#define MAX_TRUNC_LENGTH 3
@@ -417,19 +417,13 @@ static my_bool execute_commands(MYSQL *mysql,int argc, char **argv)
}
case ADMIN_DROP:
{
- char buff[FN_REFLEN+20];
if (argc < 2)
{
my_printf_error(0,"Too few arguments to drop",MYF(ME_BELL));
return 1;
}
- sprintf(buff,"drop database `%.*s`",FN_REFLEN,argv[1]);
- if (mysql_query(mysql,buff))
- {
- my_printf_error(0,"DROP DATABASE failed; error: '%-.200s'",
- MYF(ME_BELL), mysql_error(mysql));
+ if (drop_db(mysql,argv[1]))
return 1;
- }
argc--; argv++;
break;
}
@@ -867,7 +861,8 @@ static int drop_db(MYSQL *mysql, const char *db)
{
puts("Dropping the database is potentially a very bad thing to do.");
puts("Any data stored in the database will be destroyed.\n");
- printf("Do you really want to drop the '%s' database [y/N]\n",db);
+ printf("Do you really want to drop the '%s' database [y/N] ",db);
+ fflush(stdout);
VOID(fgets(buf,sizeof(buf)-1,stdin));
if ((*buf != 'y') && (*buf != 'Y'))
{
@@ -878,7 +873,7 @@ static int drop_db(MYSQL *mysql, const char *db)
sprintf(name_buff,"drop database %.*s",FN_REFLEN,db);
if (mysql_query(mysql,name_buff))
{
- my_printf_error(0,"drop of '%s' failed;\nerror: '%s'",MYF(ME_BELL),
+ my_printf_error(0,"DROP DATABASE %s failed;\nerror: '%s'",MYF(ME_BELL),
db,mysql_error(mysql));
return 1;
}
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
new file mode 100644
index 00000000000..3d4d4597ef5
--- /dev/null
+++ b/client/mysqlcheck.c
@@ -0,0 +1,685 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
+
+#define CHECK_VERSION "1.01"
+
+#include <global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <m_ctype.h>
+
+#include "mysql.h"
+#include "mysql_version.h"
+#include "mysqld_error.h"
+#include <getopt.h>
+#include "sslopt-vars.h"
+
+#include <m_string.h>
+
+/* Exit codes */
+
+#define EX_USAGE 1
+#define EX_MYSQLERR 2
+
+static MYSQL mysql_connection, *sock = 0;
+static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
+ opt_compress = 0, opt_databases = 0, opt_fast = 0,
+ opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
+ opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0;
+static uint verbose = 0, opt_mysql_port=0;
+static my_string opt_mysql_unix_port = 0;
+static char *opt_password = 0, *current_user = 0, *default_charset = 0,
+ *current_host = 0;
+static int first_error = 0;
+DYNAMIC_ARRAY tables4repair;
+
+enum operations {DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE};
+
+enum options {OPT_CHARSETS_DIR=256, OPT_COMPRESS, OPT_DEFAULT_CHARSET,
+ OPT_TABLES, OPT_AUTO_REPAIR};
+
+static struct option long_options[] =
+{
+ {"all-databases", no_argument, 0, 'A'},
+ {"all-in-1", no_argument, 0, '1'},
+ {"auto-repair", no_argument, 0, OPT_AUTO_REPAIR},
+ {"analyze", no_argument, 0, 'a'},
+ {"character-sets-dir", required_argument, 0, OPT_CHARSETS_DIR},
+ {"check", no_argument, 0, 'c'},
+ {"check-only-changed", no_argument, 0, 'C'},
+ {"compress", no_argument, 0, OPT_COMPRESS},
+ {"databases", no_argument, 0, 'B'},
+ {"debug", optional_argument, 0, '#'},
+ {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
+ {"fast", no_argument, 0, 'F'},
+ {"force", no_argument, 0, 'f'},
+ {"extended", no_argument, 0, 'e'},
+ {"help", no_argument, 0, '?'},
+ {"host", required_argument, 0, 'h'},
+ {"medium-check", no_argument, 0, 'm'},
+ {"optimize", no_argument, 0, 'o'},
+ {"password", optional_argument, 0, 'p'},
+#ifdef __WIN__
+ {"pipe", no_argument, 0, 'W'},
+#endif
+ {"port", required_argument, 0, 'P'},
+ {"quick", no_argument, 0, 'q'},
+ {"repair", no_argument, 0, 'r'},
+ {"silent", no_argument, 0, 's'},
+ {"socket", required_argument, 0, 'S'},
+#include "sslopt-longopts.h"
+ {"tables", no_argument, 0, OPT_TABLES},
+#ifndef DONT_ALLOW_USER_CHANGE
+ {"user", required_argument, 0, 'u'},
+#endif
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0}
+};
+
+static const char *load_default_groups[] = { "mysqlcheck", "client", 0 };
+
+
+static void print_version(void);
+static void usage(void);
+static int get_options(int *argc, char ***argv);
+static int process_all_databases();
+static int process_databases(char **db_names);
+static int process_selected_tables(char *db, char **table_names, int tables);
+static int process_all_tables_in_db(char *database);
+static int use_db(char *database);
+static int handle_request_for_tables(char *tables, uint length);
+static int dbConnect(char *host, char *user,char *passwd);
+static void dbDisconnect(char *host);
+static void DBerror(MYSQL *mysql, const char *when);
+static void safe_exit(int error);
+static void print_result();
+int what_to_do = 0;
+
+static void print_version(void)
+{
+ printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, CHECK_VERSION,
+ MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+} /* print_version */
+
+
+static void usage(void)
+{
+ print_version();
+ puts("By Jani Tolonen, 2001-04-20, MySQL Development Team\n");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free");
+ puts("software and you are welcome to modify and redistribute it");
+ puts("under the GPL license.\n");
+ puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
+ puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
+ puts("used same time. It works on MyISAM and in some cases on BDB tables.");
+ puts("Please consult the MySQL manual for latest information about the");
+ puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
+ puts("means that the last option will be used, if several was specified.\n");
+ puts("The option -c will be used by default, if none was specified. You");
+ puts("can change the default behavior by making a symbolic link, or");
+ puts("copying this file somewhere with another name, the alternatives are:");
+ puts("mysqlrepair: The default option will be -r");
+ puts("mysqlanalyze: The default option will be -a");
+ puts("mysqloptimize: The default option will be -o\n");
+ printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
+ printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
+ my_progname);
+ printf("OR %s [OPTIONS] --all-databases\n", my_progname);
+ printf("\
+ -A, --all-databases Check all the databases. This will be same as\n\
+ --databases with all databases selected\n\
+ -1, --all-in-1 Instead of making one query for each table, execute\n\
+ all queries in 1 query separately for each database.\n\
+ Table names will be in a comma separeted list.\n\
+ -a, --analyze Analyze given tables.\n\
+ --auto-repair If a checked table is corrupted, automatically fix\n\
+ it. Repairing will be done after all tables have\n\
+ been checked, if corrupted ones were found.\n\
+ -#, --debug=... Output debug log. Often this is 'd:t:o,filename'\n\
+ --character-sets-dir=...\n\
+ Directory where character sets are\n\
+ -c, --check Check table for errors\n\
+ -C, --check-only-changed\n\
+ Check only tables that have changed since last check\n\
+ or haven't been closed properly.\n\
+ --compress Use compression in server/client protocol.\n\
+ -?, --help Display this help message and exit.\n\
+ -B, --databases To check several databases. Note the difference in\n\
+ usage; In this case no tables are given. All name\n\
+ arguments are regarded as databasenames.\n\
+ --default-character-set=...\n\
+ Set the default character set\n\
+ -F, --fast Check only tables that hasn't been closed properly\n\
+ -f, --force Continue even if we get an sql-error.\n\
+ -e, --extended If you are using this option with CHECK TABLE,\n\
+ it will ensure that the table is 100 percent\n\
+ consistent, but will take a long time.\n\n");
+printf("\
+ If you are using this option with REPAIR TABLE,\n\
+ it will run an extended repair on the table, which\n\
+ may not only take a long time to execute, but\n\
+ may produce a lot of garbage rows also!\n\
+ -h, --host=... Connect to host.\n\
+ -m, --medium-check Faster than extended-check, but only finds 99.99 percent\n\
+ of all errors. Should be good enough for most cases.\n\
+ -o, --optimize Optimize table\n\
+ -p, --password[=...] Password to use when connecting to server.\n\
+ If password is not given it's solicited on the tty.\n");
+#ifdef __WIN__
+ puts("-W, --pipe Use named pipes to connect to server");
+#endif
+ printf("\
+ -P, --port=... Port number to use for connection.\n\
+ -q, --quick If you are using this option with CHECK TABLE, it\n\
+ prevents the check from scanning the rows to check\n\
+ for wrong links. This is the fastest check.\n\n\
+ If you are using this option with REPAIR TABLE, it\n\
+ will try to repair only the index tree. This is\n\
+ the fastest repair method for a table.\n\
+ -r, --repair Can fix almost anything except unique keys that aren't\n\
+ unique.\n\
+ -s, --silent Print only error messages.\n\
+ -S, --socket=... Socket file to use for connection.\n\
+ --tables Overrides option --databases (-B).\n");
+#include "sslopt-usage.h"
+#ifndef DONT_ALLOW_USER_CHANGE
+ printf("\
+ -u, --user=# User for login if not current user.\n");
+#endif
+ printf("\
+ -v, --verbose Print info about the various stages.\n\
+ -V, --version Output version information and exit.\n");
+ print_defaults("my", load_default_groups);
+} /* usage */
+
+
+static int get_options(int *argc, char ***argv)
+{
+ int c, option_index;
+ my_bool tty_password = 0;
+
+ if (*argc == 1)
+ {
+ usage();
+ exit(0);
+ }
+
+ load_defaults("my", load_default_groups, argc, argv);
+ while ((c = getopt_long(*argc, *argv, "#::p::h:u:P:S:BaAcCdeFfmqorsvVw:?I1",
+ long_options, &option_index)) != EOF)
+ {
+ switch(c) {
+ case 'a':
+ what_to_do = DO_ANALYZE;
+ break;
+ case '1':
+ opt_all_in_1 = 1;
+ break;
+ case 'A':
+ opt_alldbs = 1;
+ break;
+ case OPT_AUTO_REPAIR:
+ opt_auto_repair = 1;
+ break;
+ case OPT_DEFAULT_CHARSET:
+ default_charset = optarg;
+ break;
+ case OPT_CHARSETS_DIR:
+ charsets_dir = optarg;
+ break;
+ case 'c':
+ what_to_do = DO_CHECK;
+ break;
+ case 'C':
+ what_to_do = DO_CHECK;
+ opt_check_only_changed = 1;
+ break;
+ case 'e':
+ opt_extended = 1;
+ break;
+ case OPT_COMPRESS:
+ opt_compress = 1;
+ break;
+ case 'B':
+ opt_databases = 1;
+ break;
+ case 'F':
+ opt_fast = 1;
+ break;
+ case 'f':
+ ignore_errors = 1;
+ break;
+ case 'I': /* Fall through */
+ case '?':
+ usage();
+ exit(0);
+ case 'h':
+ my_free(current_host, MYF(MY_ALLOW_ZERO_PTR));
+ current_host = my_strdup(optarg, MYF(MY_WME));
+ break;
+ case 'm':
+ what_to_do = DO_CHECK;
+ opt_medium_check = 1;
+ break;
+ case 'o':
+ what_to_do = DO_OPTIMIZE;
+ break;
+#ifndef DONT_ALLOW_USER_CHANGE
+ case 'u':
+ current_user = optarg;
+ break;
+#endif
+ case 'p':
+ if (optarg)
+ {
+ char *start = optarg;
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ opt_password = my_strdup(optarg, MYF(MY_FAE));
+ while (*optarg) *optarg++= 'x'; /* Destroy argument */
+ if (*start)
+ start[1] = 0; /* Cut length of argument */
+ }
+ else
+ tty_password = 1;
+ break;
+ case 'P':
+ opt_mysql_port = (unsigned int) atoi(optarg);
+ break;
+ case 'q':
+ opt_quick = 1;
+ break;
+ case 'r':
+ what_to_do = DO_REPAIR;
+ break;
+ case 'S':
+ opt_mysql_unix_port = optarg;
+ break;
+ case 's':
+ opt_silent = 1;
+ break;
+ case 'W':
+#ifdef __WIN__
+ opt_mysql_unix_port = MYSQL_NAMEDPIPE;
+#endif
+ break;
+ case '#':
+ DBUG_PUSH(optarg ? optarg : "d:t:o");
+ break;
+ case OPT_TABLES:
+ opt_databases = 0;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'V': print_version(); exit(0);
+ default:
+ fprintf(stderr, "%s: Illegal option character '%c'\n", my_progname,
+ opterr);
+#include "sslopt-case.h"
+ }
+ }
+ if (!what_to_do)
+ {
+ int pnlen = strlen(my_progname);
+
+ if (pnlen < 6) // name too short
+ what_to_do = DO_CHECK;
+ else if (!strcmp("repair", my_progname + pnlen - 6))
+ what_to_do = DO_REPAIR;
+ else if (!strcmp("analyze", my_progname + pnlen - 7))
+ what_to_do = DO_ANALYZE;
+ else if (!strcmp("optimize", my_progname + pnlen - 8))
+ what_to_do = DO_OPTIMIZE;
+ else
+ what_to_do = DO_CHECK;
+ }
+ if (default_charset)
+ {
+ if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
+ exit(1);
+ }
+ (*argc) -= optind;
+ (*argv) += optind;
+ if (*argc > 0 && opt_alldbs)
+ {
+ printf("You should give only options, no arguments at all, with option\n");
+ printf("--all-databases. Please see %s --help for more information.\n",
+ my_progname);
+ return 1;
+ }
+ if (*argc < 1 && !opt_alldbs)
+ {
+ printf("You forgot to give the arguments! Please see %s --help\n",
+ my_progname);
+ printf("for more information.\n");
+ return 1;
+ }
+ if (tty_password)
+ opt_password = get_tty_password(NullS);
+ return(0);
+} /* get_options */
+
+
+static int process_all_databases()
+{
+ MYSQL_ROW row;
+ MYSQL_RES *tableres;
+ int result = 0;
+
+ if (mysql_query(sock, "SHOW DATABASES") ||
+ !(tableres = mysql_store_result(sock)))
+ {
+ my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
+ MYF(0), mysql_error(sock));
+ return 1;
+ }
+ while ((row = mysql_fetch_row(tableres)))
+ {
+ if (process_all_tables_in_db(row[0]))
+ result = 1;
+ }
+ return result;
+}
+/* process_all_databases */
+
+
+static int process_databases(char **db_names)
+{
+ int result = 0;
+ for ( ; *db_names ; db_names++)
+ {
+ if (process_all_tables_in_db(*db_names))
+ result = 1;
+ }
+ return result;
+} /* process_databases */
+
+
+static int process_selected_tables(char *db, char **table_names, int tables)
+{
+ if (use_db(db))
+ return 1;
+ if (opt_all_in_1)
+ {
+ char *table_names_comma_sep, *end;
+ int i, tot_length = 0;
+
+ for (i = 0; i < tables; i++)
+ tot_length += strlen(*(table_names + i)) + 1;
+
+ if (!(table_names_comma_sep = (char *)
+ my_malloc((sizeof(char) * tot_length) + 1, MYF(MY_WME))))
+ return 1;
+
+ for (end = table_names_comma_sep + 1; tables > 0;
+ tables--, table_names++)
+ {
+ end = strmov(end, *table_names);
+ *end++= ',';
+ }
+ *--end = 0;
+ handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1);
+ my_free(table_names_comma_sep, MYF(0));
+ }
+ else
+ for (; tables > 0; tables--, table_names++)
+ handle_request_for_tables(*table_names, strlen(*table_names));
+ return 0;
+} /* process_selected_tables */
+
+
+static int process_all_tables_in_db(char *database)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ LINT_INIT(res);
+ if (use_db(database))
+ return 1;
+ if (!(mysql_query(sock, "SHOW TABLES") ||
+ (res = mysql_store_result(sock))))
+ return 1;
+
+ if (opt_all_in_1)
+ {
+ char *tables, *end;
+ uint tot_length = 0;
+
+ while ((row = mysql_fetch_row(res)))
+ tot_length += strlen(row[0]) + 1;
+ mysql_data_seek(res, 0);
+
+ if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+1, MYF(MY_WME))))
+ {
+ mysql_free_result(res);
+ return 1;
+ }
+ for (end = tables + 1; (row = mysql_fetch_row(res)) ;)
+ {
+ end = strmov(end, row[0]);
+ *end++= ',';
+ }
+ *--end = 0;
+ if (tot_length)
+ handle_request_for_tables(tables + 1, tot_length - 1);
+ my_free(tables, MYF(0));
+ }
+ else
+ {
+ while ((row = mysql_fetch_row(res)))
+ handle_request_for_tables(row[0], strlen(row[0]));
+ }
+ mysql_free_result(res);
+ return 0;
+} /* process_all_tables_in_db */
+
+
+static int use_db(char *database)
+{
+ if (mysql_select_db(sock, database))
+ {
+ DBerror(sock, "when selecting the database");
+ return 1;
+ }
+ return 0;
+} /* use_db */
+
+
+static int handle_request_for_tables(char *tables, uint length)
+{
+ char *query, *end, options[100];
+ const char *op = 0;
+
+ options[0] = 0;
+ switch (what_to_do) {
+ case DO_CHECK:
+ op = "CHECK";
+ end = options;
+ if (opt_quick) end = strmov(end, "QUICK");
+ if (opt_fast) end = strmov(end, "FAST");
+ if (opt_medium_check) end = strmov(end, "MEDIUM"); /* Default */
+ if (opt_extended) end = strmov(end, "EXTENDED");
+ if (opt_check_only_changed) end = strmov(end, "CHANGED");
+ break;
+ case DO_REPAIR:
+ op = "REPAIR";
+ end = options;
+ if (opt_quick) end = strmov(end, "QUICK");
+ if (opt_extended) end = strmov(end, "EXTENDED");
+ break;
+ case DO_ANALYZE:
+ op = "ANALYZE";
+ break;
+ case DO_OPTIMIZE:
+ op = "OPTIMIZE";
+ break;
+ }
+
+ if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
+ return 1;
+ sprintf(query, "%s TABLE %s %s", op, options, tables);
+ if (mysql_query(sock, query))
+ {
+ sprintf(options, "when executing '%s TABLE'", op);
+ DBerror(sock, options);
+ return 1;
+ }
+ print_result();
+ my_free(query, MYF(0));
+ return 0;
+}
+
+
+static void print_result()
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ char prev[NAME_LEN*2+2];
+ int i;
+
+ res = mysql_use_result(sock);
+ prev[0] = '\0';
+ for (i = 0; (row = mysql_fetch_row(res)); i++)
+ {
+ int changed = strcmp(prev, row[0]);
+ int status = !strcmp(row[2], "status");
+ if (opt_silent && status)
+ continue;
+ if (status && changed)
+ printf("%-50s %s", row[0], row[3]);
+ else if (!status && changed)
+ {
+ printf("%s\n%-9s: %s", row[0], row[2], row[3]);
+ if (what_to_do != DO_REPAIR && opt_auto_repair)
+ insert_dynamic(&tables4repair, row[0]);
+ }
+ else
+ printf("%-9s: %s", row[2], row[3]);
+ strmov(prev, row[0]);
+ putchar('\n');
+ }
+ mysql_free_result(res);
+}
+
+
+static int dbConnect(char *host, char *user, char *passwd)
+{
+ DBUG_ENTER("dbConnect");
+ if (verbose)
+ {
+ fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost");
+ }
+ mysql_init(&mysql_connection);
+ if (opt_compress)
+ mysql_options(&mysql_connection, MYSQL_OPT_COMPRESS, NullS);
+#ifdef HAVE_OPENSSL
+ if (opt_use_ssl)
+ mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+ opt_ssl_capath);
+#endif
+ if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
+ NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
+ {
+ DBerror(&mysql_connection, "when trying to connect");
+ return 1;
+ }
+ return 0;
+} /* dbConnect */
+
+
+static void dbDisconnect(char *host)
+{
+ if (verbose)
+ fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost");
+ mysql_close(sock);
+} /* dbDisconnect */
+
+
+static void DBerror(MYSQL *mysql, const char *when)
+{
+ DBUG_ENTER("DBerror");
+ my_printf_error(0,"Got error: %d: %s %s", MYF(0),
+ mysql_errno(mysql), mysql_error(mysql), when);
+ safe_exit(EX_MYSQLERR);
+ DBUG_VOID_RETURN;
+} /* DBerror */
+
+
+static void safe_exit(int error)
+{
+ if (!first_error)
+ first_error= error;
+ if (ignore_errors)
+ return;
+ if (sock)
+ mysql_close(sock);
+ exit(error);
+}
+
+
+int main(int argc, char **argv)
+{
+ MY_INIT(argv[0]);
+ /*
+ ** Check out the args
+ */
+ if (get_options(&argc, &argv))
+ {
+ my_end(0);
+ exit(EX_USAGE);
+ }
+ if (dbConnect(current_host, current_user, opt_password))
+ exit(EX_MYSQLERR);
+
+ if (opt_auto_repair &&
+ init_dynamic_array(&tables4repair, sizeof(char)*(NAME_LEN*2+2),16,64))
+ {
+ first_error = 1;
+ goto end;
+ }
+
+ if (opt_alldbs)
+ process_all_databases();
+ /* Only one database and selected table(s) */
+ else if (argc > 1 && !opt_databases)
+ process_selected_tables(*argv, (argv + 1), (argc - 1));
+ /* One or more databases, all tables */
+ else
+ process_databases(argv);
+ if (opt_auto_repair)
+ {
+ uint i;
+
+ if (!opt_silent && tables4repair.elements)
+ puts("\nRepairing tables");
+ what_to_do = DO_REPAIR;
+ for (i = 0; i < tables4repair.elements ; i++)
+ {
+ char *name= (char*) dynamic_array_ptr(&tables4repair, i);
+ handle_request_for_tables(name, strlen(name));
+ }
+ }
+ end:
+ dbDisconnect(current_host);
+ if (opt_auto_repair)
+ delete_dynamic(&tables4repair);
+ my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
+ my_end(0);
+ return(first_error!=0);
+} /* main */
diff --git a/client/mysqldump.c b/client/mysqldump.c
index ce6c64aa00e..4893c13a0a0 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -37,7 +37,7 @@
** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
**/
-#define DUMP_VERSION "8.13"
+#define DUMP_VERSION "8.14"
#include <global.h>
#include <my_sys.h>
@@ -73,7 +73,7 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0,
lock_tables=0,ignore_errors=0,flush_logs=0,replace=0,
ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0,
opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0,
- opt_alldbs=0,opt_create_db=0,opt_first_slave=0;
+ opt_alldbs=0,opt_create_db=0,opt_first_slave=0;
static MYSQL mysql_connection,*sock=0;
static char insert_pat[12 * 1024],*opt_password=0,*current_user=0,
*current_host=0,*path=0,*fields_terminated=0,
@@ -85,6 +85,7 @@ static int first_error=0;
extern ulong net_buffer_length;
static DYNAMIC_STRING extended_row;
#include "sslopt-vars.h"
+FILE *result_file;
enum options {OPT_FTB=256, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_KEYWORDS,
OPT_LOCKS, OPT_DROP, OPT_OPTIMIZE, OPT_DELAYED, OPT_TABLES,
@@ -127,6 +128,7 @@ static struct option long_options[] =
{"port", required_argument, 0, 'P'},
{"quick", no_argument, 0, 'q'},
{"quote-names", no_argument, 0, 'Q'},
+ {"result-file", required_argument, 0, 'r'},
{"set-variable", required_argument, 0, 'O'},
{"socket", required_argument, 0, 'S'},
#include "sslopt-longopts.h"
@@ -227,6 +229,10 @@ puts("\
-P, --port=... Port number to use for connection.\n\
-q, --quick Don't buffer query, dump directly to stdout.\n\
-Q, --quote-names Quote table and column names with `\n\
+ -r, --result-file=... Direct output to a given file. This option should be\n\
+ used in MSDOS, because it prevents new line '\\n'\n\
+ from being converted to '\\n\\r' (newline + carriage\n\
+ return).\n\
-S, --socket=... Socket file to use for connection.\n\
--tables Overrides option --databases (-B).\n");
#include "sslopt-usage.h"
@@ -284,9 +290,11 @@ static int get_options(int *argc,char ***argv)
int c,option_index;
my_bool tty_password=0;
+ result_file=stdout;
load_defaults("my",load_default_groups,argc,argv);
set_all_changeable_vars(changeable_vars);
- while ((c=getopt_long(*argc,*argv,"#::p::h:u:O:P:S:T:EBaAcCdefFlnqtvVw:?Ix",
+ while ((c=getopt_long(*argc,*argv,
+ "#::p::h:u:O:P:r:S:T:EBaAcCdefFlnqtvVw:?Ix",
long_options, &option_index)) != EOF)
{
switch(c) {
@@ -346,6 +354,11 @@ static int get_options(int *argc,char ***argv)
case 'P':
opt_mysql_port= (unsigned int) atoi(optarg);
break;
+ case 'r':
+ if (!(result_file = my_fopen(optarg, O_WRONLY | O_BINARY,
+ MYF(MY_WME))))
+ exit(1);
+ break;
case 'S':
opt_mysql_unix_port= optarg;
break;
@@ -589,7 +602,7 @@ static uint getTableStructure(char *table, char* db)
char *strpos, *table_name;
const char *delayed;
char name_buff[NAME_LEN+3],table_buff[NAME_LEN+3];
- FILE *sql_file = stdout;
+ FILE *sql_file = result_file;
DBUG_ENTER("getTableStructure");
delayed= opt_delayed ? " DELAYED " : "";
@@ -625,8 +638,8 @@ static uint getTableStructure(char *table, char* db)
O_WRONLY, MYF(MY_WME));
if (!sql_file) /* If file couldn't be opened */
{
- safe_exit(EX_MYSQLERR);
- DBUG_RETURN(0);
+ safe_exit(EX_MYSQLERR);
+ DBUG_RETURN(0);
}
write_heder(sql_file, db);
}
@@ -724,9 +737,9 @@ static uint getTableStructure(char *table, char* db)
if (init)
{
if (!tFlag)
- fputs(",\n",sql_file);
+ fputs(",\n",sql_file);
if (cFlag)
- strpos=strmov(strpos,", ");
+ strpos=strmov(strpos,", ");
}
init=1;
if (cFlag)
@@ -734,20 +747,20 @@ static uint getTableStructure(char *table, char* db)
if (!tFlag)
{
if (opt_keywords)
- fprintf(sql_file, " %s.%s %s", table_name,
- quote_name(row[SHOW_FIELDNAME],name_buff), row[SHOW_TYPE]);
+ fprintf(sql_file, " %s.%s %s", table_name,
+ quote_name(row[SHOW_FIELDNAME],name_buff), row[SHOW_TYPE]);
else
- fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],name_buff),
- row[SHOW_TYPE]);
+ fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
+ name_buff), row[SHOW_TYPE]);
if (row[SHOW_DEFAULT])
{
- fputs(" DEFAULT ", sql_file);
- unescape(sql_file,row[SHOW_DEFAULT],lengths[SHOW_DEFAULT]);
+ fputs(" DEFAULT ", sql_file);
+ unescape(sql_file,row[SHOW_DEFAULT],lengths[SHOW_DEFAULT]);
}
if (!row[SHOW_NULL][0])
- fputs(" NOT NULL", sql_file);
+ fputs(" NOT NULL", sql_file);
if (row[SHOW_EXTRA][0])
- fprintf(sql_file, " %s",row[SHOW_EXTRA]);
+ fprintf(sql_file, " %s",row[SHOW_EXTRA]);
}
}
numFields = (uint) mysql_num_rows(tableRes);
@@ -761,9 +774,9 @@ static uint getTableStructure(char *table, char* db)
if (mysql_query(sock, buff))
{
fprintf(stderr, "%s: Can't get keys for table '%s' (%s)\n",
- my_progname, table, mysql_error(sock));
+ my_progname, table, mysql_error(sock));
if (sql_file != stdout)
- my_fclose(sql_file, MYF(MY_WME));
+ my_fclose(sql_file, MYF(MY_WME));
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
}
@@ -776,16 +789,16 @@ static uint getTableStructure(char *table, char* db)
{
if (atoi(row[3]) == 1)
{
- keynr++;
- #ifdef FORCE_PRIMARY_KEY
- if (atoi(row[1]) == 0 && primary_key == INT_MAX)
- primary_key=keynr;
- #endif
- if (!strcmp(row[2],"PRIMARY"))
- {
- primary_key=keynr;
- break;
- }
+ keynr++;
+#ifdef FORCE_PRIMARY_KEY
+ if (atoi(row[1]) == 0 && primary_key == INT_MAX)
+ primary_key=keynr;
+#endif
+ if (!strcmp(row[2],"PRIMARY"))
+ {
+ primary_key=keynr;
+ break;
+ }
}
}
mysql_data_seek(tableRes,0);
@@ -794,21 +807,21 @@ static uint getTableStructure(char *table, char* db)
{
if (atoi(row[3]) == 1)
{
- if (keynr++)
- putc(')', sql_file);
- if (atoi(row[1])) /* Test if duplicate key */
- /* Duplicate allowed */
- fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff));
- else if (keynr == primary_key)
- fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
- else
- fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff));
+ if (keynr++)
+ putc(')', sql_file);
+ if (atoi(row[1])) /* Test if duplicate key */
+ /* Duplicate allowed */
+ fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff));
+ else if (keynr == primary_key)
+ fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
+ else
+ fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff));
}
else
- putc(',', sql_file);
+ putc(',', sql_file);
fputs(quote_name(row[4],name_buff), sql_file);
if (row[7])
- fprintf(sql_file, " (%s)",row[7]); /* Sub key */
+ fprintf(sql_file, " (%s)",row[7]); /* Sub key */
}
if (keynr)
putc(')', sql_file);
@@ -820,28 +833,28 @@ static uint getTableStructure(char *table, char* db)
sprintf(buff,"show table status like '%s'",table);
if (mysql_query(sock, buff))
{
- if (mysql_errno(sock) != ER_PARSE_ERROR)
- { /* If old MySQL version */
- if (verbose)
- fprintf(stderr,
- "# Warning: Couldn't get status information for table '%s' (%s)\n",
- table,mysql_error(sock));
- }
+ if (mysql_errno(sock) != ER_PARSE_ERROR)
+ { /* If old MySQL version */
+ if (verbose)
+ fprintf(stderr,
+ "# Warning: Couldn't get status information for table '%s' (%s)\n",
+ table,mysql_error(sock));
+ }
}
else if (!(tableRes=mysql_store_result(sock)) ||
- !(row=mysql_fetch_row(tableRes)))
+ !(row=mysql_fetch_row(tableRes)))
{
- fprintf(stderr,
- "Error: Couldn't read status information for table '%s' (%s)\n",
- table,mysql_error(sock));
+ fprintf(stderr,
+ "Error: Couldn't read status information for table '%s' (%s)\n",
+ table,mysql_error(sock));
}
else
{
- fputs("/*!",sql_file);
- print_value(sql_file,tableRes,row,"type=","Type",0);
- print_value(sql_file,tableRes,row,"","Create_options",0);
- print_value(sql_file,tableRes,row,"comment=","Comment",1);
- fputs(" */",sql_file);
+ fputs("/*!",sql_file);
+ print_value(sql_file,tableRes,row,"type=","Type",0);
+ print_value(sql_file,tableRes,row,"","Create_options",0);
+ print_value(sql_file,tableRes,row,"comment=","Comment",1);
+ fputs(" */",sql_file);
}
mysql_free_result(tableRes); /* Is always safe to free */
}
@@ -960,14 +973,14 @@ static void dumpTable(uint numFields, char *table)
}
else
{
- printf("\n#\n# Dumping data for table '%s'\n", table);
+ fprintf(result_file,"\n#\n# Dumping data for table '%s'\n", table);
sprintf(query, "SELECT * FROM %s", quote_name(table,table_buff));
if (where)
{
- printf("# WHERE: %s\n",where);
+ fprintf(result_file,"# WHERE: %s\n",where);
strxmov(strend(query), " WHERE ",where,NullS);
}
- puts("#\n");
+ fputs("#\n\n", result_file);
if (mysql_query(sock, query))
{
@@ -994,7 +1007,8 @@ static void dumpTable(uint numFields, char *table)
}
if (opt_lock)
- printf("LOCK TABLES %s WRITE;\n", quote_name(table,table_buff));
+ fprintf(result_file,"LOCK TABLES %s WRITE;\n",
+ quote_name(table,table_buff));
total_length=net_buffer_length; /* Force row break */
row_break=0;
@@ -1007,7 +1021,7 @@ static void dumpTable(uint numFields, char *table)
ulong *lengths=mysql_fetch_lengths(res);
rownr++;
if (!extended_insert)
- fputs(insert_pat,stdout);
+ fputs(insert_pat,result_file);
mysql_field_seek(res,0);
for (i = 0; i < mysql_num_fields(res); i++)
@@ -1061,17 +1075,17 @@ static void dumpTable(uint numFields, char *table)
else
{
if (i)
- putchar(',');
+ fputc(',',result_file);
if (row[i])
{
if (!IS_NUM_FIELD(field))
- unescape(stdout, row[i], lengths[i]);
+ unescape(result_file, row[i], lengths[i]);
else
- fputs(row[i],stdout);
+ fputs(row[i],result_file);
}
else
{
- fputs("NULL",stdout);
+ fputs("NULL",result_file);
}
}
}
@@ -1084,27 +1098,25 @@ static void dumpTable(uint numFields, char *table)
if (total_length + row_length < net_buffer_length)
{
total_length += row_length;
- putchar(','); /* Always row break */
- fputs(extended_row.str,stdout);
+ fputc(',',result_file); /* Always row break */
+ fputs(extended_row.str,result_file);
}
else
{
if (row_break)
- puts(";");
+ fputs(";\n", result_file);
row_break=1; /* This is first row */
- fputs(insert_pat,stdout);
- fputs(extended_row.str,stdout);
+ fputs(insert_pat,result_file);
+ fputs(extended_row.str,result_file);
total_length = row_length+init_length;
}
}
else
- {
- puts(");");
- }
+ fputs(");\n", result_file);
}
if (extended_insert && row_break)
- puts(";"); /* If not empty table */
- fflush(stdout);
+ fputs(";\n", result_file); /* If not empty table */
+ fflush(result_file);
if (mysql_errno(sock))
{
sprintf(query,"%s: Error %d: %s when dumping table '%s' at row: %ld\n",
@@ -1118,7 +1130,7 @@ static void dumpTable(uint numFields, char *table)
return;
}
if (opt_lock)
- puts("UNLOCK TABLES;");
+ fputs("UNLOCK TABLES;\n", result_file);
mysql_free_result(res);
}
} /* dumpTable */
@@ -1194,10 +1206,11 @@ static int init_dumping(char *database)
{
if (opt_databases || opt_alldbs)
{
- printf("\n#\n# Current Database: %s\n#\n", database);
+ fprintf(result_file,"\n#\n# Current Database: %s\n#\n", database);
if (!opt_create_db)
- printf("\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n", database);
- printf("\nUSE %s;\n", database);
+ fprintf(result_file,"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
+ database);
+ fprintf(result_file,"\nUSE %s;\n", database);
}
}
if (extended_insert)
@@ -1329,7 +1342,7 @@ int main(int argc, char **argv)
if (dbConnect(current_host, current_user, opt_password))
exit(EX_MYSQLERR);
if (!path)
- write_heder(stdout, *argv);
+ write_heder(result_file, *argv);
if (opt_first_slave)
{
@@ -1365,7 +1378,9 @@ int main(int argc, char **argv)
}
}
dbDisconnect(current_host);
- puts("");
+ fputs("\n", result_file);
+ if (result_file != stdout)
+ my_fclose(result_file, MYF(0));
my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
if (extended_insert)
dynstr_free(&extended_row);
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 09138f93df6..e1ca5638340 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -569,7 +569,7 @@ int eval_expr(VAR* v, const char* p, const char** p_end)
else
{
v->str_val = (char*)p;
- v->str_val_len = (p_end && *p_end) ? *p_end - p : strlen(p);
+ v->str_val_len = (p_end && *p_end) ? (int) (*p_end - p) : (int) strlen(p);
v->int_val=atoi(p);
v->int_dirty=0;
return 0;
@@ -1758,6 +1758,7 @@ static void init_var_hash()
die("Variable hash initialization failed");
var_from_env("MASTER_MYPORT", "9306");
var_from_env("SLAVE_MYPORT", "9307");
+ var_from_env("MYSQL_TEST_DIR", "");
}
int main(int argc, char** argv)