00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #define DUMP_VERSION "10.10"
00041
00042 #include <my_global.h>
00043 #include <my_sys.h>
00044 #include <m_string.h>
00045 #include <m_ctype.h>
00046 #include <hash.h>
00047
00048 #include "client_priv.h"
00049 #include "mysql.h"
00050 #include "mysql_version.h"
00051 #include "mysqld_error.h"
00052
00053
00054
00055 #define EX_USAGE 1
00056 #define EX_MYSQLERR 2
00057 #define EX_CONSCHECK 3
00058 #define EX_EOM 4
00059 #define EX_EOF 5
00060 #define EX_ILLEGAL_TABLE 6
00061
00062
00063
00064 #define SHOW_FIELDNAME 0
00065 #define SHOW_TYPE 1
00066 #define SHOW_NULL 2
00067 #define SHOW_DEFAULT 4
00068 #define SHOW_EXTRA 5
00069
00070
00071 #define QUERY_LENGTH 1536
00072
00073 static char *add_load_option(char *ptr, const char *object,
00074 const char *statement);
00075 static ulong find_set(TYPELIB *lib, const char *x, uint length,
00076 char **err_pos, uint *err_len);
00077
00078 static char *field_escape(char *to,const char *from,uint length);
00079 static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1,
00080 lock_tables=1,ignore_errors=0,flush_logs=0,
00081 opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0,
00082 opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0,
00083 opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0,
00084 opt_set_charset=0,
00085 opt_autocommit=0,opt_disable_keys=1,opt_xml=0,
00086 opt_delete_master_logs=0, tty_password=0,
00087 opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
00088 opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
00089 opt_complete_insert= 0, opt_drop_database= 0;
00090 static ulong opt_max_allowed_packet, opt_net_buffer_length;
00091 static MYSQL mysql_connection,*sock=0;
00092 static my_bool insert_pat_inited=0;
00093 static DYNAMIC_STRING insert_pat;
00094 static char *opt_password=0,*current_user=0,
00095 *current_host=0,*path=0,*fields_terminated=0,
00096 *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
00097 *where=0, *order_by=0,
00098 *opt_compatible_mode_str= 0,
00099 *err_ptr= 0;
00100 static char compatible_mode_normal_str[255];
00101 static ulong opt_compatible_mode= 0;
00102 #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
00103 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
00104 static uint opt_mysql_port= 0, err_len= 0, opt_master_data;
00105 static my_string opt_mysql_unix_port=0;
00106 static int first_error=0;
00107 static DYNAMIC_STRING extended_row;
00108 #include <sslopt-vars.h>
00109 FILE *md_result_file;
00110 #ifdef HAVE_SMEM
00111 static char *shared_memory_base_name=0;
00112 #endif
00113 static uint opt_protocol= 0;
00114
00115
00116
00117
00118
00119 static const char *mysql_universal_client_charset=
00120 MYSQL_UNIVERSAL_CLIENT_CHARSET;
00121 static char *default_charset;
00122 static CHARSET_INFO *charset_info= &my_charset_latin1;
00123 const char *default_dbug_option="d:t:o,/tmp/mysqldump.trace";
00124
00125 my_bool was_views= 0;
00126
00127 const char *compatible_mode_names[]=
00128 {
00129 "MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
00130 "MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
00131 "ANSI",
00132 NullS
00133 };
00134 #define MASK_ANSI_QUOTES \
00135 (\
00136 (1<<2) | \
00137 (1<<3) | \
00138 (1<<4) | \
00139 (1<<5) | \
00140 (1<<6) | \
00141 (1<<10) \
00142 )
00143 TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
00144 "", compatible_mode_names, NULL};
00145
00146 HASH ignore_table;
00147
00148 static struct my_option my_long_options[] =
00149 {
00150 {"all", 'a', "Deprecated. Use --create-options instead.",
00151 (gptr*) &create_options, (gptr*) &create_options, 0, GET_BOOL, NO_ARG, 1,
00152 0, 0, 0, 0, 0},
00153 {"all-databases", 'A',
00154 "Dump all the databases. This will be same as --databases with all databases selected.",
00155 (gptr*) &opt_alldbs, (gptr*) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
00156 0, 0},
00157 {"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
00158 (gptr*) &opt_drop_database, (gptr*) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
00159 0},
00160 {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
00161 (gptr*) &opt_drop, (gptr*) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
00162 0},
00163 {"add-locks", OPT_LOCKS, "Add locks around insert statements.",
00164 (gptr*) &opt_lock, (gptr*) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
00165 0},
00166 {"allow-keywords", OPT_KEYWORDS,
00167 "Allow creation of column names that are keywords.", (gptr*) &opt_keywords,
00168 (gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00169 {"character-sets-dir", OPT_CHARSETS_DIR,
00170 "Directory where character sets are.", (gptr*) &charsets_dir,
00171 (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00172 {"comments", 'i', "Write additional information.",
00173 (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG,
00174 1, 0, 0, 0, 0, 0},
00175 {"compatible", OPT_COMPATIBLE,
00176 "Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MySQL. Legal modes are: ansi, mysql323, mysql40, postgresql, oracle, mssql, db2, maxdb, no_key_options, no_table_options, no_field_options. One can use several modes separated by commas. Note: Requires MySQL server version 4.1.0 or higher. This option is ignored with earlier server versions.",
00177 (gptr*) &opt_compatible_mode_str, (gptr*) &opt_compatible_mode_str, 0,
00178 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00179 {"compact", OPT_COMPACT,
00180 "Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --no-set-names --skip-disable-keys --skip-add-locks",
00181 (gptr*) &opt_compact, (gptr*) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
00182 0, 0},
00183 {"complete-insert", 'c', "Use complete insert statements.",
00184 (gptr*) &opt_complete_insert, (gptr*) &opt_complete_insert, 0, GET_BOOL,
00185 NO_ARG, 0, 0, 0, 0, 0, 0},
00186 {"compress", 'C', "Use compression in server/client protocol.",
00187 (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
00188 0, 0, 0},
00189 {"create-options", OPT_CREATE_OPTIONS,
00190 "Include all MySQL specific create options.",
00191 (gptr*) &create_options, (gptr*) &create_options, 0, GET_BOOL, NO_ARG, 1,
00192 0, 0, 0, 0, 0},
00193 {"databases", 'B',
00194 "To dump several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as databasenames. 'USE db_name;' will be included in the output.",
00195 (gptr*) &opt_databases, (gptr*) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
00196 0, 0, 0, 0},
00197 #ifdef DBUG_OFF
00198 {"debug", '#', "This is a non-debug version. Catch this and exit",
00199 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
00200 #else
00201 {"debug", '#', "Output debug log", (gptr*) &default_dbug_option,
00202 (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
00203 #endif
00204 {"default-character-set", OPT_DEFAULT_CHARSET,
00205 "Set the default character set.", (gptr*) &default_charset,
00206 (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00207 {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; "
00208 "currently ignored because of http://bugs.mysql.com/bug.php?id=7815 "
00209 "but will be re-enabled later",
00210 (gptr*) &opt_delayed, (gptr*) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
00211 0, 0},
00212 {"delete-master-logs", OPT_DELETE_MASTER_LOGS,
00213 "Delete logs on master after backup. This automatically enables --master-data.",
00214 (gptr*) &opt_delete_master_logs, (gptr*) &opt_delete_master_logs, 0,
00215 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00216 {"disable-keys", 'K',
00217 "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys,
00218 (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
00219 {"extended-insert", 'e',
00220 "Allows utilization of the new, much faster INSERT syntax.",
00221 (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG,
00222 1, 0, 0, 0, 0, 0},
00223 {"fields-terminated-by", OPT_FTB,
00224 "Fields in the textfile are terminated by ...", (gptr*) &fields_terminated,
00225 (gptr*) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00226 {"fields-enclosed-by", OPT_ENC,
00227 "Fields in the importfile are enclosed by ...", (gptr*) &enclosed,
00228 (gptr*) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
00229 {"fields-optionally-enclosed-by", OPT_O_ENC,
00230 "Fields in the i.file are opt. enclosed by ...", (gptr*) &opt_enclosed,
00231 (gptr*) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
00232 {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
00233 (gptr*) &escaped, (gptr*) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00234 {"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
00235 (gptr*) &opt_lock_all_tables, (gptr*) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
00236 0, 0, 0, 0, 0, 0},
00237 {"flush-logs", 'F', "Flush logs file in server before starting dump. "
00238 "Note that if you dump many databases at once (using the option "
00239 "--databases= or --all-databases), the logs will be flushed for "
00240 "each database dumped. The exception is when using --lock-all-tables "
00241 "or --master-data: "
00242 "in this case the logs will be flushed only once, corresponding "
00243 "to the moment all tables are locked. So if you want your dump and "
00244 "the log flush to happen at the same exact moment you should use "
00245 "--lock-all-tables or --master-data with --flush-logs",
00246 (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
00247 0, 0},
00248 {"force", 'f', "Continue even if we get an sql-error.",
00249 (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG,
00250 0, 0, 0, 0, 0, 0},
00251 {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
00252 NO_ARG, 0, 0, 0, 0, 0, 0},
00253 {"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
00254 "VARBINARY, BLOB) in hexadecimal format.",
00255 (gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00256 {"host", 'h', "Connect to host.", (gptr*) ¤t_host,
00257 (gptr*) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00258 {"ignore-table", OPT_IGNORE_TABLE,
00259 "Do not dump the specified table. To specify more than one table to ignore, "
00260 "use the directive multiple times, once for each table. Each table must "
00261 "be specified with both database and table names, e.g. --ignore-table=database.table",
00262 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00263 {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
00264 (gptr*) &opt_ignore, (gptr*) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
00265 0, 0},
00266 {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
00267 (gptr*) &lines_terminated, (gptr*) &lines_terminated, 0, GET_STR,
00268 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00269 {"lock-all-tables", 'x', "Locks all tables across all databases. This "
00270 "is achieved by taking a global read lock for the duration of the whole "
00271 "dump. Automatically turns --single-transaction and --lock-tables off.",
00272 (gptr*) &opt_lock_all_tables, (gptr*) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
00273 0, 0, 0, 0, 0, 0},
00274 {"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables,
00275 (gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
00276 {"master-data", OPT_MASTER_DATA,
00277 "This causes the binary log position and filename to be appended to the "
00278 "output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
00279 " to 2, that command will be prefixed with a comment symbol. "
00280 "This option will turn --lock-all-tables on, unless "
00281 "--single-transaction is specified too (in which case a "
00282 "global read lock is only taken a short time at the beginning of the dump "
00283 "- don't forget to read about --single-transaction below). In all cases "
00284 "any action on logs will happen at the exact moment of the dump."
00285 "Option automatically turns --lock-tables off.",
00286 (gptr*) &opt_master_data, (gptr*) &opt_master_data, 0,
00287 GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
00288 {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "",
00289 (gptr*) &opt_max_allowed_packet, (gptr*) &opt_max_allowed_packet, 0,
00290 GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096,
00291 (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
00292 {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "",
00293 (gptr*) &opt_net_buffer_length, (gptr*) &opt_net_buffer_length, 0,
00294 GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L,
00295 MALLOC_OVERHEAD-1024, 1024, 0},
00296 {"no-autocommit", OPT_AUTOCOMMIT,
00297 "Wrap tables with autocommit/commit statements.",
00298 (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG,
00299 0, 0, 0, 0, 0, 0},
00300 {"no-create-db", 'n',
00301 "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}.",
00302 (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
00303 0, 0, 0, 0},
00304 {"no-create-info", 't', "Don't write table creation info.",
00305 (gptr*) &tFlag, (gptr*) &tFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00306 {"no-data", 'd', "No row information.", (gptr*) &dFlag, (gptr*) &dFlag, 0,
00307 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00308 {"no-set-names", 'N',
00309 "Deprecated. Use --skip-set-charset instead.",
00310 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
00311 {"opt", OPT_OPTIMIZE,
00312 "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.",
00313 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
00314 {"order-by-primary", OPT_ORDER_BY_PRIMARY,
00315 "Sorts each table's rows by primary key, or first unique key, if such a key exists. Useful when dumping a MyISAM table to be loaded into an InnoDB table, but will make the dump itself take considerably longer.",
00316 (gptr*) &opt_order_by_primary, (gptr*) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00317 {"password", 'p',
00318 "Password to use when connecting to server. If password is not given it's solicited on the tty.",
00319 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
00320 #ifdef __WIN__
00321 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
00322 NO_ARG, 0, 0, 0, 0, 0, 0},
00323 #endif
00324 {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port,
00325 (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
00326 0},
00327 {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
00328 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00329 {"quick", 'q', "Don't buffer query, dump directly to stdout.",
00330 (gptr*) &quick, (gptr*) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
00331 {"quote-names",'Q', "Quote table and column names with backticks (`).",
00332 (gptr*) &opt_quoted, (gptr*) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
00333 0, 0},
00334 {"result-file", 'r',
00335 "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
00336 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00337 {"set-charset", OPT_SET_CHARSET,
00338 "Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.",
00339 (gptr*) &opt_set_charset, (gptr*) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
00340 0, 0, 0, 0, 0},
00341 {"set-variable", 'O',
00342 "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.",
00343 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00344 #ifdef HAVE_SMEM
00345 {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
00346 "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name,
00347 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00348 #endif
00349
00350
00351
00352
00353
00354 {"single-transaction", OPT_TRANSACTION,
00355 "Creates a consistent snapshot by dumping all tables in a single "
00356 "transaction. Works ONLY for tables stored in storage engines which "
00357 "support multiversioning (currently only InnoDB does); the dump is NOT "
00358 "guaranteed to be consistent for other storage engines. Option "
00359 "automatically turns off --lock-tables.",
00360 (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0,
00361 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00362 {"skip-opt", OPT_SKIP_OPTIMIZATION,
00363 "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
00364 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
00365 {"socket", 'S', "Socket file to use for connection.",
00366 (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
00367 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00368 #include <sslopt-longopts.h>
00369 {"tab",'T',
00370 "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
00371 (gptr*) &path, (gptr*) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00372 {"tables", OPT_TABLES, "Overrides option --databases (-B).",
00373 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
00374 #ifndef DONT_ALLOW_USER_CHANGE
00375 {"user", 'u', "User for login if not current user.",
00376 (gptr*) ¤t_user, (gptr*) ¤t_user, 0, GET_STR, REQUIRED_ARG,
00377 0, 0, 0, 0, 0, 0},
00378 #endif
00379 {"verbose", 'v', "Print info about the various stages.",
00380 (gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
00381 {"version",'V', "Output version information and exit.", 0, 0, 0,
00382 GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
00383 {"where", 'w', "Dump only selected records; QUOTES mandatory!",
00384 (gptr*) &where, (gptr*) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
00385 {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
00386 NO_ARG, 0, 0, 0, 0, 0, 0},
00387 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
00388 };
00389
00390 static const char *load_default_groups[]= { "mysqldump","client",0 };
00391
00392 static void safe_exit(int error);
00393 static void write_header(FILE *sql_file, char *db_name);
00394 static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
00395 const char *prefix,const char *name,
00396 int string_value);
00397 static int dump_selected_tables(char *db, char **table_names, int tables);
00398 static int dump_all_tables_in_db(char *db);
00399 static int init_dumping(char *);
00400 static int dump_databases(char **);
00401 static int dump_all_databases();
00402 static char *quote_name(const char *name, char *buff, my_bool force);
00403 static const char *check_if_ignore_table(const char *table_name);
00404 static char *primary_key_fields(const char *table_name);
00405 static my_bool get_view_structure(char *table, char* db);
00406 static my_bool dump_all_views_in_db(char *database);
00407
00408 #include <help_start.h>
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 void check_io(FILE *file)
00419 {
00420 if (ferror(file))
00421 {
00422 fprintf(stderr, "%s: Got errno %d on write\n", my_progname, errno);
00423 safe_exit(EX_EOF);
00424 }
00425 }
00426
00427 static void print_version(void)
00428 {
00429 printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,DUMP_VERSION,
00430 MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
00431 NETWARE_SET_SCREEN_MODE(1);
00432 }
00433
00434
00435 static void short_usage_sub(void)
00436 {
00437 printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
00438 printf("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n",
00439 my_progname);
00440 printf("OR %s [OPTIONS] --all-databases [OPTIONS]\n", my_progname);
00441 NETWARE_SET_SCREEN_MODE(1);
00442 }
00443
00444
00445 static void usage(void)
00446 {
00447 print_version();
00448 puts("By Igor Romanenko, Monty, Jani & Sinisa");
00449 puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
00450 puts("Dumping definition and data mysql database or table");
00451 short_usage_sub();
00452 print_defaults("my",load_default_groups);
00453 my_print_help(my_long_options);
00454 my_print_variables(my_long_options);
00455 }
00456
00457
00458 static void short_usage(void)
00459 {
00460 short_usage_sub();
00461 printf("For more options, use %s --help\n", my_progname);
00462 }
00463
00464 #include <help_end.h>
00465
00466
00467 static void write_header(FILE *sql_file, char *db_name)
00468 {
00469 if (opt_xml)
00470 {
00471 fputs("<?xml version=\"1.0\"?>\n", sql_file);
00472 fputs("<mysqldump ", sql_file);
00473 fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
00474 sql_file);
00475 fputs(">\n", sql_file);
00476 check_io(sql_file);
00477 }
00478 else if (!opt_compact)
00479 {
00480 if (opt_comments)
00481 {
00482 fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION);
00483 fprintf(sql_file, "-- Host: %s Database: %s\n",
00484 current_host ? current_host : "localhost", db_name ? db_name :
00485 "");
00486 fputs("-- ------------------------------------------------------\n",
00487 sql_file);
00488 fprintf(sql_file, "-- Server version\t%s\n",
00489 mysql_get_server_info(&mysql_connection));
00490 }
00491 if (opt_set_charset)
00492 fprintf(sql_file,
00493 "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
00494 "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
00495 "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
00496 "\n/*!40101 SET NAMES %s */;\n",default_charset);
00497 if (!path)
00498 {
00499 fprintf(md_result_file,"\;\n\;\n\
00502 ");
00503 }
00504 fprintf(sql_file,
00505 "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */;\n"
00506 "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\n",
00507 path?"":"NO_AUTO_VALUE_ON_ZERO",compatible_mode_normal_str[0]==0?"":",",
00508 compatible_mode_normal_str);
00509 check_io(sql_file);
00510 }
00511 }
00512
00513
00514 static void write_footer(FILE *sql_file)
00515 {
00516 if (opt_xml)
00517 {
00518 fputs("</mysqldump>\n", sql_file);
00519 check_io(sql_file);
00520 }
00521 else if (!opt_compact)
00522 {
00523 fprintf(sql_file,"\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n");
00524 if (!path)
00525 {
00526 fprintf(md_result_file,"\;\n\;\n");
00529 }
00530 if (opt_set_charset)
00531 fprintf(sql_file,
00532 "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
00533 "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
00534 "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
00535 fprintf(sql_file,
00536 "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n");
00537 fputs("\n", sql_file);
00538 check_io(sql_file);
00539 }
00540 }
00541
00542 static void free_table_ent(char *key)
00543
00544 {
00545 my_free((gptr) key, MYF(0));
00546 }
00547
00548
00549 byte* get_table_key(const char *entry, uint *length,
00550 my_bool not_used __attribute__((unused)))
00551 {
00552 *length= strlen(entry);
00553 return (byte*) entry;
00554 }
00555
00556
00557 void init_table_rule_hash(HASH* h)
00558 {
00559 if (hash_init(h, charset_info, 16, 0, 0,
00560 (hash_get_key) get_table_key,
00561 (hash_free_key) free_table_ent, 0))
00562 exit(EX_EOM);
00563 }
00564
00565 static my_bool
00566 get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
00567 char *argument)
00568 {
00569 switch (optid) {
00570 case 'p':
00571 if (argument)
00572 {
00573 char *start=argument;
00574 my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
00575 opt_password=my_strdup(argument,MYF(MY_FAE));
00576 while (*argument) *argument++= 'x';
00577 if (*start)
00578 start[1]=0;
00579 tty_password= 0;
00580 }
00581 else
00582 tty_password=1;
00583 break;
00584 case 'r':
00585 if (!(md_result_file = my_fopen(argument, O_WRONLY | FILE_BINARY,
00586 MYF(MY_WME))))
00587 exit(1);
00588 break;
00589 case 'W':
00590 #ifdef __WIN__
00591 opt_protocol = MYSQL_PROTOCOL_PIPE;
00592 #endif
00593 break;
00594 case 'N':
00595 opt_set_charset= 0;
00596 break;
00597 case 'T':
00598 opt_disable_keys=0;
00599 break;
00600 case '#':
00601 DBUG_PUSH(argument ? argument : default_dbug_option);
00602 break;
00603 #include <sslopt-case.h>
00604 case 'V': print_version(); exit(0);
00605 case 'X':
00606 opt_xml = 1;
00607 extended_insert= opt_drop= opt_lock=
00608 opt_disable_keys= opt_autocommit= opt_create_db= 0;
00609 break;
00610 case 'I':
00611 case '?':
00612 usage();
00613 exit(0);
00614 case (int) OPT_MASTER_DATA:
00615 if (!argument)
00616 opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
00617 break;
00618 case (int) OPT_OPTIMIZE:
00619 extended_insert= opt_drop= opt_lock= quick= create_options=
00620 opt_disable_keys= lock_tables= opt_set_charset= 1;
00621 break;
00622 case (int) OPT_SKIP_OPTIMIZATION:
00623 extended_insert= opt_drop= opt_lock= quick= create_options=
00624 opt_disable_keys= lock_tables= opt_set_charset= 0;
00625 break;
00626 case (int) OPT_COMPACT:
00627 if (opt_compact)
00628 {
00629 opt_comments= opt_drop= opt_disable_keys= opt_lock= 0;
00630 opt_set_charset= 0;
00631 }
00632 case (int) OPT_TABLES:
00633 opt_databases=0;
00634 break;
00635 case (int) OPT_IGNORE_TABLE:
00636 {
00637 if (!strchr(argument, '.'))
00638 {
00639 fprintf(stderr, "Illegal use of option --ignore-table=<database>.<table>\n");
00640 exit(1);
00641 }
00642 if (!hash_inited(&ignore_table))
00643 init_table_rule_hash(&ignore_table);
00644
00645 if (my_hash_insert(&ignore_table, (byte*)my_strdup(argument, MYF(0))))
00646 exit(EX_EOM);
00647 break;
00648 }
00649 case (int) OPT_COMPATIBLE:
00650 {
00651 char buff[255];
00652 char *end= compatible_mode_normal_str;
00653 int i;
00654 ulong mode;
00655
00656 opt_quoted= 1;
00657 opt_set_charset= 0;
00658 opt_compatible_mode_str= argument;
00659 opt_compatible_mode= find_set(&compatible_mode_typelib,
00660 argument, strlen(argument),
00661 &err_ptr, &err_len);
00662 if (err_len)
00663 {
00664 strmake(buff, err_ptr, min(sizeof(buff), err_len));
00665 fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
00666 exit(1);
00667 }
00668 #if !defined(DBUG_OFF)
00669 {
00670 uint size_for_sql_mode= 0;
00671 const char **ptr;
00672 for (ptr= compatible_mode_names; *ptr; ptr++)
00673 size_for_sql_mode+= strlen(*ptr);
00674 size_for_sql_mode+= sizeof(compatible_mode_names)-1;
00675 DBUG_ASSERT(sizeof(compatible_mode_normal_str)>=size_for_sql_mode);
00676 }
00677 #endif
00678 mode= opt_compatible_mode;
00679 for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
00680 {
00681 if (mode & 1)
00682 {
00683 end= strmov(end, compatible_mode_names[i]);
00684 end= strmov(end, ",");
00685 }
00686 }
00687 if (end!=compatible_mode_normal_str)
00688 end[-1]= 0;
00689
00690
00691
00692
00693 if (default_charset == mysql_universal_client_charset)
00694 default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
00695 break;
00696 }
00697 case (int) OPT_MYSQL_PROTOCOL:
00698 {
00699 if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0)
00700 {
00701 fprintf(stderr, "Unknown option to protocol: %s\n", argument);
00702 exit(1);
00703 }
00704 break;
00705 }
00706 #ifndef REMOVE_THIS_CODE_WHEN_FIX_BUG_7815
00707 case (int) OPT_DELAYED:
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 if (opt_delayed)
00718 {
00719 fprintf(stderr, "Warning: ignoring --delayed-insert (as explained "
00720 "in the output of 'mysqldump --help').\n");
00721 opt_delayed= 0;
00722 }
00723 break;
00724 #endif
00725 }
00726 return 0;
00727 }
00728
00729 static int get_options(int *argc, char ***argv)
00730 {
00731 int ho_error;
00732 MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
00733
00734 opt_max_allowed_packet= *mysql_params->p_max_allowed_packet;
00735 opt_net_buffer_length= *mysql_params->p_net_buffer_length;
00736
00737 md_result_file= stdout;
00738 load_defaults("my",load_default_groups,argc,argv);
00739
00740 if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
00741 exit(ho_error);
00742
00743 *mysql_params->p_max_allowed_packet= opt_max_allowed_packet;
00744 *mysql_params->p_net_buffer_length= opt_net_buffer_length;
00745
00746 if (opt_delayed)
00747 opt_lock=0;
00748 if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
00749 fields_terminated))
00750 {
00751 fprintf(stderr,
00752 "%s: You must use option --tab with --fields-...\n", my_progname);
00753 return(1);
00754 }
00755
00756
00757 if (opt_delete_master_logs && !opt_master_data)
00758 opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
00759 if (opt_single_transaction && opt_lock_all_tables)
00760 {
00761 fprintf(stderr, "%s: You can't use --single-transaction and "
00762 "--lock-all-tables at the same time.\n", my_progname);
00763 return(1);
00764 }
00765 if (opt_master_data)
00766 opt_lock_all_tables= !opt_single_transaction;
00767 if (opt_single_transaction || opt_lock_all_tables)
00768 lock_tables= 0;
00769 if (enclosed && opt_enclosed)
00770 {
00771 fprintf(stderr, "%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n", my_progname);
00772 return(1);
00773 }
00774 if ((opt_databases || opt_alldbs) && path)
00775 {
00776 fprintf(stderr,
00777 "%s: --databases or --all-databases can't be used with --tab.\n",
00778 my_progname);
00779 return(1);
00780 }
00781 if (strcmp(default_charset, charset_info->csname) &&
00782 !(charset_info= get_charset_by_csname(default_charset,
00783 MY_CS_PRIMARY, MYF(MY_WME))))
00784 exit(1);
00785 if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
00786 {
00787 short_usage();
00788 return 1;
00789 }
00790 if (tty_password)
00791 opt_password=get_tty_password(NullS);
00792 return(0);
00793 }
00794
00795
00796
00797
00798
00799 static void DB_error(MYSQL *mysql, const char *when)
00800 {
00801 DBUG_ENTER("DB_error");
00802 my_printf_error(0,"Got error: %d: %s %s", MYF(0),
00803 mysql_errno(mysql), mysql_error(mysql), when);
00804 safe_exit(EX_MYSQLERR);
00805 DBUG_VOID_RETURN;
00806 }
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
00826 const char *query)
00827 {
00828 if (mysql_query(mysql_con, query) ||
00829 (res && !((*res)= mysql_store_result(mysql_con))))
00830 {
00831 my_printf_error(0, "%s: Couldn't execute '%s': %s (%d)",
00832 MYF(0), my_progname, query,
00833 mysql_error(mysql_con), mysql_errno(mysql_con));
00834 return 1;
00835 }
00836 return 0;
00837 }
00838
00839
00840 static void safe_exit(int error)
00841 {
00842 if (!first_error)
00843 first_error= error;
00844 if (ignore_errors)
00845 return;
00846 if (sock)
00847 mysql_close(sock);
00848 exit(error);
00849 }
00850
00851
00852
00853
00854
00855
00856 static int dbConnect(char *host, char *user,char *passwd)
00857 {
00858 char buff[20+FN_REFLEN];
00859 DBUG_ENTER("dbConnect");
00860 if (verbose)
00861 {
00862 fprintf(stderr, "-- Connecting to %s...\n", host ? host : "localhost");
00863 }
00864 mysql_init(&mysql_connection);
00865 if (opt_compress)
00866 mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
00867 #ifdef HAVE_OPENSSL
00868 if (opt_use_ssl)
00869 mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
00870 opt_ssl_capath, opt_ssl_cipher);
00871 #endif
00872 if (opt_protocol)
00873 mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
00874 #ifdef HAVE_SMEM
00875 if (shared_memory_base_name)
00876 mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
00877 #endif
00878 mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
00879 if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
00880 NULL,opt_mysql_port,opt_mysql_unix_port,
00881 0)))
00882 {
00883 DB_error(&mysql_connection, "when trying to connect");
00884 return 1;
00885 }
00886
00887
00888
00889 if (mysql_get_server_version(&mysql_connection) < 40100)
00890 opt_set_charset= 0;
00891
00892
00893
00894
00895 sock->reconnect= 0;
00896 my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */",
00897 compatible_mode_normal_str);
00898 if (mysql_query_with_error_report(sock, 0, buff))
00899 {
00900 mysql_close(sock);
00901 safe_exit(EX_MYSQLERR);
00902 return 1;
00903 }
00904 return 0;
00905 }
00906
00907
00908
00909
00910
00911 static void dbDisconnect(char *host)
00912 {
00913 if (verbose)
00914 fprintf(stderr, "-- Disconnecting from %s...\n", host ? host : "localhost");
00915 mysql_close(sock);
00916 }
00917
00918
00919 static void unescape(FILE *file,char *pos,uint length)
00920 {
00921 char *tmp;
00922 DBUG_ENTER("unescape");
00923 if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME))))
00924 {
00925 ignore_errors=0;
00926 safe_exit(EX_MYSQLERR);
00927 }
00928 mysql_real_escape_string(&mysql_connection, tmp, pos, length);
00929 fputc('\'', file);
00930 fputs(tmp, file);
00931 fputc('\'', file);
00932 check_io(file);
00933 my_free(tmp, MYF(MY_WME));
00934 DBUG_VOID_RETURN;
00935 }
00936
00937
00938 static my_bool test_if_special_chars(const char *str)
00939 {
00940 #if MYSQL_VERSION_ID >= 32300
00941 for ( ; *str ; str++)
00942 if (!my_isvar(charset_info,*str) && *str != '$')
00943 return 1;
00944 #endif
00945 return 0;
00946 }
00947
00948
00949
00950 static char *quote_name(const char *name, char *buff, my_bool force)
00951 {
00952 char *to= buff;
00953 char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
00954
00955 if (!force && !opt_quoted && !test_if_special_chars(name))
00956 return (char*) name;
00957 *to++= qtype;
00958 while (*name)
00959 {
00960 if (*name == qtype)
00961 *to++= qtype;
00962 *to++= *name++;
00963 }
00964 to[0]= qtype;
00965 to[1]= 0;
00966 return buff;
00967 }
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 static char *quote_for_like(const char *name, char *buff)
00993 {
00994 char *to= buff;
00995 *to++= '\'';
00996 while (*name)
00997 {
00998 if (*name == '\\')
00999 {
01000 *to++='\\';
01001 *to++='\\';
01002 *to++='\\';
01003 }
01004 else if (*name == '\'' || *name == '_' || *name == '%')
01005 *to++= '\\';
01006 *to++= *name++;
01007 }
01008 to[0]= '\'';
01009 to[1]= 0;
01010 return buff;
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 static void print_quoted_xml(FILE *xml_file, const char *str, ulong len)
01028 {
01029 const char *end;
01030
01031 for (end= str + len; str != end; str++)
01032 {
01033 switch (*str) {
01034 case '<':
01035 fputs("<", xml_file);
01036 break;
01037 case '>':
01038 fputs(">", xml_file);
01039 break;
01040 case '&':
01041 fputs("&", xml_file);
01042 break;
01043 case '\"':
01044 fputs(""", xml_file);
01045 break;
01046 default:
01047 fputc(*str, xml_file);
01048 break;
01049 }
01050 }
01051 check_io(xml_file);
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 static void print_xml_tag1(FILE * xml_file, const char* sbeg,
01075 const char* stag_atr, const char* sval,
01076 const char* send)
01077 {
01078 fputs(sbeg, xml_file);
01079 fputs("<", xml_file);
01080 fputs(stag_atr, xml_file);
01081 fputs("\"", xml_file);
01082 print_quoted_xml(xml_file, sval, strlen(sval));
01083 fputs("\">", xml_file);
01084 fputs(send, xml_file);
01085 check_io(xml_file);
01086 }
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108 static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
01109 const char* stag_atr, const char* sval,
01110 const char* send)
01111 {
01112 fputs(sbeg, xml_file);
01113 fputs("<", xml_file);
01114 fputs(stag_atr, xml_file);
01115 fputs("\"", xml_file);
01116 print_quoted_xml(xml_file, sval, strlen(sval));
01117 fputs("\" xsi:nil=\"true\" />", xml_file);
01118 fputs(send, xml_file);
01119 check_io(xml_file);
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140 static void print_xml_row(FILE *xml_file, const char *row_name,
01141 MYSQL_RES *tableRes, MYSQL_ROW *row)
01142 {
01143 uint i;
01144 MYSQL_FIELD *field;
01145 ulong *lengths= mysql_fetch_lengths(tableRes);
01146
01147 fprintf(xml_file, "\t\t<%s", row_name);
01148 check_io(xml_file);
01149 mysql_field_seek(tableRes, 0);
01150 for (i= 0; (field= mysql_fetch_field(tableRes)); i++)
01151 {
01152 if ((*row)[i])
01153 {
01154 fputc(' ', xml_file);
01155 print_quoted_xml(xml_file, field->name, field->name_length);
01156 fputs("=\"", xml_file);
01157 print_quoted_xml(xml_file, (*row)[i], lengths[i]);
01158 fputc('"', xml_file);
01159 check_io(xml_file);
01160 }
01161 }
01162 fputs(" />\n", xml_file);
01163 check_io(xml_file);
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 static uint get_table_structure(char *table, char *db)
01176 {
01177 MYSQL_RES *tableRes;
01178 MYSQL_ROW row;
01179 my_bool init=0;
01180 uint numFields;
01181 char *result_table, *opt_quoted_table;
01182 const char *insert_option;
01183 char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
01184 char table_buff2[NAME_LEN*2+3];
01185 char query_buff[512];
01186 FILE *sql_file = md_result_file;
01187 int len;
01188 DBUG_ENTER("get_table_structure");
01189 DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
01190
01191 if (!insert_pat_inited)
01192 {
01193 insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024);
01194 }
01195 else
01196 dynstr_set(&insert_pat, "");
01197
01198 insert_option= ((opt_delayed && opt_ignore) ? " DELAYED IGNORE " :
01199 opt_delayed ? " DELAYED " :
01200 opt_ignore ? " IGNORE " : "");
01201
01202 if (verbose)
01203 fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
01204
01205 len= my_snprintf(query_buff, sizeof(query_buff),
01206 "SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
01207 (opt_quoted || opt_keywords));
01208 if (!create_options)
01209 strmov(query_buff+len, "/*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */");
01210
01211 result_table= quote_name(table, table_buff, 1);
01212 opt_quoted_table= quote_name(table, table_buff2, 0);
01213
01214 if (opt_order_by_primary)
01215 order_by = primary_key_fields(opt_quoted_table);
01216
01217 if (!opt_xml && !mysql_query_with_error_report(sock, 0, query_buff))
01218 {
01219
01220 if (!tFlag)
01221 {
01222
01223 char buff[20+FN_REFLEN];
01224 MYSQL_FIELD *field;
01225
01226 my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
01227 if (mysql_query_with_error_report(sock, 0, buff))
01228 {
01229 safe_exit(EX_MYSQLERR);
01230 DBUG_RETURN(0);
01231 }
01232
01233 if (path)
01234 {
01235 char filename[FN_REFLEN], tmp_path[FN_REFLEN];
01236 convert_dirname(tmp_path,path,NullS);
01237 sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
01238 O_WRONLY, MYF(MY_WME));
01239 if (!sql_file)
01240 {
01241 safe_exit(EX_MYSQLERR);
01242 DBUG_RETURN(0);
01243 }
01244 write_header(sql_file, db);
01245 }
01246 if (!opt_xml && opt_comments)
01247 {
01248 fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
01249 result_table);
01250 check_io(sql_file);
01251 }
01252 if (opt_drop)
01253 {
01254 fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
01255 check_io(sql_file);
01256 }
01257
01258 tableRes= mysql_store_result(sock);
01259 field= mysql_fetch_field_direct(tableRes, 0);
01260 if (strcmp(field->name, "View") == 0)
01261 {
01262 if (verbose)
01263 fprintf(stderr, "-- It's a view, create dummy table for view\n");
01264
01265 mysql_free_result(tableRes);
01266
01267
01268
01269
01270
01271
01272
01273
01274 my_snprintf(query_buff, sizeof(query_buff),
01275 "CREATE TEMPORARY TABLE %s SELECT * FROM %s WHERE 0",
01276 result_table, result_table);
01277 if (mysql_query_with_error_report(sock, 0, query_buff))
01278 {
01279 safe_exit(EX_MYSQLERR);
01280 DBUG_RETURN(0);
01281 }
01282
01283
01284 my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE TABLE %s",
01285 result_table);
01286 if (mysql_query_with_error_report(sock, 0, query_buff))
01287 {
01288 safe_exit(EX_MYSQLERR);
01289 DBUG_RETURN(0);
01290 }
01291 tableRes= mysql_store_result(sock);
01292 row= mysql_fetch_row(tableRes);
01293
01294 if (opt_drop)
01295 fprintf(sql_file, "DROP VIEW IF EXISTS %s;\n",opt_quoted_table);
01296
01297
01298 fprintf(sql_file, "CREATE %s;\n", row[1]+17);
01299 check_io(sql_file);
01300
01301 mysql_free_result(tableRes);
01302
01303
01304 my_snprintf(buff, sizeof(buff),
01305 "DROP TEMPORARY TABLE %s", result_table);
01306 if (mysql_query_with_error_report(sock, 0, buff))
01307 {
01308 safe_exit(EX_MYSQLERR);
01309 DBUG_RETURN(0);
01310 }
01311 was_views= 1;
01312 DBUG_RETURN(0);
01313 }
01314 row= mysql_fetch_row(tableRes);
01315 fprintf(sql_file, "%s;\n", row[1]);
01316 check_io(sql_file);
01317 mysql_free_result(tableRes);
01318 }
01319 my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
01320 result_table);
01321 if (mysql_query_with_error_report(sock, &tableRes, query_buff))
01322 {
01323 if (path)
01324 my_fclose(sql_file, MYF(MY_WME));
01325 safe_exit(EX_MYSQLERR);
01326 DBUG_RETURN(0);
01327 }
01328
01329 dynstr_append_mem(&insert_pat, "INSERT ", 7);
01330 dynstr_append(&insert_pat, insert_option);
01331 dynstr_append_mem(&insert_pat, "INTO ", 5);
01332 dynstr_append(&insert_pat, opt_quoted_table);
01333 if (opt_complete_insert)
01334 {
01335 dynstr_append_mem(&insert_pat, " (", 2);
01336 }
01337 else
01338 {
01339 dynstr_append_mem(&insert_pat, " VALUES ", 8);
01340 if (!extended_insert)
01341 dynstr_append_mem(&insert_pat, "(", 1);
01342 }
01343
01344 while ((row=mysql_fetch_row(tableRes)))
01345 {
01346 if (init)
01347 {
01348 if (opt_complete_insert)
01349 dynstr_append_mem(&insert_pat, ", ", 2);
01350 }
01351 init=1;
01352 if (opt_complete_insert)
01353 dynstr_append(&insert_pat,
01354 quote_name(row[SHOW_FIELDNAME], name_buff, 0));
01355 }
01356 numFields = (uint) mysql_num_rows(tableRes);
01357 mysql_free_result(tableRes);
01358 }
01359 else
01360 {
01361 if (verbose)
01362 fprintf(stderr,
01363 "%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
01364 my_progname, mysql_error(sock));
01365
01366 my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
01367 result_table);
01368 if (mysql_query_with_error_report(sock, &tableRes, query_buff))
01369 {
01370 safe_exit(EX_MYSQLERR);
01371 DBUG_RETURN(0);
01372 }
01373
01374
01375 if (!tFlag)
01376 {
01377 if (path)
01378 {
01379 char filename[FN_REFLEN], tmp_path[FN_REFLEN];
01380 convert_dirname(tmp_path,path,NullS);
01381 sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
01382 O_WRONLY, MYF(MY_WME));
01383 if (!sql_file)
01384 {
01385 safe_exit(EX_MYSQLERR);
01386 DBUG_RETURN(0);
01387 }
01388 write_header(sql_file, db);
01389 }
01390 if (!opt_xml && opt_comments)
01391 fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
01392 result_table);
01393 if (opt_drop)
01394 fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",result_table);
01395 if (!opt_xml)
01396 fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
01397 else
01398 print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n");
01399 check_io(sql_file);
01400 }
01401
01402 dynstr_append_mem(&insert_pat, "INSERT ", 7);
01403 dynstr_append(&insert_pat, insert_option);
01404 dynstr_append_mem(&insert_pat, "INTO ", 5);
01405 dynstr_append(&insert_pat, result_table);
01406 if (opt_complete_insert)
01407 {
01408 dynstr_append_mem(&insert_pat, " (", 2);
01409 }
01410 else
01411 {
01412 dynstr_append_mem(&insert_pat, " VALUES ", 8);
01413 if (!extended_insert)
01414 dynstr_append_mem(&insert_pat, "(", 1);
01415 }
01416
01417 while ((row=mysql_fetch_row(tableRes)))
01418 {
01419 ulong *lengths=mysql_fetch_lengths(tableRes);
01420 if (init)
01421 {
01422 if (!opt_xml && !tFlag)
01423 {
01424 fputs(",\n",sql_file);
01425 check_io(sql_file);
01426 }
01427 if (opt_complete_insert)
01428 dynstr_append_mem(&insert_pat, ", ", 2);
01429 }
01430 init=1;
01431 if (opt_complete_insert)
01432 dynstr_append(&insert_pat,
01433 quote_name(row[SHOW_FIELDNAME], name_buff, 0));
01434 if (!tFlag)
01435 {
01436 if (opt_xml)
01437 {
01438 print_xml_row(sql_file, "field", tableRes, &row);
01439 continue;
01440 }
01441
01442 if (opt_keywords)
01443 fprintf(sql_file, " %s.%s %s", result_table,
01444 quote_name(row[SHOW_FIELDNAME],name_buff, 0),
01445 row[SHOW_TYPE]);
01446 else
01447 fprintf(sql_file, " %s %s", quote_name(row[SHOW_FIELDNAME],
01448 name_buff, 0),
01449 row[SHOW_TYPE]);
01450 if (row[SHOW_DEFAULT])
01451 {
01452 fputs(" DEFAULT ", sql_file);
01453 unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]);
01454 }
01455 if (!row[SHOW_NULL][0])
01456 fputs(" NOT NULL", sql_file);
01457 if (row[SHOW_EXTRA][0])
01458 fprintf(sql_file, " %s",row[SHOW_EXTRA]);
01459 check_io(sql_file);
01460 }
01461 }
01462 numFields = (uint) mysql_num_rows(tableRes);
01463 mysql_free_result(tableRes);
01464 if (!tFlag)
01465 {
01466
01467 char buff[20+FN_REFLEN];
01468 uint keynr,primary_key;
01469 my_snprintf(buff, sizeof(buff), "show keys from %s", result_table);
01470 if (mysql_query_with_error_report(sock, &tableRes, buff))
01471 {
01472 if (mysql_errno(sock) == ER_WRONG_OBJECT)
01473 {
01474
01475 fputs("\t\t<options Comment=\"view\" />\n", sql_file);
01476 goto continue_xml;
01477 }
01478 fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
01479 my_progname, result_table, mysql_error(sock));
01480 if (path)
01481 my_fclose(sql_file, MYF(MY_WME));
01482 safe_exit(EX_MYSQLERR);
01483 DBUG_RETURN(0);
01484 }
01485
01486
01487 keynr=0;
01488 primary_key=INT_MAX;
01489 while ((row=mysql_fetch_row(tableRes)))
01490 {
01491 if (atoi(row[3]) == 1)
01492 {
01493 keynr++;
01494 #ifdef FORCE_PRIMARY_KEY
01495 if (atoi(row[1]) == 0 && primary_key == INT_MAX)
01496 primary_key=keynr;
01497 #endif
01498 if (!strcmp(row[2],"PRIMARY"))
01499 {
01500 primary_key=keynr;
01501 break;
01502 }
01503 }
01504 }
01505 mysql_data_seek(tableRes,0);
01506 keynr=0;
01507 while ((row=mysql_fetch_row(tableRes)))
01508 {
01509 if (opt_xml)
01510 {
01511 print_xml_row(sql_file, "key", tableRes, &row);
01512 continue;
01513 }
01514
01515 if (atoi(row[3]) == 1)
01516 {
01517 if (keynr++)
01518 putc(')', sql_file);
01519 if (atoi(row[1]))
01520
01521 fprintf(sql_file, ",\n KEY %s (",quote_name(row[2],name_buff,0));
01522 else if (keynr == primary_key)
01523 fputs(",\n PRIMARY KEY (",sql_file);
01524 else
01525 fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
01526 0));
01527 }
01528 else
01529 putc(',', sql_file);
01530 fputs(quote_name(row[4], name_buff, 0), sql_file);
01531 if (row[7])
01532 fprintf(sql_file, " (%s)",row[7]);
01533 check_io(sql_file);
01534 }
01535 if (!opt_xml)
01536 {
01537 if (keynr)
01538 putc(')', sql_file);
01539 fputs("\n)",sql_file);
01540 check_io(sql_file);
01541 }
01542
01543
01544 if (create_options)
01545 {
01546 char show_name_buff[NAME_LEN*2+2+24];
01547
01548
01549 my_snprintf(buff, sizeof(buff), "show table status like %s",
01550 quote_for_like(table, show_name_buff));
01551
01552 if (mysql_query_with_error_report(sock, &tableRes, buff))
01553 {
01554 if (mysql_errno(sock) != ER_PARSE_ERROR)
01555 {
01556 if (verbose)
01557 fprintf(stderr,
01558 "-- Warning: Couldn't get status information for table %s (%s)\n",
01559 result_table,mysql_error(sock));
01560 }
01561 }
01562 else if (!(row=mysql_fetch_row(tableRes)))
01563 {
01564 fprintf(stderr,
01565 "Error: Couldn't read status information for table %s (%s)\n",
01566 result_table,mysql_error(sock));
01567 }
01568 else
01569 {
01570 if (opt_xml)
01571 {
01572 print_xml_row(sql_file, "options", tableRes, &row);
01573 }
01574 else
01575 {
01576 fputs("",sql_file);
01581 check_io(sql_file);
01582 }
01583 }
01584 mysql_free_result(tableRes);
01585 }
01586 continue_xml:
01587 if (!opt_xml)
01588 fputs(";\n", sql_file);
01589 else
01590 fputs("\t</table_structure>\n", sql_file);
01591 check_io(sql_file);
01592 }
01593 }
01594 if (opt_complete_insert)
01595 {
01596 dynstr_append_mem(&insert_pat, ") VALUES ", 9);
01597 if (!extended_insert)
01598 dynstr_append_mem(&insert_pat, "(", 1);
01599 }
01600 if (sql_file != md_result_file)
01601 {
01602 fputs("\n", sql_file);
01603 write_footer(sql_file);
01604 my_fclose(sql_file, MYF(MY_WME));
01605 }
01606 DBUG_RETURN(numFields);
01607 }
01608
01609
01610 static char *add_load_option(char *ptr,const char *object,
01611 const char *statement)
01612 {
01613 if (object)
01614 {
01615
01616 if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
01617 ptr= strxmov(ptr," ",statement," ",object,NullS);
01618 else
01619 {
01620
01621 ptr= strxmov(ptr," ",statement," '",NullS);
01622 ptr= field_escape(ptr,object,(uint) strlen(object));
01623 *ptr++= '\'';
01624 }
01625 }
01626 return ptr;
01627 }
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637 static char *field_escape(char *to,const char *from,uint length)
01638 {
01639 const char *end;
01640 uint end_backslashes=0;
01641
01642 for (end= from+length; from != end; from++)
01643 {
01644 *to++= *from;
01645 if (*from == '\\')
01646 end_backslashes^=1;
01647 else
01648 {
01649 if (*from == '\'' && !end_backslashes)
01650 *to++= *from;
01651 end_backslashes=0;
01652 }
01653 }
01654
01655 if (end_backslashes)
01656 *to++= '\\';
01657 return to;
01658 }
01659
01660
01661 static char *alloc_query_str(ulong size)
01662 {
01663 char *query;
01664
01665 if (!(query= (char*) my_malloc(size, MYF(MY_WME))))
01666 {
01667 ignore_errors= 0;
01668 safe_exit(EX_MYSQLERR);
01669 }
01670 return query;
01671 }
01672
01673
01674
01675
01676
01677
01678 static void dump_table(uint numFields, char *table)
01679 {
01680 char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
01681 char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
01682 char *query= query_buf;
01683 MYSQL_RES *res;
01684 MYSQL_FIELD *field;
01685 MYSQL_ROW row;
01686 ulong rownr, row_break, total_length, init_length;
01687 const char *table_type;
01688 int error= 0;
01689
01690
01691 if (dFlag)
01692 {
01693 if (verbose)
01694 fprintf(stderr,
01695 "-- Skipping dump data for table '%s', --no-data was used\n",
01696 table);
01697 return;
01698 }
01699
01700
01701 if (numFields == 0)
01702 {
01703 if (verbose)
01704 fprintf(stderr,
01705 "-- Skipping dump data for table '%s', it has no fields\n",
01706 table);
01707 return;
01708 }
01709
01710 result_table= quote_name(table,table_buff, 1);
01711 opt_quoted_table= quote_name(table, table_buff2, 0);
01712
01713
01714 if ((table_type= check_if_ignore_table(table)))
01715 {
01716 if (verbose)
01717 fprintf(stderr,
01718 "-- Skipping data for table '%s' because it's of type %s\n",
01719 table, table_type);
01720 return;
01721 }
01722
01723 if (verbose)
01724 fprintf(stderr, "-- Sending SELECT query...\n");
01725 if (path)
01726 {
01727 char filename[FN_REFLEN], tmp_path[FN_REFLEN];
01728 convert_dirname(tmp_path,path,NullS);
01729 my_load_path(tmp_path, tmp_path, NULL);
01730 fn_format(filename, table, tmp_path, ".txt", 4);
01731 my_delete(filename, MYF(0));
01732
01733 to_unix_path(filename);
01734 my_snprintf(query, QUERY_LENGTH,
01735 "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'",
01736 filename);
01737 end= strend(query);
01738
01739 if (fields_terminated || enclosed || opt_enclosed || escaped)
01740 end= strmov(end, " FIELDS");
01741 end= add_load_option(end, fields_terminated, " TERMINATED BY");
01742 end= add_load_option(end, enclosed, " ENCLOSED BY");
01743 end= add_load_option(end, opt_enclosed, " OPTIONALLY ENCLOSED BY");
01744 end= add_load_option(end, escaped, " ESCAPED BY");
01745 end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
01746 *end= '\0';
01747
01748 my_snprintf(buff, sizeof(buff), " FROM %s", result_table);
01749 end= strmov(end,buff);
01750 if (where || order_by)
01751 {
01752 query = alloc_query_str((ulong) ((end - query) + 1 +
01753 (where ? strlen(where) + 7 : 0) +
01754 (order_by ? strlen(order_by) + 10 : 0)));
01755 end = strmov(query, query_buf);
01756
01757 if (where)
01758 end = strxmov(end, " WHERE ", where, NullS);
01759 if (order_by)
01760 end = strxmov(end, " ORDER BY ", order_by, NullS);
01761 }
01762 if (mysql_real_query(sock, query, (uint) (end - query)))
01763 {
01764 DB_error(sock, "when executing 'SELECT INTO OUTFILE'");
01765 return;
01766 }
01767 }
01768 else
01769 {
01770 if (!opt_xml && opt_comments)
01771 {
01772 fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
01773 result_table);
01774 check_io(md_result_file);
01775 }
01776 my_snprintf(query, QUERY_LENGTH,
01777 "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s",
01778 result_table);
01779 if (where || order_by)
01780 {
01781 query = alloc_query_str((ulong) (strlen(query) + 1 +
01782 (where ? strlen(where) + 7 : 0) +
01783 (order_by ? strlen(order_by) + 10 : 0)));
01784 end = strmov(query, query_buf);
01785
01786 if (where)
01787 {
01788 if (!opt_xml && opt_comments)
01789 {
01790 fprintf(md_result_file, "-- WHERE: %s\n", where);
01791 check_io(md_result_file);
01792 }
01793 end = strxmov(end, " WHERE ", where, NullS);
01794 }
01795 if (order_by)
01796 {
01797 if (!opt_xml && opt_comments)
01798 {
01799 fprintf(md_result_file, "-- ORDER BY: %s\n", order_by);
01800 check_io(md_result_file);
01801 }
01802 end = strxmov(end, " ORDER BY ", order_by, NullS);
01803 }
01804 }
01805 if (!opt_xml && !opt_compact)
01806 {
01807 fputs("\n", md_result_file);
01808 check_io(md_result_file);
01809 }
01810 if (mysql_query_with_error_report(sock, 0, query))
01811 DB_error(sock, "when retrieving data from server");
01812 if (quick)
01813 res=mysql_use_result(sock);
01814 else
01815 res=mysql_store_result(sock);
01816 if (!res)
01817 DB_error(sock, "when retrieving data from server");
01818 if (verbose)
01819 fprintf(stderr, "-- Retrieving rows...\n");
01820 if (mysql_num_fields(res) != numFields)
01821 {
01822 fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n",
01823 my_progname, result_table);
01824 error= EX_CONSCHECK;
01825 goto err;
01826 }
01827
01828 if (opt_disable_keys)
01829 {
01830 fprintf(md_result_file, "\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
01831 opt_quoted_table);
01832 check_io(md_result_file);
01833 }
01834 if (opt_lock)
01835 {
01836 fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
01837 check_io(md_result_file);
01838 }
01839
01840 total_length= opt_net_buffer_length;
01841 row_break=0;
01842 rownr=0;
01843 init_length=(uint) insert_pat.length+4;
01844 if (opt_xml)
01845 print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n");
01846
01847 if (opt_autocommit)
01848 {
01849 fprintf(md_result_file, "set autocommit=0;\n");
01850 check_io(md_result_file);
01851 }
01852
01853 while ((row=mysql_fetch_row(res)))
01854 {
01855 uint i;
01856 ulong *lengths=mysql_fetch_lengths(res);
01857 rownr++;
01858 if (!extended_insert && !opt_xml)
01859 {
01860 fputs(insert_pat.str,md_result_file);
01861 check_io(md_result_file);
01862 }
01863 mysql_field_seek(res,0);
01864
01865 if (opt_xml)
01866 {
01867 fputs("\t<row>\n", md_result_file);
01868 check_io(md_result_file);
01869 }
01870
01871 for (i = 0; i < mysql_num_fields(res); i++)
01872 {
01873 int is_blob;
01874 if (!(field = mysql_fetch_field(res)))
01875 {
01876 my_snprintf(query, QUERY_LENGTH,
01877 "%s: Not enough fields from table %s! Aborting.\n",
01878 my_progname, result_table);
01879 fputs(query,stderr);
01880 error= EX_CONSCHECK;
01881 goto err;
01882 }
01883
01884
01885
01886
01887
01888
01889 is_blob= (opt_hex_blob && field->charsetnr == 63 &&
01890 (field->type == MYSQL_TYPE_STRING ||
01891 field->type == MYSQL_TYPE_VAR_STRING ||
01892 field->type == MYSQL_TYPE_VARCHAR ||
01893 field->type == MYSQL_TYPE_BLOB ||
01894 field->type == MYSQL_TYPE_LONG_BLOB ||
01895 field->type == MYSQL_TYPE_MEDIUM_BLOB ||
01896 field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0;
01897 if (extended_insert)
01898 {
01899 ulong length = lengths[i];
01900 if (i == 0)
01901 dynstr_set(&extended_row,"(");
01902 else
01903 dynstr_append(&extended_row,",");
01904
01905 if (row[i])
01906 {
01907 if (length)
01908 {
01909 if (!IS_NUM_FIELD(field))
01910 {
01911
01912
01913
01914
01915
01916
01917
01918 if (dynstr_realloc(&extended_row,length * 2+2))
01919 {
01920 fputs("Aborting dump (out of memory)",stderr);
01921 error= EX_EOM;
01922 goto err;
01923 }
01924 if (opt_hex_blob && is_blob)
01925 {
01926 dynstr_append(&extended_row, "0x");
01927 extended_row.length+= mysql_hex_string(extended_row.str +
01928 extended_row.length,
01929 row[i], length);
01930 extended_row.str[extended_row.length]= '\0';
01931 }
01932 else
01933 {
01934 dynstr_append(&extended_row,"'");
01935 extended_row.length +=
01936 mysql_real_escape_string(&mysql_connection,
01937 &extended_row.str[extended_row.length],
01938 row[i],length);
01939 extended_row.str[extended_row.length]='\0';
01940 dynstr_append(&extended_row,"'");
01941 }
01942 }
01943 else
01944 {
01945
01946 char *ptr = row[i];
01947 if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
01948 my_isalpha(charset_info, ptr[1])))
01949 dynstr_append(&extended_row, "NULL");
01950 else
01951 {
01952 if (field->type == FIELD_TYPE_DECIMAL)
01953 {
01954
01955 dynstr_append(&extended_row, "'");
01956 dynstr_append(&extended_row, ptr);
01957 dynstr_append(&extended_row, "'");
01958 }
01959 else
01960 dynstr_append(&extended_row, ptr);
01961 }
01962 }
01963 }
01964 else
01965 dynstr_append(&extended_row,"''");
01966 }
01967 else if (dynstr_append(&extended_row,"NULL"))
01968 {
01969 fputs("Aborting dump (out of memory)",stderr);
01970 error= EX_EOM;
01971 goto err;
01972 }
01973 }
01974 else
01975 {
01976 if (i && !opt_xml)
01977 {
01978 fputc(',', md_result_file);
01979 check_io(md_result_file);
01980 }
01981 if (row[i])
01982 {
01983 if (!IS_NUM_FIELD(field))
01984 {
01985 if (opt_xml)
01986 {
01987 print_xml_tag1(md_result_file, "\t\t", "field name=",
01988 field->name, "");
01989 print_quoted_xml(md_result_file, row[i], lengths[i]);
01990 fputs("</field>\n", md_result_file);
01991 }
01992 else if (opt_hex_blob && is_blob)
01993 {
01994
01995 char *ptr= row[i], *end= ptr+ lengths[i];
01996 fputs("0x", md_result_file);
01997 for (; ptr < end ; ptr++)
01998 fprintf(md_result_file, "%02X", *((uchar *)ptr));
01999 }
02000 else
02001 unescape(md_result_file, row[i], lengths[i]);
02002 }
02003 else
02004 {
02005
02006 char *ptr = row[i];
02007 if (opt_xml)
02008 {
02009 print_xml_tag1(md_result_file, "\t\t", "field name=",
02010 field->name, "");
02011 fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
02012 md_result_file);
02013 fputs("</field>\n", md_result_file);
02014 }
02015 else if (my_isalpha(charset_info, *ptr) ||
02016 (*ptr == '-' && my_isalpha(charset_info, ptr[1])))
02017 fputs("NULL", md_result_file);
02018 else if (field->type == FIELD_TYPE_DECIMAL)
02019 {
02020
02021 fputc('\'', md_result_file);
02022 fputs(ptr, md_result_file);
02023 fputc('\'', md_result_file);
02024 }
02025 else
02026 fputs(ptr, md_result_file);
02027 }
02028 }
02029 else
02030 {
02031
02032 if (!opt_xml)
02033 fputs("NULL", md_result_file);
02034 else
02035 print_xml_null_tag(md_result_file, "\t\t", "field name=",
02036 field->name, "\n");
02037 }
02038 check_io(md_result_file);
02039 }
02040 }
02041
02042 if (opt_xml)
02043 {
02044 fputs("\t</row>\n", md_result_file);
02045 check_io(md_result_file);
02046 }
02047
02048 if (extended_insert)
02049 {
02050 ulong row_length;
02051 dynstr_append(&extended_row,")");
02052 row_length = 2 + extended_row.length;
02053 if (total_length + row_length < opt_net_buffer_length)
02054 {
02055 total_length += row_length;
02056 fputc(',',md_result_file);
02057 fputs(extended_row.str,md_result_file);
02058 }
02059 else
02060 {
02061 if (row_break)
02062 fputs(";\n", md_result_file);
02063 row_break=1;
02064
02065 fputs(insert_pat.str,md_result_file);
02066 fputs(extended_row.str,md_result_file);
02067 total_length = row_length+init_length;
02068 }
02069 check_io(md_result_file);
02070 }
02071 else if (!opt_xml)
02072 {
02073 fputs(");\n", md_result_file);
02074 check_io(md_result_file);
02075 }
02076 }
02077
02078
02079 if (opt_xml)
02080 fputs("\t</table_data>\n", md_result_file);
02081 else if (extended_insert && row_break)
02082 fputs(";\n", md_result_file);
02083 fflush(md_result_file);
02084 check_io(md_result_file);
02085 if (mysql_errno(sock))
02086 {
02087 my_snprintf(query, QUERY_LENGTH,
02088 "%s: Error %d: %s when dumping table %s at row: %ld\n",
02089 my_progname,
02090 mysql_errno(sock),
02091 mysql_error(sock),
02092 result_table,
02093 rownr);
02094 fputs(query,stderr);
02095 error= EX_CONSCHECK;
02096 goto err;
02097 }
02098 if (opt_lock)
02099 {
02100 fputs("UNLOCK TABLES;\n", md_result_file);
02101 check_io(md_result_file);
02102 }
02103 if (opt_disable_keys)
02104 {
02105 fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
02106 opt_quoted_table);
02107 check_io(md_result_file);
02108 }
02109 if (opt_autocommit)
02110 {
02111 fprintf(md_result_file, "commit;\n");
02112 check_io(md_result_file);
02113 }
02114 mysql_free_result(res);
02115 if (query != query_buf)
02116 my_free(query, MYF(MY_ALLOW_ZERO_PTR));
02117 }
02118 return;
02119
02120 err:
02121 if (query != query_buf)
02122 my_free(query, MYF(MY_ALLOW_ZERO_PTR));
02123 safe_exit(error);
02124 return;
02125 }
02126
02127
02128 static char *getTableName(int reset)
02129 {
02130 static MYSQL_RES *res = NULL;
02131 MYSQL_ROW row;
02132
02133 if (!res)
02134 {
02135 if (!(res = mysql_list_tables(sock,NullS)))
02136 return(NULL);
02137 }
02138 if ((row = mysql_fetch_row(res)))
02139 return((char*) row[0]);
02140
02141 if (reset)
02142 mysql_data_seek(res,0);
02143 else
02144 {
02145 mysql_free_result(res);
02146 res = NULL;
02147 }
02148 return(NULL);
02149 }
02150
02151
02152 static int dump_all_databases()
02153 {
02154 MYSQL_ROW row;
02155 MYSQL_RES *tableres;
02156 int result=0;
02157
02158 if (mysql_query_with_error_report(sock, &tableres, "SHOW DATABASES"))
02159 return 1;
02160 while ((row = mysql_fetch_row(tableres)))
02161 {
02162 if (dump_all_tables_in_db(row[0]))
02163 result=1;
02164 }
02165 if (was_views)
02166 {
02167 if (mysql_query(sock, "SHOW DATABASES") ||
02168 !(tableres = mysql_store_result(sock)))
02169 {
02170 my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
02171 MYF(0), mysql_error(sock));
02172 return 1;
02173 }
02174 while ((row = mysql_fetch_row(tableres)))
02175 {
02176 if (dump_all_views_in_db(row[0]))
02177 result=1;
02178 }
02179 }
02180 return result;
02181 }
02182
02183
02184
02185 static int dump_databases(char **db_names)
02186 {
02187 int result=0;
02188 char **db;
02189 for (db= db_names ; *db ; db++)
02190 {
02191 if (dump_all_tables_in_db(*db))
02192 result=1;
02193 }
02194 if (!result && was_views)
02195 {
02196 for (db= db_names ; *db ; db++)
02197 {
02198 if (dump_all_views_in_db(*db))
02199 result=1;
02200 }
02201 }
02202 return result;
02203 }
02204
02205
02206 static int init_dumping(char *database)
02207 {
02208 if (mysql_get_server_version(sock) >= 50003 &&
02209 !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
02210 return 1;
02211
02212 if (mysql_select_db(sock, database))
02213 {
02214 DB_error(sock, "when selecting the database");
02215 return 1;
02216 }
02217 if (!path && !opt_xml)
02218 {
02219 if (opt_databases || opt_alldbs)
02220 {
02221
02222
02223
02224 char quoted_database_buf[64*2+3];
02225 char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
02226 if (opt_comments)
02227 {
02228 fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
02229 check_io(md_result_file);
02230 }
02231 if (!opt_create_db)
02232 {
02233 char qbuf[256];
02234 MYSQL_ROW row;
02235 MYSQL_RES *dbinfo;
02236
02237 my_snprintf(qbuf, sizeof(qbuf),
02238 "SHOW CREATE DATABASE IF NOT EXISTS %s",
02239 qdatabase);
02240
02241 if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock)))
02242 {
02243
02244 if (opt_drop_database)
02245 fprintf(md_result_file,
02246 "\n/*!40000 DROP DATABASE IF EXISTS %s;*/\n",
02247 qdatabase);
02248 fprintf(md_result_file,
02249 "\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
02250 qdatabase);
02251 }
02252 else
02253 {
02254 if (opt_drop_database)
02255 fprintf(md_result_file,
02256 "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
02257 qdatabase);
02258 row = mysql_fetch_row(dbinfo);
02259 if (row[1])
02260 {
02261 fprintf(md_result_file,"\n%s;\n",row[1]);
02262 }
02263 }
02264 }
02265 fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
02266 check_io(md_result_file);
02267 }
02268 }
02269 if (extended_insert && init_dynamic_string(&extended_row, "", 1024, 1024))
02270 exit(EX_EOM);
02271 return 0;
02272 }
02273
02274
02275 my_bool include_table(byte* hash_key, uint len)
02276 {
02277 if (hash_search(&ignore_table, (byte*) hash_key, len))
02278 return FALSE;
02279
02280 return TRUE;
02281 }
02282
02283
02284 static int dump_all_tables_in_db(char *database)
02285 {
02286 char *table;
02287 uint numrows;
02288 char table_buff[NAME_LEN*2+3];
02289
02290 char hash_key[2*NAME_LEN+2];
02291 char *afterdot;
02292
02293 afterdot= strmov(hash_key, database);
02294 *afterdot++= '.';
02295
02296 if (init_dumping(database))
02297 return 1;
02298 if (opt_xml)
02299 print_xml_tag1(md_result_file, "", "database name=", database, "\n");
02300 if (lock_tables)
02301 {
02302 DYNAMIC_STRING query;
02303 init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
02304 for (numrows= 0 ; (table= getTableName(1)) ; numrows++)
02305 {
02306 dynstr_append(&query, quote_name(table, table_buff, 1));
02307 dynstr_append(&query, " READ /*!32311 LOCAL */,");
02308 }
02309 if (numrows && mysql_real_query(sock, query.str, query.length-1))
02310 DB_error(sock, "when using LOCK TABLES");
02311
02312 dynstr_free(&query);
02313 }
02314 if (flush_logs)
02315 {
02316 if (mysql_refresh(sock, REFRESH_LOG))
02317 DB_error(sock, "when doing refresh");
02318
02319 }
02320 while ((table= getTableName(0)))
02321 {
02322 char *end= strmov(afterdot, table);
02323 if (include_table(hash_key, end - hash_key))
02324 {
02325 numrows = get_table_structure(table, database);
02326 dump_table(numrows,table);
02327 my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
02328 order_by= 0;
02329 }
02330 }
02331 if (opt_xml)
02332 {
02333 fputs("</database>\n", md_result_file);
02334 check_io(md_result_file);
02335 }
02336 if (lock_tables)
02337 mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
02338 return 0;
02339 }
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354 static my_bool dump_all_views_in_db(char *database)
02355 {
02356 char *table;
02357 uint numrows;
02358 char table_buff[NAME_LEN*2+3];
02359
02360 if (init_dumping(database))
02361 return 1;
02362 if (opt_xml)
02363 print_xml_tag1(md_result_file, "", "database name=", database, "\n");
02364 if (lock_tables)
02365 {
02366 DYNAMIC_STRING query;
02367 init_dynamic_string(&query, "LOCK TABLES ", 256, 1024);
02368 for (numrows= 0 ; (table= getTableName(1)); numrows++)
02369 {
02370 dynstr_append(&query, quote_name(table, table_buff, 1));
02371 dynstr_append(&query, " READ /*!32311 LOCAL */,");
02372 }
02373 if (numrows && mysql_real_query(sock, query.str, query.length-1))
02374 DB_error(sock, "when using LOCK TABLES");
02375
02376 dynstr_free(&query);
02377 }
02378 if (flush_logs)
02379 {
02380 if (mysql_refresh(sock, REFRESH_LOG))
02381 DB_error(sock, "when doing refresh");
02382
02383 }
02384 while ((table= getTableName(0)))
02385 get_view_structure(table, database);
02386 if (opt_xml)
02387 {
02388 fputs("</database>\n", md_result_file);
02389 check_io(md_result_file);
02390 }
02391 if (lock_tables)
02392 mysql_query(sock,"UNLOCK TABLES");
02393 return 0;
02394 }
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407 static int get_actual_table_name(const char *old_table_name,
02408 char *new_table_name,
02409 int buf_size)
02410 {
02411 int retval;
02412 MYSQL_RES *table_res;
02413 MYSQL_ROW row;
02414 char query[50 + 2*NAME_LEN];
02415 char show_name_buff[FN_REFLEN];
02416 DBUG_ENTER("get_actual_table_name");
02417
02418
02419 DBUG_ASSERT(2*sizeof(old_table_name) < sizeof(show_name_buff));
02420 my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
02421 quote_for_like(old_table_name, show_name_buff));
02422
02423 if (mysql_query_with_error_report(sock, 0, query))
02424 {
02425 safe_exit(EX_MYSQLERR);
02426 }
02427
02428 retval = 1;
02429
02430 if ((table_res= mysql_store_result(sock)))
02431 {
02432 my_ulonglong num_rows= mysql_num_rows(table_res);
02433 if (num_rows > 0)
02434 {
02435
02436
02437
02438
02439 row= mysql_fetch_row(table_res);
02440 strmake(new_table_name, row[0], buf_size-1);
02441 retval= 0;
02442 }
02443 mysql_free_result(table_res);
02444 }
02445 return retval;
02446 }
02447
02448
02449 static int dump_selected_tables(char *db, char **table_names, int tables)
02450 {
02451 uint numrows, i;
02452 char table_buff[NAME_LEN*+3];
02453 char new_table_name[NAME_LEN];
02454 DYNAMIC_STRING lock_tables_query;
02455 HASH dump_tables;
02456 char *table_name;
02457 DBUG_ENTER("dump_selected_tables");
02458
02459 if (init_dumping(db))
02460 return 1;
02461
02462
02463 if (hash_init(&dump_tables, charset_info, 16, 0, 0,
02464 (hash_get_key) get_table_key, (hash_free_key) free_table_ent,
02465 0))
02466 exit(EX_EOM);
02467
02468 init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024);
02469 for (; tables > 0 ; tables-- , table_names++)
02470 {
02471
02472 if (!get_actual_table_name(*table_names,
02473 new_table_name, sizeof(new_table_name)))
02474 {
02475
02476 if (lock_tables)
02477 {
02478 dynstr_append(&lock_tables_query,
02479 quote_name(new_table_name, table_buff, 1));
02480 dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,");
02481 }
02482
02483
02484 if (my_hash_insert(&dump_tables,
02485 (byte*)my_strdup(new_table_name, MYF(0))))
02486 exit(EX_EOM);
02487
02488 }
02489 else
02490 {
02491 my_printf_error(0,"Couldn't find table: \"%s\"\n", MYF(0),
02492 *table_names);
02493 safe_exit(EX_ILLEGAL_TABLE);
02494
02495 }
02496 }
02497
02498 if (lock_tables)
02499 {
02500 if (mysql_real_query(sock, lock_tables_query.str,
02501 lock_tables_query.length-1))
02502 DB_error(sock, "when doing LOCK TABLES");
02503
02504 }
02505 dynstr_free(&lock_tables_query);
02506 if (flush_logs)
02507 {
02508 if (mysql_refresh(sock, REFRESH_LOG))
02509 DB_error(sock, "when doing refresh");
02510
02511 }
02512 if (opt_xml)
02513 print_xml_tag1(md_result_file, "", "database name=", db, "\n");
02514
02515
02516 for (i= 0; i < dump_tables.records; i++)
02517 {
02518 table_name= hash_element(&dump_tables, i);
02519 DBUG_PRINT("info",("Dumping table %s", table_name));
02520 numrows= get_table_structure(table_name, db);
02521 dump_table(numrows, table_name);
02522 }
02523
02524
02525 if (was_views)
02526 {
02527 for(i=0; i < dump_tables.records; i++)
02528 {
02529 table_name= hash_element(&dump_tables, i);
02530 get_view_structure(table_name, db);
02531 }
02532 }
02533 hash_free(&dump_tables);
02534 my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
02535 order_by= 0;
02536 if (opt_xml)
02537 {
02538 fputs("</database>\n", md_result_file);
02539 check_io(md_result_file);
02540 }
02541 if (lock_tables)
02542 mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
02543 DBUG_RETURN(0);
02544 }
02545
02546
02547 static int do_show_master_status(MYSQL *mysql_con)
02548 {
02549 MYSQL_ROW row;
02550 MYSQL_RES *master;
02551 const char *comment_prefix=
02552 (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
02553 if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
02554 {
02555 my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s",
02556 MYF(0), mysql_error(mysql_con));
02557 return 1;
02558 }
02559 else
02560 {
02561 row = mysql_fetch_row(master);
02562 if (row && row[0] && row[1])
02563 {
02564
02565 if (opt_comments)
02566 fprintf(md_result_file,
02567 "\n--\n-- Position to start replication or point-in-time "
02568 "recovery from\n--\n\n");
02569 fprintf(md_result_file,
02570 "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
02571 comment_prefix, row[0], row[1]);
02572 check_io(md_result_file);
02573 }
02574 else if (!ignore_errors)
02575 {
02576
02577 my_printf_error(0, "Error: Binlogging on server not active",
02578 MYF(0), mysql_error(mysql_con));
02579 mysql_free_result(master);
02580 return 1;
02581 }
02582 mysql_free_result(master);
02583 }
02584 return 0;
02585 }
02586
02587
02588 static int do_flush_tables_read_lock(MYSQL *mysql_con)
02589 {
02590
02591
02592
02593
02594
02595
02596
02597
02598 return
02599 ( mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES") ||
02600 mysql_query_with_error_report(mysql_con, 0,
02601 "FLUSH TABLES WITH READ LOCK") );
02602 }
02603
02604
02605 static int do_unlock_tables(MYSQL *mysql_con)
02606 {
02607 return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES");
02608 }
02609
02610
02611 static int do_reset_master(MYSQL *mysql_con)
02612 {
02613 return mysql_query_with_error_report(mysql_con, 0, "RESET MASTER");
02614 }
02615
02616
02617 static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now)
02618 {
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628 return (mysql_query_with_error_report(mysql_con, 0,
02629 "SET SESSION TRANSACTION ISOLATION "
02630 "LEVEL REPEATABLE READ") ||
02631 mysql_query_with_error_report(mysql_con, 0,
02632 consistent_read_now ?
02633 "START TRANSACTION "
02634 "WITH CONSISTENT SNAPSHOT" :
02635 "BEGIN"));
02636 }
02637
02638
02639 static ulong find_set(TYPELIB *lib, const char *x, uint length,
02640 char **err_pos, uint *err_len)
02641 {
02642 const char *end= x + length;
02643 ulong found= 0;
02644 uint find;
02645 char buff[255];
02646
02647 *err_pos= 0;
02648 while (end > x && my_isspace(charset_info, end[-1]))
02649 end--;
02650
02651 *err_len= 0;
02652 if (x != end)
02653 {
02654 const char *start= x;
02655 for (;;)
02656 {
02657 const char *pos= start;
02658 uint var_len;
02659
02660 for (; pos != end && *pos != ','; pos++) ;
02661 var_len= (uint) (pos - start);
02662 strmake(buff, start, min(sizeof(buff), var_len));
02663 find= find_type(buff, lib, var_len);
02664 if (!find)
02665 {
02666 *err_pos= (char*) start;
02667 *err_len= var_len;
02668 }
02669 else
02670 found|= ((longlong) 1 << (find - 1));
02671 if (pos == end)
02672 break;
02673 start= pos + 1;
02674 }
02675 }
02676 return found;
02677 }
02678
02679
02680
02681 static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
02682 const char *prefix, const char *name,
02683 int string_value)
02684 {
02685 MYSQL_FIELD *field;
02686 mysql_field_seek(result, 0);
02687
02688 for ( ; (field = mysql_fetch_field(result)) ; row++)
02689 {
02690 if (!strcmp(field->name,name))
02691 {
02692 if (row[0] && row[0][0] && strcmp(row[0],"0"))
02693 {
02694 fputc(' ',file);
02695 fputs(prefix, file);
02696 if (string_value)
02697 unescape(file,row[0],(uint) strlen(row[0]));
02698 else
02699 fputs(row[0], file);
02700 check_io(file);
02701 return;
02702 }
02703 }
02704 }
02705 return;
02706 }
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726 static const char *check_if_ignore_table(const char *table_name)
02727 {
02728 char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
02729 MYSQL_RES *res;
02730 MYSQL_ROW row;
02731 const char *result= 0;
02732
02733
02734 DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
02735 my_snprintf(buff, sizeof(buff), "show table status like %s",
02736 quote_for_like(table_name, show_name_buff));
02737 if (mysql_query_with_error_report(sock, &res, buff))
02738 {
02739 if (mysql_errno(sock) != ER_PARSE_ERROR)
02740 {
02741 if (verbose)
02742 fprintf(stderr,
02743 "-- Warning: Couldn't get status information for table %s (%s)\n",
02744 table_name,mysql_error(sock));
02745 return 0;
02746 }
02747 }
02748 if (!(row= mysql_fetch_row(res)))
02749 {
02750 fprintf(stderr,
02751 "Error: Couldn't read status information for table %s (%s)\n",
02752 table_name, mysql_error(sock));
02753 mysql_free_result(res);
02754 return 0;
02755 }
02756 if (!(row[1]))
02757 result= "VIEW";
02758 else
02759 {
02760 if (strcmp(row[1], (result= "MRG_MyISAM")) &&
02761 strcmp(row[1], (result= "MRG_ISAM")))
02762 result= 0;
02763 }
02764 mysql_free_result(res);
02765 return result;
02766 }
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785 static char *primary_key_fields(const char *table_name)
02786 {
02787 MYSQL_RES *res = NULL;
02788 MYSQL_ROW row;
02789
02790 char show_keys_buff[15 + 64 * 2 + 3];
02791 uint result_length = 0;
02792 char *result = 0;
02793
02794 my_snprintf(show_keys_buff, sizeof(show_keys_buff),
02795 "SHOW KEYS FROM %s", table_name);
02796 if (mysql_query(sock, show_keys_buff) ||
02797 !(res = mysql_store_result(sock)))
02798 {
02799 fprintf(stderr, "Warning: Couldn't read keys from table %s;"
02800 " records are NOT sorted (%s)\n",
02801 table_name, mysql_error(sock));
02802
02803 goto cleanup;
02804 }
02805
02806
02807
02808
02809
02810
02811
02812 if ((row = mysql_fetch_row(res)) && atoi(row[1]) == 0)
02813 {
02814
02815 do
02816 result_length += strlen(row[4]) + 1;
02817 while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1);
02818 }
02819
02820
02821 if (result_length) {
02822 char *end;
02823
02824 result = my_malloc(result_length + 10, MYF(MY_WME));
02825 if (!result) {
02826 fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
02827 goto cleanup;
02828 }
02829 mysql_data_seek(res, 0);
02830 row = mysql_fetch_row(res);
02831 end = strmov(result, row[4]);
02832 while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1)
02833 end = strxmov(end, ",", row[4], NullS);
02834 }
02835
02836 cleanup:
02837 if (res)
02838 mysql_free_result(res);
02839
02840 return result;
02841 }
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857 static my_bool get_view_structure(char *table, char* db)
02858 {
02859 MYSQL_RES *table_res;
02860 MYSQL_ROW row;
02861 MYSQL_FIELD *field;
02862 char *result_table, *opt_quoted_table;
02863 char table_buff[NAME_LEN*2+3];
02864 char table_buff2[NAME_LEN*2+3];
02865 char buff[20+FN_REFLEN];
02866 FILE *sql_file = md_result_file;
02867 DBUG_ENTER("get_view_structure");
02868
02869 if (tFlag)
02870 DBUG_RETURN(0);
02871
02872 if (verbose)
02873 fprintf(stderr, "-- Retrieving view structure for table %s...\n", table);
02874
02875 #ifdef NOT_REALLY_USED_YET
02876 sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
02877 (opt_quoted || opt_keywords));
02878 #endif
02879
02880 result_table= quote_name(table, table_buff, 1);
02881 opt_quoted_table= quote_name(table, table_buff2, 0);
02882
02883 sprintf(buff,"show create table %s", result_table);
02884 if (mysql_query(sock, buff))
02885 {
02886 fprintf(stderr, "%s: Can't get CREATE TABLE for view %s (%s)\n",
02887 my_progname, result_table, mysql_error(sock));
02888 safe_exit(EX_MYSQLERR);
02889 DBUG_RETURN(0);
02890 }
02891
02892 if (path)
02893 {
02894 char filename[FN_REFLEN], tmp_path[FN_REFLEN];
02895 convert_dirname(tmp_path,path,NullS);
02896 sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
02897 O_WRONLY, MYF(MY_WME));
02898 if (!sql_file)
02899 {
02900 safe_exit(EX_MYSQLERR);
02901 DBUG_RETURN(1);
02902 }
02903 write_header(sql_file, db);
02904 }
02905 table_res= mysql_store_result(sock);
02906 field= mysql_fetch_field_direct(table_res, 0);
02907 if (strcmp(field->name, "View") != 0)
02908 {
02909 if (verbose)
02910 fprintf(stderr, "-- It's base table, skipped\n");
02911 DBUG_RETURN(0);
02912 }
02913
02914 if (!opt_xml && opt_comments)
02915 {
02916 fprintf(sql_file, "\n--\n-- View structure for view %s\n--\n\n",
02917 result_table);
02918 check_io(sql_file);
02919 }
02920 if (opt_drop)
02921 {
02922 fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
02923 fprintf(sql_file, "DROP VIEW IF EXISTS %s;\n", opt_quoted_table);
02924 check_io(sql_file);
02925 }
02926
02927 row= mysql_fetch_row(table_res);
02928 fprintf(sql_file, "%s;\n", row[1]);
02929 check_io(sql_file);
02930 mysql_free_result(table_res);
02931
02932 if (sql_file != md_result_file)
02933 {
02934 fputs("\n", sql_file);
02935 write_footer(sql_file);
02936 my_fclose(sql_file, MYF(MY_WME));
02937 }
02938 DBUG_RETURN(0);
02939 }
02940
02941
02942 int main(int argc, char **argv)
02943 {
02944 compatible_mode_normal_str[0]= 0;
02945 default_charset= (char *)mysql_universal_client_charset;
02946 bzero((char*) &ignore_table, sizeof(ignore_table));
02947
02948 MY_INIT("mysqldump");
02949 if (get_options(&argc, &argv))
02950 {
02951 my_end(0);
02952 exit(EX_USAGE);
02953 }
02954 if (dbConnect(current_host, current_user, opt_password))
02955 exit(EX_MYSQLERR);
02956 if (!path)
02957 write_header(md_result_file, *argv);
02958
02959 if ((opt_lock_all_tables || opt_master_data) &&
02960 do_flush_tables_read_lock(sock))
02961 goto err;
02962 if (opt_single_transaction && start_transaction(sock, test(opt_master_data)))
02963 goto err;
02964 if (opt_delete_master_logs && do_reset_master(sock))
02965 goto err;
02966 if (opt_lock_all_tables || opt_master_data)
02967 {
02968 if (flush_logs && mysql_refresh(sock, REFRESH_LOG))
02969 goto err;
02970 flush_logs= 0;
02971 }
02972 if (opt_master_data && do_show_master_status(sock))
02973 goto err;
02974 if (opt_single_transaction && do_unlock_tables(sock))
02975 goto err;
02976
02977 if (opt_alldbs)
02978 dump_all_databases();
02979 else if (argc > 1 && !opt_databases)
02980 {
02981
02982 dump_selected_tables(*argv, (argv + 1), (argc - 1));
02983 }
02984 else
02985 {
02986
02987 dump_databases(argv);
02988 }
02989 #ifdef HAVE_SMEM
02990 my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
02991 #endif
02992
02993
02994
02995
02996
02997
02998 err:
02999 dbDisconnect(current_host);
03000 if (!path)
03001 write_footer(md_result_file);
03002 if (md_result_file != stdout)
03003 my_fclose(md_result_file, MYF(0));
03004 my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
03005 if (hash_inited(&ignore_table))
03006 hash_free(&ignore_table);
03007 if (extended_insert)
03008 dynstr_free(&extended_row);
03009 if (insert_pat_inited)
03010 dynstr_free(&insert_pat);
03011 my_end(0);
03012 return(first_error);
03013 }