diff options
author | unknown <sasha@mysql.sashanet.com> | 2001-05-10 15:06:35 -0600 |
---|---|---|
committer | unknown <sasha@mysql.sashanet.com> | 2001-05-10 15:06:35 -0600 |
commit | 9192600eb7c52f2675a67548849409dec2364165 (patch) | |
tree | 32fd0eb2c34334b7806726cf2dc9f8a893ea6fc8 /client | |
parent | 9afb49f53cb7b8da7519f45f588a78b559013de3 (diff) | |
parent | b59b5f4b6ec6bd5b0eb8cee832b6d4f51fa646fc (diff) | |
download | mariadb-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.am | 3 | ||||
-rw-r--r-- | client/mysqladmin.c | 15 | ||||
-rw-r--r-- | client/mysqlcheck.c | 685 | ||||
-rw-r--r-- | client/mysqldump.c | 175 | ||||
-rw-r--r-- | client/mysqltest.c | 3 |
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) |