2001-12-06 13:10:51 +01:00
/* Copyright (C) 2000 MySQL AB
2000-08-30 19:40:59 +02:00
2000-07-31 21:29:14 +02:00
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 .
2000-08-30 19:40:59 +02:00
2000-07-31 21:29:14 +02:00
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 .
2000-08-30 19:40:59 +02:00
2000-07-31 21:29:14 +02:00
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 */
/* mysqldump.c - Dump a tables contents and format to an ASCII file
* *
* * The author ' s original notes follow : -
* *
2001-10-04 19:43:06 +02:00
* * AUTHOR : Igor Romanenko ( igor @ frog . kiev . ua )
* * DATE : December 3 , 1994
* * WARRANTY : None , expressed , impressed , implied
2006-05-25 10:00:28 +02:00
* * or other
2001-10-04 19:43:06 +02:00
* * STATUS : Public domain
* * Adapted and optimized for MySQL by
* * Michael Widenius , Sinisa Milivojevic , Jani Tolonen
* * - w - - where added 9 / 10 / 98 by Jim Faucette
* * slave code by David Saez Padros < david @ ols . es >
* * master / autocommit code by Brian Aker < brian @ tangent . org >
* * SSL by
* * Andrei Errapart < andreie @ no . spam . ee >
2005-10-11 23:58:22 +02:00
* * Tõnu Samuel < tonu @ please . do . not . remove . this . spam . ee >
2001-11-05 22:48:03 +01:00
* * XML by Gary Huntress < ghuntress @ mediaone . net > 10 / 10 / 01 , cleaned up
* * and adapted to mysqldump 05 / 11 / 01 by Jani Tolonen
2002-06-11 11:37:48 +02:00
* * Added - - single - transaction option 06 / 06 / 2002 by Peter Zaitsev
2003-06-10 08:34:00 +02:00
* * 10 Jun 2003 : SET NAMES and - - no - set - names by Alexander Barkov
2001-11-05 22:48:03 +01:00
*/
2000-07-31 21:29:14 +02:00
2005-04-04 23:32:48 +02:00
# define DUMP_VERSION "10.10"
2000-07-31 21:29:14 +02:00
2001-09-14 01:54:33 +02:00
# include <my_global.h>
2000-07-31 21:29:14 +02:00
# include <my_sys.h>
2006-01-11 00:07:40 +01:00
# include <my_user.h>
2000-07-31 21:29:14 +02:00
# include <m_string.h>
# include <m_ctype.h>
2004-12-27 19:10:30 +01:00
# include <hash.h>
2006-10-19 00:43:51 +02:00
# include <stdarg.h>
2000-07-31 21:29:14 +02:00
2001-10-31 02:22:31 +01:00
# include "client_priv.h"
2000-07-31 21:29:14 +02:00
# include "mysql.h"
# include "mysql_version.h"
# include "mysqld_error.h"
/* Exit codes */
# define EX_USAGE 1
# define EX_MYSQLERR 2
# define EX_CONSCHECK 3
# define EX_EOM 4
2004-06-24 22:14:12 +02:00
# define EX_EOF 5 /* ferror for output file was got */
2005-06-21 14:19:56 +02:00
# define EX_ILLEGAL_TABLE 6
2000-07-31 21:29:14 +02:00
/* index into 'show fields from table' */
# define SHOW_FIELDNAME 0
# define SHOW_TYPE 1
# define SHOW_NULL 2
# define SHOW_DEFAULT 4
# define SHOW_EXTRA 5
2002-04-27 11:09:59 +02:00
/* Size of buffer for dump's select query */
# define QUERY_LENGTH 1536
2005-09-27 07:43:09 +02:00
/* ignore table flags */
# define IGNORE_NONE 0x00 /* no ignore */
# define IGNORE_DATA 0x01 /* don't dump data for this table */
# define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
2000-07-31 21:29:14 +02:00
static char * add_load_option ( char * ptr , const char * object ,
2006-05-25 10:00:28 +02:00
const char * statement ) ;
2003-01-16 04:35:59 +01:00
static ulong find_set ( TYPELIB * lib , const char * x , uint length ,
2006-05-25 10:00:28 +02:00
char * * err_pos , uint * err_len ) ;
2006-03-02 13:18:49 +01:00
static char * alloc_query_str ( ulong size ) ;
2000-07-31 21:29:14 +02:00
static char * field_escape ( char * to , const char * from , uint length ) ;
2006-07-24 11:56:01 +02:00
static my_bool verbose = 0 , opt_no_create_info = 0 , opt_no_data = 0 ,
quick = 1 , extended_insert = 1 ,
2006-09-14 20:56:14 +02:00
lock_tables = 1 , ignore_errors = 0 , flush_logs = 0 , flush_privileges = 0 ,
2006-05-25 10:00:28 +02:00
opt_drop = 1 , opt_keywords = 0 , opt_lock = 1 , opt_compress = 0 ,
2003-01-16 04:35:59 +01:00
opt_delayed = 0 , create_options = 1 , opt_quoted = 0 , opt_databases = 0 ,
2005-05-18 18:25:06 +02:00
opt_alldbs = 0 , opt_create_db = 0 , opt_lock_all_tables = 0 ,
opt_set_charset = 0 ,
2006-05-25 10:00:28 +02:00
opt_autocommit = 0 , opt_disable_keys = 1 , opt_xml = 0 ,
opt_delete_master_logs = 0 , tty_password = 0 ,
opt_single_transaction = 0 , opt_comments = 0 , opt_compact = 0 ,
opt_hex_blob = 0 , opt_order_by_primary = 0 , opt_ignore = 0 ,
2005-07-22 04:11:45 +02:00
opt_complete_insert = 0 , opt_drop_database = 0 ,
2005-10-13 07:44:42 +02:00
opt_dump_triggers = 0 , opt_routines = 0 , opt_tz_utc = 1 ;
2004-05-26 18:40:27 +02:00
static ulong opt_max_allowed_packet , opt_net_buffer_length ;
2006-07-24 12:00:44 +02:00
static MYSQL mysql_connection , * mysql = 0 ;
2005-05-08 21:02:46 +02:00
static my_bool insert_pat_inited = 0 ;
static DYNAMIC_STRING insert_pat ;
static char * opt_password = 0 , * current_user = 0 ,
2000-07-31 21:29:14 +02:00
* current_host = 0 , * path = 0 , * fields_terminated = 0 ,
* lines_terminated = 0 , * enclosed = 0 , * opt_enclosed = 0 , * escaped = 0 ,
2004-11-16 23:45:24 +01:00
* where = 0 , * order_by = 0 ,
2003-03-16 08:20:45 +01:00
* opt_compatible_mode_str = 0 ,
2003-01-16 04:35:59 +01:00
* err_ptr = 0 ;
2004-03-11 15:46:27 +01:00
static char compatible_mode_normal_str [ 255 ] ;
2003-01-16 04:35:59 +01:00
static ulong opt_compatible_mode = 0 ;
2004-11-10 17:56:45 +01:00
# define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
# define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
static uint opt_mysql_port = 0 , err_len = 0 , opt_master_data ;
2000-07-31 21:29:14 +02:00
static my_string opt_mysql_unix_port = 0 ;
static int first_error = 0 ;
static DYNAMIC_STRING extended_row ;
2002-09-17 22:46:53 +02:00
# include <sslopt-vars.h>
2001-08-22 00:45:07 +02:00
FILE * md_result_file ;
2002-11-14 20:16:30 +01:00
# ifdef HAVE_SMEM
static char * shared_memory_base_name = 0 ;
# endif
2003-01-16 04:35:59 +01:00
static uint opt_protocol = 0 ;
2005-01-06 18:13:58 +01:00
/*
2005-01-06 19:47:08 +01:00
Constant for detection of default value of default_charset .
If default_charset is equal to mysql_universal_client_charset , then
it is the default value which assigned at the very beginning of main ( ) .
2005-01-06 18:13:58 +01:00
*/
2005-01-06 19:47:08 +01:00
static const char * mysql_universal_client_charset =
2005-01-06 18:13:58 +01:00
MYSQL_UNIVERSAL_CLIENT_CHARSET ;
static char * default_charset ;
2003-03-16 08:20:45 +01:00
static CHARSET_INFO * charset_info = & my_charset_latin1 ;
2004-04-27 16:32:40 +02:00
const char * default_dbug_option = " d:t:o,/tmp/mysqldump.trace " ;
2006-05-25 10:00:28 +02:00
/* have we seen any VIEWs during table scanning? */
my_bool seen_views = 0 ;
2003-01-16 04:35:59 +01:00
const char * compatible_mode_names [ ] =
{
" MYSQL323 " , " MYSQL40 " , " POSTGRESQL " , " ORACLE " , " MSSQL " , " DB2 " ,
2004-01-15 03:26:57 +01:00
" MAXDB " , " NO_KEY_OPTIONS " , " NO_TABLE_OPTIONS " , " NO_FIELD_OPTIONS " ,
" ANSI " ,
2003-01-16 04:35:59 +01:00
NullS
} ;
2004-03-11 15:46:27 +01:00
# define MASK_ANSI_QUOTES \
( \
( 1 < < 2 ) | /* POSTGRESQL */ \
( 1 < < 3 ) | /* ORACLE */ \
( 1 < < 4 ) | /* MSSQL */ \
( 1 < < 5 ) | /* DB2 */ \
( 1 < < 6 ) | /* MAXDB */ \
( 1 < < 10 ) /* ANSI */ \
)
2003-01-16 04:35:59 +01:00
TYPELIB compatible_mode_typelib = { array_elements ( compatible_mode_names ) - 1 ,
2006-05-25 10:00:28 +02:00
" " , compatible_mode_names , NULL } ;
2003-01-16 04:35:59 +01:00
2004-12-27 19:10:30 +01:00
HASH ignore_table ;
2000-07-31 21:29:14 +02:00
2002-04-02 19:29:53 +02:00
static struct my_option my_long_options [ ] =
2000-07-31 21:29:14 +02:00
{
2004-06-26 23:00:23 +02:00
{ " all " , ' a ' , " Deprecated. Use --create-options instead. " ,
( gptr * ) & create_options , ( gptr * ) & create_options , 0 , GET_BOOL , NO_ARG , 1 ,
0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " all-databases " , ' A ' ,
" Dump all the databases. This will be same as --databases with all databases selected. " ,
( gptr * ) & opt_alldbs , ( gptr * ) & opt_alldbs , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
2005-05-20 15:56:02 +02:00
{ " add-drop-database " , OPT_DROP_DATABASE , " Add a 'DROP DATABASE' before each create. " ,
( gptr * ) & opt_drop_database , ( gptr * ) & opt_drop_database , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 ,
0 } ,
2002-04-02 19:29:53 +02:00
{ " add-drop-table " , OPT_DROP , " Add a 'drop table' before each create. " ,
2003-01-16 04:35:59 +01:00
( gptr * ) & opt_drop , ( gptr * ) & opt_drop , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 ,
2002-04-02 19:29:53 +02:00
0 } ,
{ " add-locks " , OPT_LOCKS , " Add locks around insert statements. " ,
2003-01-16 04:35:59 +01:00
( gptr * ) & opt_lock , ( gptr * ) & opt_lock , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 ,
2002-04-02 19:29:53 +02:00
0 } ,
{ " allow-keywords " , OPT_KEYWORDS ,
" Allow creation of column names that are keywords. " , ( gptr * ) & opt_keywords ,
( gptr * ) & opt_keywords , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2005-08-24 21:03:34 +02:00
# ifdef __NETWARE__
2005-11-18 18:25:46 +01:00
{ " autoclose " , OPT_AUTO_CLOSE , " Auto close the screen on exit for Netware. " ,
2005-08-24 21:03:34 +02:00
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
# endif
2002-04-02 19:29:53 +02:00
{ " character-sets-dir " , OPT_CHARSETS_DIR ,
2003-06-13 10:59:02 +02:00
" Directory where character sets are. " , ( gptr * ) & charsets_dir ,
2002-04-02 19:29:53 +02:00
( gptr * ) & charsets_dir , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-11-11 21:55:55 +01:00
{ " comments " , ' i ' , " Write additional information. " ,
( gptr * ) & opt_comments , ( gptr * ) & opt_comments , 0 , GET_BOOL , NO_ARG ,
1 , 0 , 0 , 0 , 0 , 0 } ,
2003-01-16 04:35:59 +01:00
{ " compatible " , OPT_COMPATIBLE ,
2004-04-27 14:33:40 +02:00
" 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. " ,
2003-01-16 04:35:59 +01:00
( gptr * ) & opt_compatible_mode_str , ( gptr * ) & opt_compatible_mode_str , 0 ,
GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-02-09 12:31:03 +01:00
{ " compact " , OPT_COMPACT ,
2004-12-04 10:06:38 +01:00
" 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 " ,
2004-02-09 12:31:03 +01:00
( gptr * ) & opt_compact , ( gptr * ) & opt_compact , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
2005-05-08 21:02:46 +02:00
{ " complete-insert " , ' c ' , " Use complete insert statements. " ,
( gptr * ) & opt_complete_insert , ( gptr * ) & opt_complete_insert , 0 , GET_BOOL ,
NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " compress " , ' C ' , " Use compression in server/client protocol. " ,
( gptr * ) & opt_compress , ( gptr * ) & opt_compress , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 ,
0 , 0 , 0 } ,
2004-04-27 14:33:40 +02:00
{ " create-options " , OPT_CREATE_OPTIONS ,
" Include all MySQL specific create options. " ,
( gptr * ) & create_options , ( gptr * ) & create_options , 0 , GET_BOOL , NO_ARG , 1 ,
0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " databases " , ' B ' ,
" 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. " ,
( gptr * ) & opt_databases , ( gptr * ) & opt_databases , 0 , GET_BOOL , NO_ARG , 0 , 0 ,
0 , 0 , 0 , 0 } ,
2004-04-27 16:32:40 +02:00
# ifdef DBUG_OFF
{ " debug " , ' # ' , " This is a non-debug version. Catch this and exit " ,
0 , 0 , 0 , GET_DISABLED , OPT_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
# else
{ " debug " , ' # ' , " Output debug log " , ( gptr * ) & default_dbug_option ,
( gptr * ) & default_dbug_option , 0 , GET_STR , OPT_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
# endif
2002-04-02 19:29:53 +02:00
{ " default-character-set " , OPT_DEFAULT_CHARSET ,
" Set the default character set. " , ( gptr * ) & default_charset ,
( gptr * ) & default_charset , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2005-09-27 07:43:09 +02:00
{ " delayed-insert " , OPT_DELAYED , " Insert rows with INSERT DELAYED; " ,
2002-04-02 19:29:53 +02:00
( gptr * ) & opt_delayed , ( gptr * ) & opt_delayed , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
2003-04-03 11:33:13 +02:00
{ " delete-master-logs " , OPT_DELETE_MASTER_LOGS ,
2004-11-10 17:56:45 +01:00
" Delete logs on master after backup. This automatically enables --master-data. " ,
( gptr * ) & opt_delete_master_logs , ( gptr * ) & opt_delete_master_logs , 0 ,
GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " disable-keys " , ' K ' ,
" '/*!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 ,
2003-01-16 04:35:59 +01:00
( gptr * ) & opt_disable_keys , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " extended-insert " , ' e ' ,
" Allows utilization of the new, much faster INSERT syntax. " ,
( gptr * ) & extended_insert , ( gptr * ) & extended_insert , 0 , GET_BOOL , NO_ARG ,
2003-01-16 04:35:59 +01:00
1 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " fields-terminated-by " , OPT_FTB ,
" Fields in the textfile are terminated by ... " , ( gptr * ) & fields_terminated ,
( gptr * ) & fields_terminated , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " fields-enclosed-by " , OPT_ENC ,
" Fields in the importfile are enclosed by ... " , ( gptr * ) & enclosed ,
( gptr * ) & enclosed , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " fields-optionally-enclosed-by " , OPT_O_ENC ,
" Fields in the i.file are opt. enclosed by ... " , ( gptr * ) & opt_enclosed ,
( gptr * ) & opt_enclosed , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " fields-escaped-by " , OPT_ESC , " Fields in the i.file are escaped by ... " ,
2004-02-21 14:32:22 +01:00
( gptr * ) & escaped , ( gptr * ) & escaped , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-11-10 17:56:45 +01:00
{ " first-slave " , ' x ' , " Deprecated, renamed to --lock-all-tables. " ,
( gptr * ) & opt_lock_all_tables , ( gptr * ) & opt_lock_all_tables , 0 , GET_BOOL , NO_ARG ,
2002-04-02 19:29:53 +02:00
0 , 0 , 0 , 0 , 0 , 0 } ,
2004-02-04 16:50:33 +01:00
{ " flush-logs " , ' F ' , " Flush logs file in server before starting dump. "
2004-11-10 17:56:45 +01:00
" Note that if you dump many databases at once (using the option "
" --databases= or --all-databases), the logs will be flushed for "
" each database dumped. The exception is when using --lock-all-tables "
" or --master-data: "
" in this case the logs will be flushed only once, corresponding "
" to the moment all tables are locked. So if you want your dump and "
" the log flush to happen at the same exact moment you should use "
" --lock-all-tables or --master-data with --flush-logs " ,
2002-04-02 19:29:53 +02:00
( gptr * ) & flush_logs , ( gptr * ) & flush_logs , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
2006-09-14 20:56:14 +02:00
{ " flush-privileges " , OPT_ESC , " Emit a FLUSH PRIVILEGES statement "
" after dumping the mysql database. This option should be used any "
" time the dump contains the mysql database and any other database "
" that depends on the data in the mysql database for proper restore. " ,
( gptr * ) & flush_privileges , ( gptr * ) & flush_privileges , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " force " , ' f ' , " Continue even if we get an sql-error. " ,
( gptr * ) & ignore_errors , ( gptr * ) & ignore_errors , 0 , GET_BOOL , NO_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
{ " help " , ' ? ' , " Display this help message and exit. " , 0 , 0 , 0 , GET_NO_ARG ,
NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-11-11 21:55:55 +01:00
{ " hex-blob " , OPT_HEXBLOB , " Dump binary strings (BINARY, "
" VARBINARY, BLOB) in hexadecimal format. " ,
( gptr * ) & opt_hex_blob , ( gptr * ) & opt_hex_blob , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " host " , ' h ' , " Connect to host. " , ( gptr * ) & current_host ,
2002-05-15 19:24:00 +02:00
( gptr * ) & current_host , 0 , GET_STR_ALLOC , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-12-27 19:10:30 +01:00
{ " ignore-table " , OPT_IGNORE_TABLE ,
" Do not dump the specified table. To specify more than one table to ignore, "
" use the directive multiple times, once for each table. Each table must "
" be specified with both database and table names, e.g. --ignore-table=database.table " ,
0 , 0 , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2005-05-07 18:49:39 +02:00
{ " insert-ignore " , OPT_INSERT_IGNORE , " Insert rows with INSERT IGNORE. " ,
( gptr * ) & opt_ignore , ( gptr * ) & opt_ignore , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " lines-terminated-by " , OPT_LTB , " Lines in the i.file are terminated by ... " ,
( gptr * ) & lines_terminated , ( gptr * ) & lines_terminated , 0 , GET_STR ,
REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2006-05-25 10:00:28 +02:00
{ " lock-all-tables " , ' x ' , " Locks all tables across all databases. This "
2004-11-10 17:56:45 +01:00
" is achieved by taking a global read lock for the duration of the whole "
" dump. Automatically turns --single-transaction and --lock-tables off. " ,
( gptr * ) & opt_lock_all_tables , ( gptr * ) & opt_lock_all_tables , 0 , GET_BOOL , NO_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " lock-tables " , ' l ' , " Lock all tables for read. " , ( gptr * ) & lock_tables ,
2003-01-16 04:35:59 +01:00
( gptr * ) & lock_tables , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " master-data " , OPT_MASTER_DATA ,
2004-11-10 17:56:45 +01:00
" This causes the binary log position and filename to be appended to the "
" output. If equal to 1, will print it as a CHANGE MASTER command; if equal "
" to 2, that command will be prefixed with a comment symbol. "
" This option will turn --lock-all-tables on, unless "
" --single-transaction is specified too (in which case a "
" global read lock is only taken a short time at the beginning of the dump "
" - don't forget to read about --single-transaction below). In all cases "
" any action on logs will happen at the exact moment of the dump. "
" Option automatically turns --lock-tables off. " ,
( gptr * ) & opt_master_data , ( gptr * ) & opt_master_data , 0 ,
2004-11-14 17:18:31 +01:00
GET_UINT , OPT_ARG , 0 , 0 , MYSQL_OPT_MASTER_DATA_COMMENTED_SQL , 0 , 0 , 0 } ,
2004-11-12 16:44:17 +01:00
{ " max_allowed_packet " , OPT_MAX_ALLOWED_PACKET , " " ,
( gptr * ) & opt_max_allowed_packet , ( gptr * ) & opt_max_allowed_packet , 0 ,
2006-05-25 10:00:28 +02:00
GET_ULONG , REQUIRED_ARG , 24 * 1024 * 1024 , 4096 ,
2004-11-12 16:44:17 +01:00
( longlong ) 2L * 1024L * 1024L * 1024L , MALLOC_OVERHEAD , 1024 , 0 } ,
{ " net_buffer_length " , OPT_NET_BUFFER_LENGTH , " " ,
( gptr * ) & opt_net_buffer_length , ( gptr * ) & opt_net_buffer_length , 0 ,
GET_ULONG , REQUIRED_ARG , 1024 * 1024L - 1025 , 4096 , 16 * 1024L * 1024L ,
MALLOC_OVERHEAD - 1024 , 1024 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " no-autocommit " , OPT_AUTOCOMMIT ,
" Wrap tables with autocommit/commit statements. " ,
( gptr * ) & opt_autocommit , ( gptr * ) & opt_autocommit , 0 , GET_BOOL , NO_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
{ " no-create-db " , ' n ' ,
2003-06-13 10:59:02 +02:00
" '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.}. " ,
2002-04-02 19:29:53 +02:00
( gptr * ) & opt_create_db , ( gptr * ) & opt_create_db , 0 , GET_BOOL , NO_ARG , 0 , 0 ,
0 , 0 , 0 , 0 } ,
{ " no-create-info " , ' t ' , " Don't write table creation info. " ,
2006-07-24 11:56:01 +02:00
( gptr * ) & opt_no_create_info , ( gptr * ) & opt_no_create_info , 0 , GET_BOOL ,
NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " no-data " , ' d ' , " No row information. " , ( gptr * ) & opt_no_data ,
( gptr * ) & opt_no_data , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2003-05-30 12:21:03 +02:00
{ " no-set-names " , ' N ' ,
2004-06-26 23:00:23 +02:00
" Deprecated. Use --skip-set-charset instead. " ,
2004-03-31 04:36:29 +02:00
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " opt " , OPT_OPTIMIZE ,
2004-05-01 11:07:42 +02:00
" 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. " ,
2002-04-02 19:29:53 +02:00
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2005-01-17 07:09:47 +01:00
{ " order-by-primary " , OPT_ORDER_BY_PRIMARY ,
" 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. " ,
( gptr * ) & opt_order_by_primary , ( gptr * ) & opt_order_by_primary , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " password " , ' p ' ,
" Password to use when connecting to server. If password is not given it's solicited on the tty. " ,
0 , 0 , 0 , GET_STR , OPT_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2000-07-31 21:29:14 +02:00
# ifdef __WIN__
2003-06-13 10:59:02 +02:00
{ " pipe " , ' W ' , " Use named pipes to connect to server. " , 0 , 0 , 0 , GET_NO_ARG ,
2002-04-02 19:29:53 +02:00
NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2000-07-31 21:29:14 +02:00
# endif
2002-05-11 13:36:34 +02:00
{ " port " , ' P ' , " Port number to use for connection. " , ( gptr * ) & opt_mysql_port ,
2005-10-13 21:28:43 +02:00
( gptr * ) & opt_mysql_port , 0 , GET_UINT , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 ,
2002-05-11 13:36:34 +02:00
0 } ,
2003-06-13 10:59:02 +02:00
{ " protocol " , OPT_MYSQL_PROTOCOL , " The protocol of connection (tcp,socket,pipe,memory). " ,
2002-11-14 20:16:30 +01:00
0 , 0 , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " quick " , ' q ' , " Don't buffer query, dump directly to stdout. " ,
2003-01-16 04:35:59 +01:00
( gptr * ) & quick , ( gptr * ) & quick , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 , 0 } ,
2003-06-13 10:59:02 +02:00
{ " quote-names " , ' Q ' , " Quote table and column names with backticks (`). " ,
2004-01-15 03:26:57 +01:00
( gptr * ) & opt_quoted , ( gptr * ) & opt_quoted , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 ,
2002-04-02 19:29:53 +02:00
0 , 0 } ,
{ " result-file " , ' r ' ,
2002-08-05 09:00:38 +02:00
" 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). " ,
2002-04-30 11:32:45 +02:00
0 , 0 , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2005-10-19 21:40:10 +02:00
{ " routines " , ' R ' , " Dump stored routines (functions and procedures). " ,
2005-09-04 01:34:58 +02:00
( gptr * ) & opt_routines , ( gptr * ) & opt_routines , 0 , GET_BOOL ,
NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-11-12 10:17:53 +01:00
{ " set-charset " , OPT_SET_CHARSET ,
" Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset. " ,
( gptr * ) & opt_set_charset , ( gptr * ) & opt_set_charset , 0 , GET_BOOL , NO_ARG , 1 ,
0 , 0 , 0 , 0 , 0 } ,
2004-11-09 18:03:02 +01:00
{ " set-variable " , ' O ' ,
" Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value. " ,
0 , 0 , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-11-14 20:16:30 +01:00
# ifdef HAVE_SMEM
2004-08-30 18:11:10 +02:00
{ " shared-memory-base-name " , OPT_SHARED_MEMORY_BASE_NAME ,
2003-06-13 10:59:02 +02:00
" Base name of shared memory. " , ( gptr * ) & shared_memory_base_name , ( gptr * ) & shared_memory_base_name ,
2002-11-14 20:16:30 +01:00
0 , GET_STR_ALLOC , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
# endif
2004-11-12 10:17:53 +01:00
/*
Note that the combination - - single - transaction - - master - data
will give bullet - proof binlog position only if server > = 4.1 .3 . That ' s the
old " FLUSH TABLES WITH READ LOCK does not block commit " fixed bug .
*/
2004-11-09 18:03:02 +01:00
{ " single-transaction " , OPT_TRANSACTION ,
2004-11-12 10:17:53 +01:00
" Creates a consistent snapshot by dumping all tables in a single "
" transaction. Works ONLY for tables stored in storage engines which "
" support multiversioning (currently only InnoDB does); the dump is NOT "
" guaranteed to be consistent for other storage engines. Option "
" automatically turns off --lock-tables. " ,
( gptr * ) & opt_single_transaction , ( gptr * ) & opt_single_transaction , 0 ,
GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2003-01-16 04:35:59 +01:00
{ " skip-opt " , OPT_SKIP_OPTIMIZATION ,
2004-05-01 11:07:42 +02:00
" Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. " ,
2003-01-16 04:35:59 +01:00
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " socket " , ' S ' , " Socket file to use for connection. " ,
( gptr * ) & opt_mysql_unix_port , ( gptr * ) & opt_mysql_unix_port , 0 , GET_STR ,
REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-09-17 22:46:53 +02:00
# include <sslopt-longopts.h>
2002-04-02 19:29:53 +02:00
{ " tab " , ' T ' ,
" 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. " ,
( gptr * ) & path , ( gptr * ) & path , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " tables " , OPT_TABLES , " Overrides option --databases (-B). " ,
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2005-07-31 11:49:55 +02:00
{ " triggers " , OPT_TRIGGERS , " Dump triggers for each dumped table " ,
2005-07-22 04:11:45 +02:00
( gptr * ) & opt_dump_triggers , ( gptr * ) & opt_dump_triggers , 0 , GET_BOOL ,
NO_ARG , 1 , 0 , 0 , 0 , 0 , 0 } ,
2005-10-13 07:44:42 +02:00
{ " tz-utc " , OPT_TZ_UTC ,
2005-10-25 19:04:31 +02:00
" SET TIME_ZONE='+00:00' at top of dump to allow dumping of TIMESTAMP data when a server has data in different time zones or data is being moved between servers with different time zones. " ,
2005-10-13 07:44:42 +02:00
( gptr * ) & opt_tz_utc , ( gptr * ) & opt_tz_utc , 0 , GET_BOOL , NO_ARG , 1 , 0 , 0 , 0 , 0 , 0 } ,
2000-07-31 21:29:14 +02:00
# ifndef DONT_ALLOW_USER_CHANGE
2002-04-02 19:29:53 +02:00
{ " user " , ' u ' , " User for login if not current user. " ,
( gptr * ) & current_user , ( gptr * ) & current_user , 0 , GET_STR , REQUIRED_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
2000-07-31 21:29:14 +02:00
# endif
2002-04-02 19:29:53 +02:00
{ " verbose " , ' v ' , " Print info about the various stages. " ,
( gptr * ) & verbose , ( gptr * ) & verbose , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " version " , ' V ' , " Output version information and exit. " , 0 , 0 , 0 ,
GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " where " , ' w ' , " Dump only selected records; QUOTES mandatory! " ,
( gptr * ) & where , ( gptr * ) & where , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " xml " , ' X ' , " Dump a database as well formed XML. " , 0 , 0 , 0 , GET_NO_ARG ,
NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2004-11-12 13:02:17 +01:00
{ 0 , 0 , 0 , 0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 }
2000-07-31 21:29:14 +02:00
} ;
static const char * load_default_groups [ ] = { " mysqldump " , " client " , 0 } ;
static void safe_exit ( int error ) ;
2002-01-02 20:29:41 +01:00
static void write_header ( FILE * sql_file , char * db_name ) ;
2000-07-31 21:29:14 +02:00
static void print_value ( FILE * file , MYSQL_RES * result , MYSQL_ROW row ,
2006-05-25 10:00:28 +02:00
const char * prefix , const char * name ,
int string_value ) ;
2000-07-31 21:29:14 +02:00
static int dump_selected_tables ( char * db , char * * table_names , int tables ) ;
static int dump_all_tables_in_db ( char * db ) ;
2006-08-28 23:48:06 +02:00
static int init_dumping_views ( char * ) ;
static int init_dumping_tables ( char * ) ;
static int init_dumping ( char * , int init_func ( char * ) ) ;
2000-07-31 21:29:14 +02:00
static int dump_databases ( char * * ) ;
static int dump_all_databases ( ) ;
2003-09-03 17:48:10 +02:00
static char * quote_name ( const char * name , char * buff , my_bool force ) ;
2005-09-27 07:43:09 +02:00
char check_if_ignore_table ( const char * table_name , char * table_type ) ;
2004-11-16 23:45:24 +01:00
static char * primary_key_fields ( const char * table_name ) ;
2005-04-04 23:32:48 +02:00
static my_bool get_view_structure ( char * table , char * db ) ;
2004-11-12 04:01:46 +01:00
static my_bool dump_all_views_in_db ( char * database ) ;
2003-12-14 05:39:52 +01:00
2004-05-25 21:00:14 +02:00
# include <help_start.h>
2000-07-31 21:29:14 +02:00
2006-07-24 11:51:52 +02:00
/*
Print the supplied message if in verbose mode
SYNOPSIS
verbose_msg ( )
fmt format specifier
. . . variable number of parameters
*/
static void verbose_msg ( const char * fmt , . . . )
{
va_list args ;
DBUG_ENTER ( " verbose_msg " ) ;
if ( ! verbose )
DBUG_VOID_RETURN ;
va_start ( args , fmt ) ;
vfprintf ( stderr , fmt , args ) ;
va_end ( args ) ;
DBUG_VOID_RETURN ;
}
2004-06-24 22:14:12 +02:00
/*
exit with message if ferror ( file )
2006-05-25 10:00:28 +02:00
2004-06-24 22:14:12 +02:00
SYNOPSIS
check_io ( )
2006-05-25 10:00:28 +02:00
file - checked file
2004-06-24 22:14:12 +02:00
*/
void check_io ( FILE * file )
{
if ( ferror ( file ) )
{
fprintf ( stderr , " %s: Got errno %d on write \n " , my_progname , errno ) ;
2005-07-31 11:49:55 +02:00
ignore_errors = 0 ; /* We can't ignore this error */
2004-06-24 22:14:12 +02:00
safe_exit ( EX_EOF ) ;
}
}
2000-07-31 21:29:14 +02:00
static void print_version ( void )
{
printf ( " %s Ver %s Distrib %s, for %s (%s) \n " , my_progname , DUMP_VERSION ,
2004-05-25 21:00:14 +02:00
MYSQL_SERVER_VERSION , SYSTEM_TYPE , MACHINE_TYPE ) ;
NETWARE_SET_SCREEN_MODE ( 1 ) ;
2000-07-31 21:29:14 +02:00
} /* print_version */
2002-09-24 16:11:59 +02:00
static void short_usage_sub ( void )
{
printf ( " Usage: %s [OPTIONS] database [tables] \n " , my_progname ) ;
printf ( " OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] \n " ,
2006-05-25 10:00:28 +02:00
my_progname ) ;
2002-09-24 16:11:59 +02:00
printf ( " OR %s [OPTIONS] --all-databases [OPTIONS] \n " , my_progname ) ;
2004-05-25 21:00:14 +02:00
NETWARE_SET_SCREEN_MODE ( 1 ) ;
2002-09-24 16:11:59 +02:00
}
2004-05-25 21:00:14 +02:00
2000-07-31 21:29:14 +02:00
static void usage ( void )
{
print_version ( ) ;
puts ( " By Igor Romanenko, Monty, Jani & Sinisa " ) ;
puts ( " This software comes with ABSOLUTELY NO WARRANTY. This is free software, \n and you are welcome to modify and redistribute it under the GPL license \n " ) ;
puts ( " Dumping definition and data mysql database or table " ) ;
2002-09-24 16:11:59 +02:00
short_usage_sub ( ) ;
2000-07-31 21:29:14 +02:00
print_defaults ( " my " , load_default_groups ) ;
2002-04-02 19:29:53 +02:00
my_print_help ( my_long_options ) ;
my_print_variables ( my_long_options ) ;
2000-07-31 21:29:14 +02:00
} /* usage */
2002-09-24 16:11:59 +02:00
static void short_usage ( void )
{
short_usage_sub ( ) ;
printf ( " For more options, use %s --help \n " , my_progname ) ;
}
2004-05-25 21:00:14 +02:00
# include <help_end.h>
2002-09-24 16:11:59 +02:00
2002-01-02 20:29:41 +01:00
static void write_header ( FILE * sql_file , char * db_name )
2000-07-31 21:29:14 +02:00
{
2001-11-05 22:48:03 +01:00
if ( opt_xml )
2002-11-18 17:50:42 +01:00
{
2003-10-30 11:58:30 +01:00
fputs ( " <?xml version= \" 1.0 \" ?> \n " , sql_file ) ;
2006-10-19 00:43:51 +02:00
/* Schema reference. Allows use of xsi:nil for NULL values and
xsi : type to define an element ' s data type . */
2005-06-22 20:22:54 +02:00
fputs ( " <mysqldump " , sql_file ) ;
fputs ( " xmlns:xsi= \" http://www.w3.org/2001/XMLSchema-instance \" " ,
sql_file ) ;
fputs ( " > \n " , sql_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
2002-11-18 17:50:42 +01:00
}
2004-02-09 12:31:03 +01:00
else if ( ! opt_compact )
2001-11-05 22:48:03 +01:00
{
2004-02-09 12:31:03 +01:00
if ( opt_comments )
{
fprintf ( sql_file , " -- MySQL dump %s \n -- \n " , DUMP_VERSION ) ;
fprintf ( sql_file , " -- Host: %s Database: %s \n " ,
2006-05-25 10:00:28 +02:00
current_host ? current_host : " localhost " , db_name ? db_name :
" " ) ;
2004-02-09 12:31:03 +01:00
fputs ( " -- ------------------------------------------------------ \n " ,
2006-05-25 10:00:28 +02:00
sql_file ) ;
2004-02-09 12:31:03 +01:00
fprintf ( sql_file , " -- Server version \t %s \n " ,
2006-05-25 10:00:28 +02:00
mysql_get_server_info ( & mysql_connection ) ) ;
2004-02-09 12:31:03 +01:00
}
2004-03-31 04:36:29 +02:00
if ( opt_set_charset )
2004-06-07 15:12:23 +02:00
fprintf ( sql_file ,
" \n /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; "
" \n /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; "
" \n /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; "
" \n /*!40101 SET NAMES %s */; \n " , default_charset ) ;
2005-10-13 07:44:42 +02:00
if ( opt_tz_utc )
{
fprintf ( sql_file , " /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; \n " ) ;
fprintf ( sql_file , " /*!40103 SET TIME_ZONE='+00:00' */; \n " ) ;
}
2004-02-13 22:21:46 +01:00
if ( ! path )
{
fprintf ( md_result_file , " \
2003-07-23 00:58:30 +02:00
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */ ; \ n \
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */ ; \ n \
" );
2004-02-13 22:21:46 +01:00
}
fprintf ( sql_file ,
2006-05-25 10:00:28 +02:00
" /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='%s%s%s' */; \n "
" /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; \n " ,
path ? " " : " NO_AUTO_VALUE_ON_ZERO " , compatible_mode_normal_str [ 0 ] = = 0 ? " " : " , " ,
compatible_mode_normal_str ) ;
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
2001-11-05 22:48:03 +01:00
}
2002-01-02 20:29:41 +01:00
} /* write_header */
2000-07-31 21:29:14 +02:00
2003-01-16 04:35:59 +01:00
2002-11-18 17:50:42 +01:00
static void write_footer ( FILE * sql_file )
{
if ( opt_xml )
2004-06-24 22:14:12 +02:00
{
2004-02-09 12:31:03 +01:00
fputs ( " </mysqldump> \n " , sql_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
}
2004-02-09 12:31:03 +01:00
else if ( ! opt_compact )
2003-07-23 00:58:30 +02:00
{
2005-10-13 07:44:42 +02:00
if ( opt_tz_utc )
fprintf ( sql_file , " /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; \n " ) ;
2004-02-13 22:21:46 +01:00
fprintf ( sql_file , " \n /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; \n " ) ;
if ( ! path )
{
fprintf ( md_result_file , " \
2003-07-23 00:58:30 +02:00
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */ ; \ n \
2004-02-09 12:31:03 +01:00
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */ ; \ n " );
2004-02-13 22:21:46 +01:00
}
2004-03-31 04:36:29 +02:00
if ( opt_set_charset )
2004-02-13 22:21:46 +01:00
fprintf ( sql_file ,
2004-06-07 15:12:23 +02:00
" /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; \n "
" /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; \n "
" /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; \n " ) ;
2005-02-21 18:40:28 +01:00
fprintf ( sql_file ,
2006-05-25 10:00:28 +02:00
" /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; \n " ) ;
2004-02-09 12:31:03 +01:00
fputs ( " \n " , sql_file ) ;
2006-07-24 10:56:33 +02:00
if ( opt_comments )
{
char time_str [ 20 ] ;
get_date ( time_str , GETDATE_DATE_TIME , 0 ) ;
fprintf ( sql_file , " -- Dump completed on %s \n " ,
time_str ) ;
}
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
2003-07-23 00:58:30 +02:00
}
2002-11-18 17:50:42 +01:00
} /* write_footer */
2000-07-31 21:29:14 +02:00
2005-06-27 19:31:00 +02:00
static void free_table_ent ( char * key )
{
my_free ( ( gptr ) key , MYF ( 0 ) ) ;
}
2003-01-16 04:35:59 +01:00
2005-06-21 14:19:56 +02:00
byte * get_table_key ( const char * entry , uint * length ,
2006-05-25 10:00:28 +02:00
my_bool not_used __attribute__ ( ( unused ) ) )
2004-12-27 19:10:30 +01:00
{
2005-06-21 14:19:56 +02:00
* length = strlen ( entry ) ;
return ( byte * ) entry ;
2004-12-27 19:10:30 +01:00
}
2004-12-28 17:33:49 +01:00
void init_table_rule_hash ( HASH * h )
2004-12-27 19:10:30 +01:00
{
2005-06-27 19:31:00 +02:00
if ( hash_init ( h , charset_info , 16 , 0 , 0 ,
( hash_get_key ) get_table_key ,
( hash_free_key ) free_table_ent , 0 ) )
2004-12-28 17:33:49 +01:00
exit ( EX_EOM ) ;
2004-12-27 19:10:30 +01:00
}
2002-04-02 19:29:53 +02:00
static my_bool
get_one_option ( int optid , const struct my_option * opt __attribute__ ( ( unused ) ) ,
2006-05-25 10:00:28 +02:00
char * argument )
2000-07-31 21:29:14 +02:00
{
2003-04-03 11:33:13 +02:00
switch ( optid ) {
2005-08-24 21:03:34 +02:00
# ifdef __NETWARE__
case OPT_AUTO_CLOSE :
setscreenmode ( SCR_AUTOCLOSE_ON_EXIT ) ;
break ;
# endif
2002-04-02 19:29:53 +02:00
case ' p ' :
if ( argument )
{
char * start = argument ;
my_free ( opt_password , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
opt_password = my_strdup ( argument , MYF ( MY_FAE ) ) ;
2006-05-25 10:00:28 +02:00
while ( * argument ) * argument + + = ' x ' ; /* Destroy argument */
2002-04-02 19:29:53 +02:00
if ( * start )
2006-05-25 10:00:28 +02:00
start [ 1 ] = 0 ; /* Cut length of argument */
2004-10-07 21:08:17 +02:00
tty_password = 0 ;
2002-04-02 19:29:53 +02:00
}
else
tty_password = 1 ;
break ;
case ' r ' :
2006-08-02 03:18:47 +02:00
if ( ! ( md_result_file = my_fopen ( argument , O_WRONLY | FILE_BINARY ,
2006-05-25 10:00:28 +02:00
MYF ( MY_WME ) ) ) )
2002-04-02 19:29:53 +02:00
exit ( 1 ) ;
break ;
case ' W ' :
2000-07-31 21:29:14 +02:00
# ifdef __WIN__
2006-08-02 03:18:47 +02:00
opt_protocol = MYSQL_PROTOCOL_PIPE ;
2000-07-31 21:29:14 +02:00
# endif
2002-04-02 19:29:53 +02:00
break ;
2004-03-31 04:36:29 +02:00
case ' N ' :
opt_set_charset = 0 ;
break ;
2002-04-02 19:29:53 +02:00
case ' T ' :
opt_disable_keys = 0 ;
break ;
case ' # ' :
2004-04-27 16:32:40 +02:00
DBUG_PUSH ( argument ? argument : default_dbug_option ) ;
2002-04-02 19:29:53 +02:00
break ;
2002-09-17 22:46:53 +02:00
# include <sslopt-case.h>
2002-04-02 19:29:53 +02:00
case ' V ' : print_version ( ) ; exit ( 0 ) ;
case ' X ' :
2006-08-02 03:18:47 +02:00
opt_xml = 1 ;
2006-05-25 10:00:28 +02:00
extended_insert = opt_drop = opt_lock =
2003-10-14 12:19:54 +02:00
opt_disable_keys = opt_autocommit = opt_create_db = 0 ;
2002-04-02 19:29:53 +02:00
break ;
case ' I ' :
case ' ? ' :
usage ( ) ;
exit ( 0 ) ;
2004-11-14 17:18:31 +01:00
case ( int ) OPT_MASTER_DATA :
if ( ! argument ) /* work like in old versions */
opt_master_data = MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL ;
break ;
2002-04-02 19:29:53 +02:00
case ( int ) OPT_OPTIMIZE :
2003-01-16 04:35:59 +01:00
extended_insert = opt_drop = opt_lock = quick = create_options =
2004-03-31 04:36:29 +02:00
opt_disable_keys = lock_tables = opt_set_charset = 1 ;
2002-04-02 19:29:53 +02:00
break ;
2003-01-16 04:35:59 +01:00
case ( int ) OPT_SKIP_OPTIMIZATION :
extended_insert = opt_drop = opt_lock = quick = create_options =
2004-04-27 14:33:40 +02:00
opt_disable_keys = lock_tables = opt_set_charset = 0 ;
2003-01-16 04:35:59 +01:00
break ;
2004-02-09 12:31:03 +01:00
case ( int ) OPT_COMPACT :
if ( opt_compact )
{
opt_comments = opt_drop = opt_disable_keys = opt_lock = 0 ;
2004-03-31 04:36:29 +02:00
opt_set_charset = 0 ;
2004-02-09 12:31:03 +01:00
}
2002-04-02 19:29:53 +02:00
case ( int ) OPT_TABLES :
opt_databases = 0 ;
break ;
2004-12-27 19:10:30 +01:00
case ( int ) OPT_IGNORE_TABLE :
{
2004-12-28 17:33:49 +01:00
if ( ! strchr ( argument , ' . ' ) )
2004-12-27 19:10:30 +01:00
{
2004-12-28 17:33:49 +01:00
fprintf ( stderr , " Illegal use of option --ignore-table=<database>.<table> \n " ) ;
2004-12-27 19:10:30 +01:00
exit ( 1 ) ;
}
2004-12-28 17:33:49 +01:00
if ( ! hash_inited ( & ignore_table ) )
init_table_rule_hash ( & ignore_table ) ;
2005-06-21 14:19:56 +02:00
if ( my_hash_insert ( & ignore_table , ( byte * ) my_strdup ( argument , MYF ( 0 ) ) ) )
2004-12-28 17:33:49 +01:00
exit ( EX_EOM ) ;
2004-12-27 19:10:30 +01:00
break ;
}
2003-01-16 04:35:59 +01:00
case ( int ) OPT_COMPATIBLE :
2004-12-28 17:33:49 +01:00
{
2003-01-16 04:35:59 +01:00
char buff [ 255 ] ;
2004-03-11 15:46:27 +01:00
char * end = compatible_mode_normal_str ;
int i ;
ulong mode ;
2003-01-16 04:35:59 +01:00
opt_quoted = 1 ;
2004-03-31 04:36:29 +02:00
opt_set_charset = 0 ;
2003-01-16 04:35:59 +01:00
opt_compatible_mode_str = argument ;
opt_compatible_mode = find_set ( & compatible_mode_typelib ,
2006-05-25 10:00:28 +02:00
argument , strlen ( argument ) ,
& err_ptr , & err_len ) ;
2003-01-16 04:35:59 +01:00
if ( err_len )
{
2006-05-25 10:00:28 +02:00
strmake ( buff , err_ptr , min ( sizeof ( buff ) , err_len ) ) ;
fprintf ( stderr , " Invalid mode to --compatible: %s \n " , buff ) ;
exit ( 1 ) ;
2003-01-16 04:35:59 +01:00
}
2004-03-11 15:46:27 +01:00
# if !defined(DBUG_OFF)
{
2006-05-25 10:00:28 +02:00
uint size_for_sql_mode = 0 ;
const char * * ptr ;
for ( ptr = compatible_mode_names ; * ptr ; ptr + + )
size_for_sql_mode + = strlen ( * ptr ) ;
size_for_sql_mode + = sizeof ( compatible_mode_names ) - 1 ;
DBUG_ASSERT ( sizeof ( compatible_mode_normal_str ) > = size_for_sql_mode ) ;
2004-03-11 15:46:27 +01:00
}
# endif
mode = opt_compatible_mode ;
for ( i = 0 , mode = opt_compatible_mode ; mode ; mode > > = 1 , i + + )
{
2006-05-25 10:00:28 +02:00
if ( mode & 1 )
{
end = strmov ( end , compatible_mode_names [ i ] ) ;
end = strmov ( end , " , " ) ;
}
2004-03-11 15:46:27 +01:00
}
if ( end ! = compatible_mode_normal_str )
2006-05-25 10:00:28 +02:00
end [ - 1 ] = 0 ;
/*
2004-12-22 13:02:27 +01:00
Set charset to the default compiled value if it hasn ' t
been reset yet by - - default - character - set = xxx .
*/
2005-01-06 18:13:58 +01:00
if ( default_charset = = mysql_universal_client_charset )
2004-12-22 13:02:27 +01:00
default_charset = ( char * ) MYSQL_DEFAULT_CHARSET_NAME ;
2003-01-16 04:35:59 +01:00
break ;
}
case ( int ) OPT_MYSQL_PROTOCOL :
2002-11-14 20:16:30 +01:00
{
2004-08-24 17:13:31 +02:00
if ( ( opt_protocol = find_type ( argument , & sql_protocol_typelib , 0 ) ) < = 0 )
2003-01-16 04:35:59 +01:00
{
2006-05-25 10:00:28 +02:00
fprintf ( stderr , " Unknown option to protocol: %s \n " , argument ) ;
exit ( 1 ) ;
2003-01-16 04:35:59 +01:00
}
break ;
2002-11-14 20:16:30 +01:00
}
2000-07-31 21:29:14 +02:00
}
2002-04-02 19:29:53 +02:00
return 0 ;
}
static int get_options ( int * argc , char * * * argv )
{
int ho_error ;
2004-05-26 18:40:27 +02:00
MYSQL_PARAMETERS * mysql_params = mysql_get_parameters ( ) ;
opt_max_allowed_packet = * mysql_params - > p_max_allowed_packet ;
opt_net_buffer_length = * mysql_params - > p_net_buffer_length ;
2002-04-02 19:29:53 +02:00
md_result_file = stdout ;
load_defaults ( " my " , load_default_groups , argc , argv ) ;
2004-08-31 18:27:58 +02:00
if ( ( ho_error = handle_options ( argc , argv , my_long_options , get_one_option ) ) )
2002-05-29 14:07:30 +02:00
exit ( ho_error ) ;
2002-04-02 19:29:53 +02:00
2004-05-26 18:40:27 +02:00
* mysql_params - > p_max_allowed_packet = opt_max_allowed_packet ;
* mysql_params - > p_net_buffer_length = opt_net_buffer_length ;
2000-07-31 21:29:14 +02:00
if ( opt_delayed )
2006-05-25 10:00:28 +02:00
opt_lock = 0 ; /* Can't have lock with delayed */
2000-07-31 21:29:14 +02:00
if ( ! path & & ( enclosed | | opt_enclosed | | escaped | | lines_terminated | |
2006-05-25 10:00:28 +02:00
fields_terminated ) )
2000-07-31 21:29:14 +02:00
{
2002-04-02 19:29:53 +02:00
fprintf ( stderr ,
2006-05-25 10:00:28 +02:00
" %s: You must use option --tab with --fields-... \n " , my_progname ) ;
2000-07-31 21:29:14 +02:00
return ( 1 ) ;
}
2004-11-10 17:56:45 +01:00
/* Ensure consistency of the set of binlog & locking options */
if ( opt_delete_master_logs & & ! opt_master_data )
opt_master_data = MYSQL_OPT_MASTER_DATA_COMMENTED_SQL ;
if ( opt_single_transaction & & opt_lock_all_tables )
{
fprintf ( stderr , " %s: You can't use --single-transaction and "
" --lock-all-tables at the same time. \n " , my_progname ) ;
return ( 1 ) ;
2006-05-25 10:00:28 +02:00
}
2004-11-10 17:56:45 +01:00
if ( opt_master_data )
opt_lock_all_tables = ! opt_single_transaction ;
if ( opt_single_transaction | | opt_lock_all_tables )
2003-01-16 04:35:59 +01:00
lock_tables = 0 ;
2000-07-31 21:29:14 +02:00
if ( enclosed & & opt_enclosed )
{
fprintf ( stderr , " %s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time. \n " , my_progname ) ;
return ( 1 ) ;
}
if ( ( opt_databases | | opt_alldbs ) & & path )
{
fprintf ( stderr ,
2006-05-25 10:00:28 +02:00
" %s: --databases or --all-databases can't be used with --tab. \n " ,
my_progname ) ;
2000-07-31 21:29:14 +02:00
return ( 1 ) ;
}
2004-02-11 12:15:39 +01:00
if ( strcmp ( default_charset , charset_info - > csname ) & &
2006-05-25 10:00:28 +02:00
! ( charset_info = get_charset_by_csname ( default_charset ,
MY_CS_PRIMARY , MYF ( MY_WME ) ) ) )
2003-03-16 08:20:45 +01:00
exit ( 1 ) ;
2000-07-31 21:29:14 +02:00
if ( ( * argc < 1 & & ! opt_alldbs ) | | ( * argc > 0 & & opt_alldbs ) )
{
2002-09-24 16:11:59 +02:00
short_usage ( ) ;
2000-07-31 21:29:14 +02:00
return 1 ;
}
if ( tty_password )
2000-11-13 22:55:10 +01:00
opt_password = get_tty_password ( NullS ) ;
2000-07-31 21:29:14 +02:00
return ( 0 ) ;
} /* get_options */
/*
2005-04-04 23:32:48 +02:00
* * DB_error - - prints mysql error message and exits the program .
2000-07-31 21:29:14 +02:00
*/
2005-04-04 23:32:48 +02:00
static void DB_error ( MYSQL * mysql , const char * when )
2000-07-31 21:29:14 +02:00
{
2005-04-04 23:32:48 +02:00
DBUG_ENTER ( " DB_error " ) ;
2006-08-17 23:09:24 +02:00
fprintf ( stderr , " %s: Got error: %d: %s %s \n " , my_progname ,
mysql_errno ( mysql ) , mysql_error ( mysql ) , when ) ;
2006-09-01 13:53:43 +02:00
fflush ( stderr ) ;
2000-07-31 21:29:14 +02:00
safe_exit ( EX_MYSQLERR ) ;
DBUG_VOID_RETURN ;
2005-04-04 23:32:48 +02:00
} /* DB_error */
2000-07-31 21:29:14 +02:00
2004-11-10 17:56:45 +01:00
/*
Sends a query to server , optionally reads result , prints error message if
some .
SYNOPSIS
mysql_query_with_error_report ( )
mysql_con connection to use
2005-07-03 13:17:52 +02:00
res if non zero , result will be put there with
2006-05-25 10:00:28 +02:00
mysql_store_result ( )
2004-11-10 17:56:45 +01:00
query query to send to server
RETURN VALUES
0 query sending and ( if res ! = 0 ) result reading went ok
1 error
*/
2006-05-25 10:00:28 +02:00
2004-11-10 17:56:45 +01:00
static int mysql_query_with_error_report ( MYSQL * mysql_con , MYSQL_RES * * res ,
const char * query )
{
if ( mysql_query ( mysql_con , query ) | |
( res & & ! ( ( * res ) = mysql_store_result ( mysql_con ) ) ) )
{
2006-08-17 23:09:24 +02:00
fprintf ( stderr , " %s: Couldn't execute '%s': %s (%d) \n " ,
my_progname , query ,
mysql_error ( mysql_con ) , mysql_errno ( mysql_con ) ) ;
2006-09-01 05:53:34 +02:00
safe_exit ( EX_MYSQLERR ) ;
2004-11-10 17:56:45 +01:00
return 1 ;
}
return 0 ;
}
2006-02-21 13:21:17 +01:00
/*
Open a new . sql file to dump the table or view into
SYNOPSIS
open_sql_file_for_table
name name of the table or view
RETURN VALUES
0 Failed to open file
> 0 Handle of the open file
*/
static FILE * open_sql_file_for_table ( const char * table )
{
FILE * res ;
char filename [ FN_REFLEN ] , tmp_path [ FN_REFLEN ] ;
convert_dirname ( tmp_path , path , NullS ) ;
res = my_fopen ( fn_format ( filename , table , tmp_path , " .sql " , 4 ) ,
2006-05-25 10:00:28 +02:00
O_WRONLY , MYF ( MY_WME ) ) ;
2006-02-21 13:21:17 +01:00
return res ;
}
2004-11-10 17:56:45 +01:00
2000-07-31 21:29:14 +02:00
static void safe_exit ( int error )
{
if ( ! first_error )
first_error = error ;
if ( ignore_errors )
return ;
2006-07-24 12:00:44 +02:00
if ( mysql )
mysql_close ( mysql ) ;
2000-07-31 21:29:14 +02:00
exit ( error ) ;
}
/* safe_exit */
/*
* * dbConnect - - connects to the host and selects DB .
*/
static int dbConnect ( char * host , char * user , char * passwd )
{
2004-03-11 15:46:27 +01:00
char buff [ 20 + FN_REFLEN ] ;
2000-07-31 21:29:14 +02:00
DBUG_ENTER ( " dbConnect " ) ;
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Connecting to %s... \n " , host ? host : " localhost " ) ;
2000-07-31 21:29:14 +02:00
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 ,
2006-05-25 10:00:28 +02:00
opt_ssl_capath , opt_ssl_cipher ) ;
2006-04-18 17:58:27 +02:00
mysql_options ( & mysql_connection , MYSQL_OPT_SSL_VERIFY_SERVER_CERT ,
( char * ) & opt_ssl_verify_server_cert ) ;
2002-11-14 20:16:30 +01:00
# endif
if ( opt_protocol )
mysql_options ( & mysql_connection , MYSQL_OPT_PROTOCOL , ( char * ) & opt_protocol ) ;
# ifdef HAVE_SMEM
if ( shared_memory_base_name )
mysql_options ( & mysql_connection , MYSQL_SHARED_MEMORY_BASE_NAME , shared_memory_base_name ) ;
2000-07-31 21:29:14 +02:00
# endif
2004-05-01 11:07:42 +02:00
mysql_options ( & mysql_connection , MYSQL_SET_CHARSET_NAME , default_charset ) ;
2006-07-24 12:00:44 +02:00
if ( ! ( mysql = mysql_real_connect ( & mysql_connection , host , user , passwd ,
2000-07-31 21:29:14 +02:00
NULL , opt_mysql_port , opt_mysql_unix_port ,
0 ) ) )
{
2005-04-04 23:32:48 +02:00
DB_error ( & mysql_connection , " when trying to connect " ) ;
2000-07-31 21:29:14 +02:00
return 1 ;
}
2005-02-25 15:12:53 +01:00
/*
Don ' t dump SET NAMES with a pre - 4.1 server ( bug # 7997 ) .
*/
if ( mysql_get_server_version ( & mysql_connection ) < 40100 )
opt_set_charset = 0 ;
2004-11-10 17:56:45 +01:00
/*
As we ' re going to set SQL_MODE , it would be lost on reconnect , so we
cannot reconnect .
*/
2006-07-24 12:00:44 +02:00
mysql - > reconnect = 0 ;
2005-03-16 21:56:56 +01:00
my_snprintf ( buff , sizeof ( buff ) , " /*!40100 SET @@SQL_MODE='%s' */ " ,
2006-05-25 10:00:28 +02:00
compatible_mode_normal_str ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , 0 , buff ) )
2004-03-11 15:46:27 +01:00
{
safe_exit ( EX_MYSQLERR ) ;
return 1 ;
}
2005-10-13 07:44:42 +02:00
/*
2006-05-25 10:00:28 +02:00
set time_zone to UTC to allow dumping date types between servers with
2005-10-13 07:44:42 +02:00
different time zone settings
*/
if ( opt_tz_utc )
{
my_snprintf ( buff , sizeof ( buff ) , " /*!40103 SET TIME_ZONE='+00:00' */ " ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , 0 , buff ) )
2005-10-13 07:44:42 +02:00
{
safe_exit ( EX_MYSQLERR ) ;
return 1 ;
}
}
2000-07-31 21:29:14 +02:00
return 0 ;
} /* dbConnect */
/*
* * dbDisconnect - - disconnects from the host .
*/
static void dbDisconnect ( char * host )
{
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Disconnecting from %s... \n " , host ? host : " localhost " ) ;
2006-07-24 12:00:44 +02:00
mysql_close ( mysql ) ;
2000-07-31 21:29:14 +02:00
} /* dbDisconnect */
static void unescape ( FILE * file , char * pos , uint length )
{
char * tmp ;
DBUG_ENTER ( " unescape " ) ;
if ( ! ( tmp = ( char * ) my_malloc ( length * 2 + 1 , MYF ( MY_WME ) ) ) )
{
2006-05-25 10:00:28 +02:00
ignore_errors = 0 ; /* Fatal error */
safe_exit ( EX_MYSQLERR ) ; /* Force exit */
2000-07-31 21:29:14 +02:00
}
2001-11-05 22:48:03 +01:00
mysql_real_escape_string ( & mysql_connection , tmp , pos , length ) ;
2000-07-31 21:29:14 +02:00
fputc ( ' \' ' , file ) ;
fputs ( tmp , file ) ;
fputc ( ' \' ' , file ) ;
2004-06-24 22:14:12 +02:00
check_io ( file ) ;
2000-07-31 21:29:14 +02:00
my_free ( tmp , MYF ( MY_WME ) ) ;
DBUG_VOID_RETURN ;
} /* unescape */
static my_bool test_if_special_chars ( const char * str )
{
# if MYSQL_VERSION_ID >= 32300
for ( ; * str ; str + + )
2003-03-16 08:20:45 +01:00
if ( ! my_isvar ( charset_info , * str ) & & * str ! = ' $ ' )
2000-07-31 21:29:14 +02:00
return 1 ;
# endif
return 0 ;
} /* test_if_special_chars */
2003-09-03 17:48:10 +02:00
2003-11-04 08:40:36 +01:00
2005-10-13 22:42:56 +02:00
/*
quote_name ( name , buff , force )
2006-05-25 10:00:28 +02:00
Quotes char string , taking into account compatible mode
2005-10-13 22:42:56 +02:00
Args
name Unquoted string containing that which will be quoted
buff The buffer that contains the quoted value , also returned
2006-05-25 10:00:28 +02:00
force Flag to make it ignore ' test_if_special_chars '
2005-10-13 22:42:56 +02:00
Returns
buff quoted string
*/
2003-09-03 17:48:10 +02:00
static char * quote_name ( const char * name , char * buff , my_bool force )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
char * to = buff ;
2004-03-11 15:46:27 +01:00
char qtype = ( opt_compatible_mode & MASK_ANSI_QUOTES ) ? ' \" ' : ' ` ' ;
2003-09-03 17:48:10 +02:00
if ( ! force & & ! opt_quoted & & ! test_if_special_chars ( name ) )
return ( char * ) name ;
2004-03-11 15:46:27 +01:00
* to + + = qtype ;
2003-09-03 17:48:10 +02:00
while ( * name )
{
2004-03-11 15:46:27 +01:00
if ( * name = = qtype )
* to + + = qtype ;
2003-09-03 17:48:10 +02:00
* to + + = * name + + ;
}
2004-03-11 15:46:27 +01:00
to [ 0 ] = qtype ;
to [ 1 ] = 0 ;
2000-07-31 21:29:14 +02:00
return buff ;
} /* quote_name */
2005-06-27 19:31:00 +02:00
2005-06-21 14:19:56 +02:00
/*
Quote a table name so it can be used in " SHOW TABLES LIKE <tabname> "
2000-07-31 21:29:14 +02:00
2005-06-21 14:19:56 +02:00
SYNOPSIS
2005-06-27 19:31:00 +02:00
quote_for_like ( )
name name of the table
buff quoted name of the table
2005-06-21 14:19:56 +02:00
DESCRIPTION
Quote \ , _ , ' and % characters
2000-07-31 21:29:14 +02:00
2005-06-21 14:19:56 +02:00
Note : Because MySQL uses the C escape syntax in strings
( for example , ' \n ' to represent newline ) , you must double
any ' \ ' that you use in your LIKE strings . For example , to
search for ' \n ' , specify it as ' \ \ n ' . To search for ' \ ' , specify
it as ' \ \ \ \ ' ( the backslashes are stripped once by the parser
and another time when the pattern match is done , leaving a
single backslash to be matched ) .
Example : " t \1 " = > " t \\ \\ 1 "
*/
2003-12-14 05:39:52 +01:00
static char * quote_for_like ( const char * name , char * buff )
{
char * to = buff ;
* to + + = ' \' ' ;
while ( * name )
{
2005-06-21 14:19:56 +02:00
if ( * name = = ' \\ ' )
{
* to + + = ' \\ ' ;
* to + + = ' \\ ' ;
* to + + = ' \\ ' ;
}
else if ( * name = = ' \' ' | | * name = = ' _ ' | | * name = = ' % ' )
2003-12-14 05:39:52 +01:00
* to + + = ' \\ ' ;
* to + + = * name + + ;
}
to [ 0 ] = ' \' ' ;
to [ 1 ] = 0 ;
return buff ;
}
2003-11-03 13:49:39 +01:00
/*
Quote and print a string .
2006-05-25 10:00:28 +02:00
2003-11-03 13:49:39 +01:00
SYNOPSIS
print_quoted_xml ( )
2006-10-19 00:43:51 +02:00
xml_file - output file
2006-05-25 10:00:28 +02:00
str - string to print
len - its length
2003-11-03 13:49:39 +01:00
DESCRIPTION
2004-11-16 23:45:24 +01:00
Quote ' < ' ' > ' ' & ' ' \" ' chars and print a string to the xml_file .
2003-11-03 13:49:39 +01:00
*/
static void print_quoted_xml ( FILE * xml_file , const char * str , ulong len )
{
const char * end ;
2006-05-25 10:00:28 +02:00
2003-11-03 13:49:39 +01:00
for ( end = str + len ; str ! = end ; str + + )
{
switch ( * str ) {
case ' < ' :
fputs ( " < " , xml_file ) ;
break ;
case ' > ' :
fputs ( " > " , xml_file ) ;
break ;
case ' & ' :
fputs ( " & " , xml_file ) ;
break ;
case ' \" ' :
fputs ( " " " , xml_file ) ;
break ;
default :
fputc ( * str , xml_file ) ;
break ;
}
}
2004-06-24 22:14:12 +02:00
check_io ( xml_file ) ;
2003-11-03 13:49:39 +01:00
}
/*
2006-10-19 00:43:51 +02:00
Print xml tag . Optionally add attribute ( s ) .
2006-05-25 10:00:28 +02:00
2003-11-03 13:49:39 +01:00
SYNOPSIS
2006-10-19 00:43:51 +02:00
print_xml_tag ( xml_file , sbeg , send , tag_name , first_attribute_name ,
. . . , attribute_name_n , attribute_value_n , NullS )
xml_file - output file
sbeg - line beginning
send - line ending
tag_name - XML tag name .
first_attribute_name - tag and first attribute
first_attribute_value - ( Implied ) value of first attribute
attribute_name_n - attribute n
attribute_value_n - value of attribute n
2006-05-25 10:00:28 +02:00
2003-11-03 13:49:39 +01:00
DESCRIPTION
2006-10-19 00:43:51 +02:00
Print XML tag with any number of attribute = " value " pairs to the xml_file .
Format is :
sbeg < tag_name first_attribute_name = " first_attribute_value " . . .
attribute_name_n = " attribute_value_n " > send
2003-11-03 13:49:39 +01:00
NOTE
2006-10-19 00:43:51 +02:00
Additional arguments must be present in attribute / value pairs .
The last argument should be the null character pointer .
All attribute_value arguments MUST be NULL terminated strings .
All attribute_value arguments will be quoted before output .
2003-11-03 13:49:39 +01:00
*/
2006-10-19 00:43:51 +02:00
static void print_xml_tag ( FILE * xml_file , const char * sbeg , const char * send ,
const char * tag_name ,
const char * first_attribute_name , . . . )
2003-11-03 13:49:39 +01:00
{
2006-10-19 00:43:51 +02:00
va_list arg_list ;
2006-10-24 13:52:50 +02:00
const char * attribute_name , * attribute_value ;
2006-10-19 00:43:51 +02:00
2003-11-03 13:49:39 +01:00
fputs ( sbeg , xml_file ) ;
2006-10-19 00:43:51 +02:00
fputc ( ' < ' , xml_file ) ;
fputs ( tag_name , xml_file ) ;
va_start ( arg_list , first_attribute_name ) ;
attribute_name = first_attribute_name ;
while ( attribute_name ! = NullS )
{
attribute_value = va_arg ( arg_list , char * ) ;
DBUG_ASSERT ( attribute_value ! = NullS ) ;
fputc ( ' ' , xml_file ) ;
fputs ( attribute_name , xml_file ) ;
fputc ( ' \" ' , xml_file ) ;
print_quoted_xml ( xml_file , attribute_value , strlen ( attribute_value ) ) ;
fputc ( ' \" ' , xml_file ) ;
attribute_name = va_arg ( arg_list , char * ) ;
}
va_end ( arg_list ) ;
fputc ( ' > ' , xml_file ) ;
2003-11-03 13:49:39 +01:00
fputs ( send , xml_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( xml_file ) ;
2003-11-03 13:49:39 +01:00
}
2005-06-22 20:22:54 +02:00
/*
Print xml tag with for a field that is null
SYNOPSIS
print_xml_null_tag ( )
2006-05-25 10:00:28 +02:00
xml_file - output file
sbeg - line beginning
stag_atr - tag and attribute
sval - value of attribute
send - line ending
2005-06-22 20:22:54 +02:00
DESCRIPTION
Print tag with one attribute to the xml_file . Format is :
< stag_atr = " sval " xsi : nil = " true " / >
NOTE
sval MUST be a NULL terminated string .
sval string will be qouted before output .
*/
static void print_xml_null_tag ( FILE * xml_file , const char * sbeg ,
const char * stag_atr , const char * sval ,
const char * send )
{
fputs ( sbeg , xml_file ) ;
fputs ( " < " , xml_file ) ;
fputs ( stag_atr , xml_file ) ;
fputs ( " \" " , xml_file ) ;
print_quoted_xml ( xml_file , sval , strlen ( sval ) ) ;
fputs ( " \" xsi:nil= \" true \" /> " , xml_file ) ;
fputs ( send , xml_file ) ;
check_io ( xml_file ) ;
}
2003-11-03 13:49:39 +01:00
/*
Print xml tag with many attributes .
SYNOPSIS
print_xml_row ( )
2006-05-25 10:00:28 +02:00
xml_file - output file
row_name - xml tag name
tableRes - query result
row - result row
2003-11-03 13:49:39 +01:00
DESCRIPTION
Print tag with many attribute to the xml_file . Format is :
\ t \ t < row_name Atr1 = " Val1 " Atr2 = " Val2 " . . . / >
NOTE
All atributes and values will be quoted before output .
*/
static void print_xml_row ( FILE * xml_file , const char * row_name ,
2006-05-25 10:00:28 +02:00
MYSQL_RES * tableRes , MYSQL_ROW * row )
2003-10-30 11:58:30 +01:00
{
uint i ;
MYSQL_FIELD * field ;
ulong * lengths = mysql_fetch_lengths ( tableRes ) ;
2005-09-04 01:34:58 +02:00
2003-10-30 11:58:30 +01:00
fprintf ( xml_file , " \t \t <%s " , row_name ) ;
2004-06-24 22:14:12 +02:00
check_io ( xml_file ) ;
2003-10-30 11:58:30 +01:00
mysql_field_seek ( tableRes , 0 ) ;
for ( i = 0 ; ( field = mysql_fetch_field ( tableRes ) ) ; i + + )
{
2003-11-03 13:49:39 +01:00
if ( ( * row ) [ i ] )
2003-10-30 11:58:30 +01:00
{
2004-04-26 14:53:31 +02:00
fputc ( ' ' , xml_file ) ;
2003-11-03 13:49:39 +01:00
print_quoted_xml ( xml_file , field - > name , field - > name_length ) ;
2003-10-30 11:58:30 +01:00
fputs ( " = \" " , xml_file ) ;
print_quoted_xml ( xml_file , ( * row ) [ i ] , lengths [ i ] ) ;
2004-04-27 14:33:40 +02:00
fputc ( ' " ' , xml_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( xml_file ) ;
2003-10-30 11:58:30 +01:00
}
}
fputs ( " /> \n " , xml_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( xml_file ) ;
2003-10-30 11:58:30 +01:00
}
2006-10-19 00:43:51 +02:00
/*
Print hex value for blob data .
SYNOPSIS
print_blob_as_hex ( )
output_file - output file
str - string to print
len - its length
DESCRIPTION
Print hex value for blob data .
*/
static void print_blob_as_hex ( FILE * output_file , const char * str , ulong len )
{
/* sakaik got the idea to to provide blob's in hex notation. */
2006-10-24 13:52:50 +02:00
const char * ptr = str , * end = ptr + len ;
2006-10-19 00:43:51 +02:00
for ( ; ptr < end ; ptr + + )
fprintf ( output_file , " %02X " , * ( ( uchar * ) ptr ) ) ;
check_io ( output_file ) ;
}
2005-09-04 01:34:58 +02:00
/*
dump_routines_for_db
- - retrievs list of routines for a given db , and prints out
the CREATE PROCEDURE definition into the output ( the dump ) .
This function has logic to print the appropriate syntax depending on whether
this is a procedure or functions
2005-10-06 16:54:43 +02:00
RETURN
0 Success
1 Error
2005-09-04 01:34:58 +02:00
*/
2005-10-06 16:54:43 +02:00
static uint dump_routines_for_db ( char * db )
2005-09-04 01:34:58 +02:00
{
2005-09-14 03:40:18 +02:00
char query_buff [ 512 ] ;
2005-10-06 16:54:43 +02:00
const char * routine_type [ ] = { " FUNCTION " , " PROCEDURE " } ;
char db_name_buff [ NAME_LEN * 2 + 3 ] , name_buff [ NAME_LEN * 2 + 3 ] ;
char * routine_name ;
2005-09-04 01:34:58 +02:00
int i ;
2005-10-06 16:54:43 +02:00
FILE * sql_file = md_result_file ;
2005-09-13 19:32:37 +02:00
MYSQL_RES * routine_res , * routine_list_res ;
2005-09-08 19:45:25 +02:00
MYSQL_ROW row , routine_list_row ;
2005-09-04 01:34:58 +02:00
DBUG_ENTER ( " dump_routines_for_db " ) ;
2005-10-06 16:54:43 +02:00
DBUG_PRINT ( " enter " , ( " db: '%s' " , db ) ) ;
2005-09-04 01:34:58 +02:00
2006-07-24 12:00:44 +02:00
mysql_real_escape_string ( mysql , db_name_buff , db , strlen ( db ) ) ;
2005-09-04 01:34:58 +02:00
/* nice comments */
if ( opt_comments )
fprintf ( sql_file , " \n -- \n -- Dumping routines for database '%s' \n -- \n " , db ) ;
2005-09-08 19:45:25 +02:00
/*
2005-09-13 19:32:37 +02:00
not using " mysql_query_with_error_report " because we may have not
enough privileges to lock mysql . proc .
2005-09-08 19:45:25 +02:00
*/
2005-09-13 19:32:37 +02:00
if ( lock_tables )
2006-07-24 12:00:44 +02:00
mysql_query ( mysql , " LOCK TABLES mysql.proc READ " ) ;
2005-09-08 19:45:25 +02:00
2005-10-06 16:54:43 +02:00
fprintf ( sql_file , " DELIMITER ;; \n " ) ;
2005-09-04 01:34:58 +02:00
/* 0, retrieve and dump functions, 1, procedures */
2005-10-06 16:54:43 +02:00
for ( i = 0 ; i < = 1 ; i + + )
2005-09-04 01:34:58 +02:00
{
my_snprintf ( query_buff , sizeof ( query_buff ) ,
" SHOW %s STATUS WHERE Db = '%s' " ,
2005-09-13 19:32:37 +02:00
routine_type [ i ] , db_name_buff ) ;
2005-09-04 01:34:58 +02:00
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & routine_list_res , query_buff ) )
2005-09-04 01:34:58 +02:00
DBUG_RETURN ( 1 ) ;
if ( mysql_num_rows ( routine_list_res ) )
{
2005-10-06 16:54:43 +02:00
while ( ( routine_list_row = mysql_fetch_row ( routine_list_res ) ) )
2005-09-04 01:34:58 +02:00
{
2005-09-13 19:32:37 +02:00
DBUG_PRINT ( " info " , ( " retrieving CREATE %s for %s " , routine_type [ i ] ,
name_buff ) ) ;
2005-10-06 16:54:43 +02:00
routine_name = quote_name ( routine_list_row [ 1 ] , name_buff , 0 ) ;
2005-09-04 01:34:58 +02:00
my_snprintf ( query_buff , sizeof ( query_buff ) , " SHOW CREATE %s %s " ,
2005-09-13 19:32:37 +02:00
routine_type [ i ] , routine_name ) ;
2005-09-04 01:34:58 +02:00
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & routine_res , query_buff ) )
2005-09-04 01:34:58 +02:00
DBUG_RETURN ( 1 ) ;
2005-10-06 16:54:43 +02:00
while ( ( row = mysql_fetch_row ( routine_res ) ) )
2005-09-04 01:34:58 +02:00
{
/*
2005-09-13 19:32:37 +02:00
if the user has EXECUTE privilege he see routine names , but NOT the
routine body of other routines that are not the creator of !
2005-09-04 01:34:58 +02:00
*/
DBUG_PRINT ( " info " , ( " length of body for %s row[2] '%s' is %d " ,
2005-09-13 19:32:37 +02:00
routine_name , row [ 2 ] , strlen ( row [ 2 ] ) ) ) ;
2005-09-04 01:34:58 +02:00
if ( strlen ( row [ 2 ] ) )
{
2006-03-02 13:18:49 +01:00
char * query_str = NULL ;
char * definer_begin ;
2005-09-04 01:34:58 +02:00
if ( opt_drop )
2005-10-06 16:54:43 +02:00
fprintf ( sql_file , " /*!50003 DROP %s IF EXISTS %s */;; \n " ,
2005-09-13 19:32:37 +02:00
routine_type [ i ] , routine_name ) ;
2006-03-02 13:18:49 +01:00
/*
Cover DEFINER - clause in version - specific comments .
TODO : this is definitely a BAD IDEA to parse SHOW CREATE output .
We should user INFORMATION_SCHEMA instead . The only problem is
that now INFORMATION_SCHEMA does not provide information about
routine parameters .
*/
definer_begin = strstr ( row [ 2 ] , " DEFINER " ) ;
2006-05-25 10:00:28 +02:00
2006-03-02 13:18:49 +01:00
if ( definer_begin )
{
char * definer_end = strstr ( definer_begin , " PROCEDURE " ) ;
if ( ! definer_end )
definer_end = strstr ( definer_begin , " FUNCTION " ) ;
if ( definer_end )
{
char * query_str_tail ;
/*
Allocate memory for new query string : original string
from SHOW statement and version - specific comments .
*/
query_str = alloc_query_str ( strlen ( row [ 2 ] ) + 23 ) ;
query_str_tail = strnmov ( query_str , row [ 2 ] ,
definer_begin - row [ 2 ] ) ;
2006-03-10 20:23:04 +01:00
query_str_tail = strmov ( query_str_tail , " */ /*!50020 " ) ;
2006-03-02 13:18:49 +01:00
query_str_tail = strnmov ( query_str_tail , definer_begin ,
definer_end - definer_begin ) ;
query_str_tail = strxmov ( query_str_tail , " */ /*!50003 " ,
definer_end , NullS ) ;
}
}
2005-09-04 01:34:58 +02:00
/*
2005-10-06 16:54:43 +02:00
we need to change sql_mode only for the CREATE
PROCEDURE / FUNCTION otherwise we may need to re - quote routine_name
2005-09-13 19:32:37 +02:00
*/ ;
2005-10-06 16:54:43 +02:00
fprintf ( sql_file , " /*!50003 SET SESSION SQL_MODE= \" %s \" */;; \n " ,
2005-09-13 19:32:37 +02:00
row [ 1 ] /* sql_mode */ ) ;
2006-03-02 13:18:49 +01:00
fprintf ( sql_file , " /*!50003 %s */;; \n " ,
( query_str ! = NULL ? query_str : row [ 2 ] ) ) ;
2005-10-06 16:54:43 +02:00
fprintf ( sql_file ,
" /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ "
" ;; \n " ) ;
2006-03-02 13:18:49 +01:00
my_free ( query_str , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
2005-09-04 01:34:58 +02:00
}
} /* end of routine printing */
} /* end of list of routines */
mysql_free_result ( routine_res ) ;
}
mysql_free_result ( routine_list_res ) ;
} /* end of for i (0 .. 1) */
2005-09-08 19:45:25 +02:00
/* set the delimiter back to ';' */
fprintf ( sql_file , " DELIMITER ; \n " ) ;
2005-09-04 01:34:58 +02:00
2005-09-13 19:32:37 +02:00
if ( lock_tables )
2006-07-24 12:00:44 +02:00
VOID ( mysql_query_with_error_report ( mysql , 0 , " UNLOCK TABLES " ) ) ;
2005-09-04 01:34:58 +02:00
DBUG_RETURN ( 0 ) ;
}
2005-03-14 23:47:35 +01:00
2000-07-31 21:29:14 +02:00
/*
2005-09-27 07:43:09 +02:00
get_table_structure - - retrievs database structure , prints out corresponding
CREATE statement and fills out insert_pat if the table is the type we will
be dumping .
ARGS
table - table name
db - db name
2006-05-25 10:00:28 +02:00
table_type - table type , e . g . " MyISAM " or " InnoDB " , but also " VIEW "
2005-09-27 07:43:09 +02:00
ignore_flag - what we must particularly ignore - see IGNORE_ defines above
2003-09-03 17:48:10 +02:00
RETURN
number of fields in table , 0 if error
2000-07-31 21:29:14 +02:00
*/
2003-09-03 17:48:10 +02:00
2005-09-27 07:43:09 +02:00
static uint get_table_structure ( char * table , char * db , char * table_type ,
char * ignore_flag )
2000-07-31 21:29:14 +02:00
{
2005-10-11 23:58:22 +02:00
my_bool init = 0 , delayed , write_data , complete_insert ;
2005-10-25 19:04:31 +02:00
my_ulonglong num_fields ;
2006-05-25 10:00:28 +02:00
char * result_table , * opt_quoted_table ;
2005-05-07 18:49:39 +02:00
const char * insert_option ;
2006-05-25 10:00:28 +02:00
char name_buff [ NAME_LEN + 3 ] , table_buff [ NAME_LEN * 2 + 3 ] ;
char table_buff2 [ NAME_LEN * 2 + 3 ] , query_buff [ 512 ] ;
2006-08-02 03:18:47 +02:00
FILE * sql_file = md_result_file ;
2005-05-18 18:12:37 +02:00
int len ;
2005-10-25 19:04:31 +02:00
MYSQL_RES * result ;
MYSQL_ROW row ;
2005-04-04 23:32:48 +02:00
DBUG_ENTER ( " get_table_structure " ) ;
2005-10-11 23:58:22 +02:00
DBUG_PRINT ( " enter " , ( " db: %s table: %s " , db , table ) ) ;
2000-07-31 21:29:14 +02:00
2005-09-27 07:43:09 +02:00
* ignore_flag = check_if_ignore_table ( table , table_type ) ;
2005-10-11 23:58:22 +02:00
delayed = opt_delayed ;
if ( delayed & & ( * ignore_flag & IGNORE_INSERT_DELAYED ) )
{
delayed = 0 ;
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Warning: Unable to use delayed inserts for table '%s' "
" because it's of type %s \n " , table , table_type ) ;
2005-10-11 23:58:22 +02:00
}
2005-09-27 07:43:09 +02:00
2005-10-11 23:58:22 +02:00
complete_insert = 0 ;
if ( ( write_data = ! ( * ignore_flag & IGNORE_DATA ) ) )
2005-05-08 21:02:46 +02:00
{
2005-10-11 23:58:22 +02:00
complete_insert = opt_complete_insert ;
2005-09-27 07:43:09 +02:00
if ( ! insert_pat_inited )
insert_pat_inited = init_dynamic_string ( & insert_pat , " " , 1024 , 1024 ) ;
else
dynstr_set ( & insert_pat , " " ) ;
2005-05-08 21:02:46 +02:00
}
2005-10-11 23:58:22 +02:00
insert_option = ( ( delayed & & opt_ignore ) ? " DELAYED IGNORE " :
delayed ? " DELAYED " : opt_ignore ? " IGNORE " : " " ) ;
2000-07-31 21:29:14 +02:00
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Retrieving table structure for table %s... \n " , table ) ;
2000-07-31 21:29:14 +02:00
2005-05-18 18:12:37 +02:00
len = my_snprintf ( query_buff , sizeof ( query_buff ) ,
" SET OPTION SQL_QUOTE_SHOW_CREATE=%d " ,
( opt_quoted | | opt_keywords ) ) ;
2004-04-27 14:33:40 +02:00
if ( ! create_options )
2005-09-27 07:43:09 +02:00
strmov ( query_buff + len ,
" /*!40102 ,SQL_MODE=concat(@@sql_mode, _utf8 ',NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS') */ " ) ;
2004-04-27 14:33:40 +02:00
2003-09-03 17:48:10 +02:00
result_table = quote_name ( table , table_buff , 1 ) ;
opt_quoted_table = quote_name ( table , table_buff2 , 0 ) ;
2004-11-16 23:45:24 +01:00
if ( opt_order_by_primary )
2006-08-02 03:18:47 +02:00
order_by = primary_key_fields ( result_table ) ;
2004-11-16 23:45:24 +01:00
2006-07-24 12:00:44 +02:00
if ( ! opt_xml & & ! mysql_query_with_error_report ( mysql , 0 , query_buff ) )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
/* using SHOW CREATE statement */
2006-07-24 11:56:01 +02:00
if ( ! opt_no_create_info )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
/* Make an sql-file, if path was given iow. option -T was given */
char buff [ 20 + FN_REFLEN ] ;
2004-11-12 04:01:46 +01:00
MYSQL_FIELD * field ;
2000-10-29 13:49:42 +01:00
2005-03-16 21:56:56 +01:00
my_snprintf ( buff , sizeof ( buff ) , " show create table %s " , result_table ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , 0 , buff ) )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
if ( path )
{
2006-02-21 13:21:17 +01:00
if ( ! ( sql_file = open_sql_file_for_table ( table ) ) )
2000-10-29 13:49:42 +01:00
{
2006-05-25 10:00:28 +02:00
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
2000-10-29 13:49:42 +01:00
}
2002-01-02 20:29:41 +01:00
write_header ( sql_file , db ) ;
2000-10-29 13:49:42 +01:00
}
2003-12-11 14:37:45 +01:00
if ( ! opt_xml & & opt_comments )
2004-06-24 22:14:12 +02:00
{
2006-05-25 10:00:28 +02:00
if ( strcmp ( table_type , " VIEW " ) = = 0 ) /* view */
fprintf ( sql_file , " \n -- \n -- Temporary table structure for view %s \n -- \n \n " ,
result_table ) ;
else
2003-12-17 16:35:34 +01:00
fprintf ( sql_file , " \n -- \n -- Table structure for table %s \n -- \n \n " ,
2006-05-25 10:00:28 +02:00
result_table ) ;
check_io ( sql_file ) ;
2004-06-24 22:14:12 +02:00
}
2000-10-29 13:49:42 +01:00
if ( opt_drop )
2004-06-24 22:14:12 +02:00
{
2006-05-25 10:00:28 +02:00
/*
Even if the " table " is a view , we do a DROP TABLE here . The
view - specific code below fills in the DROP VIEW .
*/
fprintf ( sql_file , " DROP TABLE IF EXISTS %s; \n " ,
opt_quoted_table ) ;
check_io ( sql_file ) ;
2004-06-24 22:14:12 +02:00
}
2000-10-29 13:49:42 +01:00
2006-07-24 12:00:44 +02:00
result = mysql_store_result ( mysql ) ;
2005-10-25 19:04:31 +02:00
field = mysql_fetch_field_direct ( result , 0 ) ;
2004-11-12 04:01:46 +01:00
if ( strcmp ( field - > name , " View " ) = = 0 )
{
2006-08-02 03:18:47 +02:00
char * scv_buff = NULL ;
2006-05-30 14:49:05 +02:00
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- It's a view, create dummy table for view \n " ) ;
2005-06-16 15:58:17 +02:00
2006-05-30 14:49:05 +02:00
/* save "show create" statement for later */
if ( ( row = mysql_fetch_row ( result ) ) & & ( scv_buff = row [ 1 ] ) )
scv_buff = my_strdup ( scv_buff , MYF ( 0 ) ) ;
2005-10-25 19:04:31 +02:00
mysql_free_result ( result ) ;
/*
2006-05-25 10:00:28 +02:00
Create a table with the same name as the view and with columns of
2005-10-25 19:04:31 +02:00
the same name in order to satisfy views that depend on this view .
The table will be removed when the actual view is created .
2005-06-16 15:58:17 +02:00
2005-10-25 19:04:31 +02:00
The properties of each column , aside from the data type , are not
preserved in this temporary table , because they are not necessary .
2005-06-16 15:58:17 +02:00
2005-10-25 19:04:31 +02:00
This will not be necessary once we can determine dependencies
between views and can simply dump them in the appropriate order .
*/
2005-06-16 15:58:17 +02:00
my_snprintf ( query_buff , sizeof ( query_buff ) ,
2005-10-25 19:04:31 +02:00
" SHOW FIELDS FROM %s " , result_table ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , 0 , query_buff ) )
2005-06-16 15:58:17 +02:00
{
2006-05-30 14:49:05 +02:00
/*
View references invalid or privileged table / col / fun ( err 1356 ) ,
so we cannot create a stand - in table . Be defensive and dump
a comment with the view ' s ' show create ' statement . ( Bug # 17371 )
*/
2006-07-24 12:00:44 +02:00
if ( mysql_errno ( mysql ) = = ER_VIEW_INVALID )
2006-05-30 14:49:05 +02:00
fprintf ( sql_file , " \n -- failed on view %s: %s \n \n " , result_table , scv_buff ? scv_buff : " " ) ;
my_free ( scv_buff , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
2005-06-16 15:58:17 +02:00
safe_exit ( EX_MYSQLERR ) ;
2006-08-02 03:18:47 +02:00
DBUG_RETURN ( 0 ) ;
2005-06-16 15:58:17 +02:00
}
2006-05-30 14:49:05 +02:00
else
my_free ( scv_buff , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
2005-06-16 15:58:17 +02:00
2006-07-24 12:00:44 +02:00
if ( ( result = mysql_store_result ( mysql ) ) )
2005-06-16 15:58:17 +02:00
{
2005-10-25 19:04:31 +02:00
if ( mysql_num_rows ( result ) )
{
if ( opt_drop )
{
2006-05-25 10:00:28 +02:00
/*
We have already dropped any table of the same name
above , so here we just drop the view .
*/
2005-10-25 19:04:31 +02:00
fprintf ( sql_file , " /*!50001 DROP VIEW IF EXISTS %s*/; \n " ,
opt_quoted_table ) ;
check_io ( sql_file ) ;
}
2005-06-16 15:58:17 +02:00
2005-10-25 19:04:31 +02:00
fprintf ( sql_file , " /*!50001 CREATE TABLE %s ( \n " , result_table ) ;
/*
Get first row , following loop will prepend comma - keeps
from having to know if the row being printed is last to
determine if there should be a _trailing_ comma .
*/
row = mysql_fetch_row ( result ) ;
2005-10-27 21:45:18 +02:00
fprintf ( sql_file , " %s %s " , quote_name ( row [ 0 ] , name_buff , 0 ) ,
row [ 1 ] ) ;
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( result ) ) )
{
/* col name, col type */
fprintf ( sql_file , " , \n %s %s " ,
quote_name ( row [ 0 ] , name_buff , 0 ) , row [ 1 ] ) ;
}
fprintf ( sql_file , " \n ) */; \n " ) ;
check_io ( sql_file ) ;
}
2005-06-16 15:58:17 +02:00
}
2005-10-25 19:04:31 +02:00
mysql_free_result ( result ) ;
2006-05-31 13:36:28 +02:00
if ( path )
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
2006-05-25 10:00:28 +02:00
seen_views = 1 ;
2004-11-12 04:01:46 +01:00
DBUG_RETURN ( 0 ) ;
}
2005-10-25 19:04:31 +02:00
row = mysql_fetch_row ( result ) ;
2003-10-30 11:58:30 +01:00
fprintf ( sql_file , " %s; \n " , row [ 1 ] ) ;
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
2005-10-25 19:04:31 +02:00
mysql_free_result ( result ) ;
2000-10-29 13:49:42 +01:00
}
2005-05-08 21:02:46 +02:00
my_snprintf ( query_buff , sizeof ( query_buff ) , " show fields from %s " ,
2006-05-25 10:00:28 +02:00
result_table ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & result , query_buff ) )
2000-07-31 21:29:14 +02:00
{
2002-01-02 20:29:41 +01:00
if ( path )
2006-05-25 10:00:28 +02:00
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
2000-10-29 13:49:42 +01:00
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
2005-09-27 07:43:09 +02:00
/*
2005-10-11 23:58:22 +02:00
If write_data is true , then we build up insert statements for
the table ' s data . Note : in subsequent lines of code , this test
will have to be performed each time we are appending to
insert_pat .
2005-09-27 07:43:09 +02:00
*/
2005-10-11 23:58:22 +02:00
if ( write_data )
2000-07-31 21:29:14 +02:00
{
2005-09-27 07:43:09 +02:00
dynstr_append_mem ( & insert_pat , " INSERT " , 7 ) ;
dynstr_append ( & insert_pat , insert_option ) ;
dynstr_append_mem ( & insert_pat , " INTO " , 5 ) ;
dynstr_append ( & insert_pat , opt_quoted_table ) ;
2005-10-11 23:58:22 +02:00
if ( complete_insert )
2005-09-27 07:43:09 +02:00
{
dynstr_append_mem ( & insert_pat , " ( " , 2 ) ;
}
else
{
dynstr_append_mem ( & insert_pat , " VALUES " , 8 ) ;
if ( ! extended_insert )
dynstr_append_mem ( & insert_pat , " ( " , 1 ) ;
}
2000-10-29 13:49:42 +01:00
}
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( result ) ) )
2000-10-29 13:49:42 +01:00
{
2005-10-11 23:58:22 +02:00
if ( complete_insert )
2000-07-31 21:29:14 +02:00
{
2005-10-11 23:58:22 +02:00
if ( init )
{
2005-05-08 21:02:46 +02:00
dynstr_append_mem ( & insert_pat , " , " , 2 ) ;
2005-10-11 23:58:22 +02:00
}
init = 1 ;
2005-05-08 21:02:46 +02:00
dynstr_append ( & insert_pat ,
quote_name ( row [ SHOW_FIELDNAME ] , name_buff , 0 ) ) ;
2005-10-11 23:58:22 +02:00
}
2000-07-31 21:29:14 +02:00
}
2005-10-25 19:04:31 +02:00
num_fields = mysql_num_rows ( result ) ;
mysql_free_result ( result ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
else
2000-07-31 21:29:14 +02:00
{
2006-07-24 11:51:52 +02:00
verbose_msg ( " %s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s) \n " ,
2006-07-24 12:00:44 +02:00
my_progname , mysql_error ( mysql ) ) ;
2000-10-29 13:49:42 +01:00
2005-05-08 21:02:46 +02:00
my_snprintf ( query_buff , sizeof ( query_buff ) , " show fields from %s " ,
2006-05-25 10:00:28 +02:00
result_table ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & result , query_buff ) )
2000-07-31 21:29:14 +02:00
{
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
}
2000-10-29 13:49:42 +01:00
/* Make an sql-file, if path was given iow. option -T was given */
2006-07-24 11:56:01 +02:00
if ( ! opt_no_create_info )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
if ( path )
2000-07-31 21:29:14 +02:00
{
2006-02-21 13:21:17 +01:00
if ( ! ( sql_file = open_sql_file_for_table ( table ) ) )
2000-10-29 13:49:42 +01:00
{
2006-05-25 10:00:28 +02:00
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
2000-10-29 13:49:42 +01:00
}
2002-01-02 20:29:41 +01:00
write_header ( sql_file , db ) ;
2000-07-31 21:29:14 +02:00
}
2003-12-11 14:37:45 +01:00
if ( ! opt_xml & & opt_comments )
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " \n -- \n -- Table structure for table %s \n -- \n \n " ,
result_table ) ;
2000-10-29 13:49:42 +01:00
if ( opt_drop )
2005-07-18 14:33:18 +02:00
fprintf ( sql_file , " DROP TABLE IF EXISTS %s; \n " , result_table ) ;
2003-10-30 11:58:30 +01:00
if ( ! opt_xml )
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " CREATE TABLE %s ( \n " , result_table ) ;
2003-10-30 11:58:30 +01:00
else
2006-10-19 00:43:51 +02:00
print_xml_tag ( sql_file , " \t " , " \n " , " table_structure " , " name= " , table ,
NullS ) ;
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
2000-10-29 13:49:42 +01:00
}
2005-05-08 21:02:46 +02:00
2005-10-11 23:58:22 +02:00
if ( write_data )
2005-05-08 21:02:46 +02:00
{
2005-09-27 07:43:09 +02:00
dynstr_append_mem ( & insert_pat , " INSERT " , 7 ) ;
dynstr_append ( & insert_pat , insert_option ) ;
dynstr_append_mem ( & insert_pat , " INTO " , 5 ) ;
dynstr_append ( & insert_pat , result_table ) ;
if ( opt_complete_insert )
dynstr_append_mem ( & insert_pat , " ( " , 2 ) ;
else
{
dynstr_append_mem ( & insert_pat , " VALUES " , 8 ) ;
if ( ! extended_insert )
dynstr_append_mem ( & insert_pat , " ( " , 1 ) ;
}
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( result ) ) )
2000-07-31 21:29:14 +02:00
{
2005-10-25 19:04:31 +02:00
ulong * lengths = mysql_fetch_lengths ( result ) ;
2000-10-29 13:49:42 +01:00
if ( init )
2000-07-31 21:29:14 +02:00
{
2006-07-24 11:56:01 +02:00
if ( ! opt_xml & & ! opt_no_create_info )
2006-05-25 10:00:28 +02:00
{
fputs ( " , \n " , sql_file ) ;
check_io ( sql_file ) ;
}
2005-10-11 23:58:22 +02:00
if ( complete_insert )
2005-05-08 21:02:46 +02:00
dynstr_append_mem ( & insert_pat , " , " , 2 ) ;
2000-10-29 13:49:42 +01:00
}
init = 1 ;
2005-10-11 23:58:22 +02:00
if ( opt_complete_insert )
2005-05-08 21:02:46 +02:00
dynstr_append ( & insert_pat ,
quote_name ( row [ SHOW_FIELDNAME ] , name_buff , 0 ) ) ;
2006-07-24 11:56:01 +02:00
if ( ! opt_no_create_info )
2000-10-29 13:49:42 +01:00
{
2006-05-25 10:00:28 +02:00
if ( opt_xml )
{
print_xml_row ( sql_file , " field " , result , & row ) ;
continue ;
}
2005-05-08 21:02:46 +02:00
2000-10-29 13:49:42 +01:00
if ( opt_keywords )
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " %s.%s %s " , result_table ,
quote_name ( row [ SHOW_FIELDNAME ] , name_buff , 0 ) ,
row [ SHOW_TYPE ] ) ;
2000-10-29 13:49:42 +01:00
else
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " %s %s " , quote_name ( row [ SHOW_FIELDNAME ] ,
name_buff , 0 ) ,
row [ SHOW_TYPE ] ) ;
2000-10-29 13:49:42 +01:00
if ( row [ SHOW_DEFAULT ] )
{
2006-05-25 10:00:28 +02:00
fputs ( " DEFAULT " , sql_file ) ;
unescape ( sql_file , row [ SHOW_DEFAULT ] , lengths [ SHOW_DEFAULT ] ) ;
2000-10-29 13:49:42 +01:00
}
if ( ! row [ SHOW_NULL ] [ 0 ] )
2006-05-25 10:00:28 +02:00
fputs ( " NOT NULL " , sql_file ) ;
2000-10-29 13:49:42 +01:00
if ( row [ SHOW_EXTRA ] [ 0 ] )
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " %s " , row [ SHOW_EXTRA ] ) ;
check_io ( sql_file ) ;
2000-07-31 21:29:14 +02:00
}
}
2005-10-25 19:04:31 +02:00
num_fields = mysql_num_rows ( result ) ;
mysql_free_result ( result ) ;
2006-07-24 11:56:01 +02:00
if ( ! opt_no_create_info )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
/* Make an sql-file, if path was given iow. option -T was given */
char buff [ 20 + FN_REFLEN ] ;
uint keynr , primary_key ;
2005-03-16 21:56:56 +01:00
my_snprintf ( buff , sizeof ( buff ) , " show keys from %s " , result_table ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & result , buff ) )
2000-07-31 21:29:14 +02:00
{
2006-07-24 12:00:44 +02:00
if ( mysql_errno ( mysql ) = = ER_WRONG_OBJECT )
2004-11-12 04:01:46 +01:00
{
/* it is VIEW */
fputs ( " \t \t <options Comment= \" view \" /> \n " , sql_file ) ;
goto continue_xml ;
}
fprintf ( stderr , " %s: Can't get keys for table %s (%s) \n " ,
2006-07-24 12:00:44 +02:00
my_progname , result_table , mysql_error ( mysql ) ) ;
2002-01-02 20:29:41 +01:00
if ( path )
2006-05-25 10:00:28 +02:00
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
2000-10-29 13:49:42 +01:00
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
/* Find first which key is primary key */
keynr = 0 ;
primary_key = INT_MAX ;
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( result ) ) )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
if ( atoi ( row [ 3 ] ) = = 1 )
{
2006-05-25 10:00:28 +02:00
keynr + + ;
2001-04-23 23:31:34 +02:00
# ifdef FORCE_PRIMARY_KEY
2006-05-25 10:00:28 +02:00
if ( atoi ( row [ 1 ] ) = = 0 & & primary_key = = INT_MAX )
primary_key = keynr ;
2001-04-23 23:31:34 +02:00
# endif
2006-05-25 10:00:28 +02:00
if ( ! strcmp ( row [ 2 ] , " PRIMARY " ) )
{
primary_key = keynr ;
break ;
}
2000-10-29 13:49:42 +01:00
}
2000-07-31 21:29:14 +02:00
}
2005-10-25 19:04:31 +02:00
mysql_data_seek ( result , 0 ) ;
2000-10-29 13:49:42 +01:00
keynr = 0 ;
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( result ) ) )
2000-10-29 13:49:42 +01:00
{
2006-05-25 10:00:28 +02:00
if ( opt_xml )
{
print_xml_row ( sql_file , " key " , result , & row ) ;
continue ;
}
2005-09-27 07:43:09 +02:00
2000-10-29 13:49:42 +01:00
if ( atoi ( row [ 3 ] ) = = 1 )
{
2006-05-25 10:00:28 +02:00
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 , 0 ) ) ;
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 ,
0 ) ) ;
2000-10-29 13:49:42 +01:00
}
else
2006-05-25 10:00:28 +02:00
putc ( ' , ' , sql_file ) ;
2003-09-03 17:48:10 +02:00
fputs ( quote_name ( row [ 4 ] , name_buff , 0 ) , sql_file ) ;
2000-10-29 13:49:42 +01:00
if ( row [ 7 ] )
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " (%s) " , row [ 7 ] ) ; /* Sub key */
check_io ( sql_file ) ;
2000-10-29 13:49:42 +01:00
}
2003-10-30 11:58:30 +01:00
if ( ! opt_xml )
{
2006-05-25 10:00:28 +02:00
if ( keynr )
putc ( ' ) ' , sql_file ) ;
fputs ( " \n ) " , sql_file ) ;
check_io ( sql_file ) ;
2003-10-30 11:58:30 +01:00
}
2000-10-29 13:49:42 +01:00
/* Get MySQL specific create options */
if ( create_options )
2000-07-31 21:29:14 +02:00
{
2006-05-25 10:00:28 +02:00
char show_name_buff [ NAME_LEN * 2 + 2 + 24 ] ;
2005-03-16 21:56:56 +01:00
2006-05-25 10:00:28 +02:00
/* Check memory for quote_for_like() */
2005-03-16 21:56:56 +01:00
my_snprintf ( buff , sizeof ( buff ) , " show table status like %s " ,
2006-05-25 10:00:28 +02:00
quote_for_like ( table , show_name_buff ) ) ;
2005-03-16 21:56:56 +01:00
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & result , buff ) )
2000-10-29 13:49:42 +01:00
{
2006-07-24 12:00:44 +02:00
if ( mysql_errno ( mysql ) ! = ER_PARSE_ERROR )
2006-05-25 10:00:28 +02:00
{ /* If old MySQL version */
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Warning: Couldn't get status information for " \
2006-07-24 12:00:44 +02:00
" table %s (%s) \n " , result_table , mysql_error ( mysql ) ) ;
2006-05-25 10:00:28 +02:00
}
2000-10-29 13:49:42 +01:00
}
2005-10-25 19:04:31 +02:00
else if ( ! ( row = mysql_fetch_row ( result ) ) )
2000-10-29 13:49:42 +01:00
{
2006-05-25 10:00:28 +02:00
fprintf ( stderr ,
" Error: Couldn't read status information for table %s (%s) \n " ,
2006-07-24 12:00:44 +02:00
result_table , mysql_error ( mysql ) ) ;
2000-10-29 13:49:42 +01:00
}
else
{
2006-05-25 10:00:28 +02:00
if ( opt_xml )
print_xml_row ( sql_file , " options " , result , & row ) ;
else
{
fputs ( " /*! " , sql_file ) ;
print_value ( sql_file , result , row , " engine= " , " Engine " , 0 ) ;
print_value ( sql_file , result , row , " " , " Create_options " , 0 ) ;
print_value ( sql_file , result , row , " comment= " , " Comment " , 1 ) ;
fputs ( " */ " , sql_file ) ;
check_io ( sql_file ) ;
}
2000-10-29 13:49:42 +01:00
}
2006-05-25 10:00:28 +02:00
mysql_free_result ( result ) ; /* Is always safe to free */
2000-07-31 21:29:14 +02:00
}
2004-11-12 04:01:46 +01:00
continue_xml :
2003-10-30 11:58:30 +01:00
if ( ! opt_xml )
2006-05-25 10:00:28 +02:00
fputs ( " ; \n " , sql_file ) ;
2003-10-30 11:58:30 +01:00
else
2006-05-25 10:00:28 +02:00
fputs ( " \t </table_structure> \n " , sql_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( sql_file ) ;
2000-07-31 21:29:14 +02:00
}
}
2005-10-11 23:58:22 +02:00
if ( opt_complete_insert )
2000-07-31 21:29:14 +02:00
{
2005-05-08 21:02:46 +02:00
dynstr_append_mem ( & insert_pat , " ) VALUES " , 9 ) ;
2000-07-31 21:29:14 +02:00
if ( ! extended_insert )
2005-05-08 21:02:46 +02:00
dynstr_append_mem ( & insert_pat , " ( " , 1 ) ;
2000-07-31 21:29:14 +02:00
}
2002-01-02 20:29:41 +01:00
if ( sql_file ! = md_result_file )
2004-02-13 22:21:46 +01:00
{
fputs ( " \n " , sql_file ) ;
write_footer ( sql_file ) ;
2002-01-02 20:29:41 +01:00
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
2004-02-13 22:21:46 +01:00
}
2005-09-27 07:43:09 +02:00
DBUG_RETURN ( num_fields ) ;
2005-04-04 23:32:48 +02:00
} /* get_table_structure */
2000-07-31 21:29:14 +02:00
2005-09-09 00:03:07 +02:00
/*
dump_triggers_for_table
Dumps the triggers given a table / db name . This should be called after
the tables have been dumped in case a trigger depends on the existence
of a table
*/
static void dump_triggers_for_table ( char * table , char * db )
{
2006-05-25 10:00:28 +02:00
char * result_table ;
char name_buff [ NAME_LEN * 4 + 3 ] , table_buff [ NAME_LEN * 2 + 3 ] ;
2005-09-09 00:03:07 +02:00
char query_buff [ 512 ] ;
2005-10-13 22:42:56 +02:00
uint old_opt_compatible_mode = opt_compatible_mode ;
2006-08-02 03:18:47 +02:00
FILE * sql_file = md_result_file ;
2005-10-13 22:42:56 +02:00
MYSQL_RES * result ;
MYSQL_ROW row ;
2005-09-09 00:03:07 +02:00
DBUG_ENTER ( " dump_triggers_for_table " ) ;
DBUG_PRINT ( " enter " , ( " db: %s, table: %s " , db , table ) ) ;
2005-10-13 22:42:56 +02:00
/* Do not use ANSI_QUOTES on triggers in dump */
opt_compatible_mode & = ~ MASK_ANSI_QUOTES ;
2005-09-09 00:03:07 +02:00
result_table = quote_name ( table , table_buff , 1 ) ;
my_snprintf ( query_buff , sizeof ( query_buff ) ,
" SHOW TRIGGERS LIKE %s " ,
quote_for_like ( table , name_buff ) ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & result , query_buff ) )
2005-09-09 00:03:07 +02:00
{
if ( path )
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
safe_exit ( EX_MYSQLERR ) ;
DBUG_VOID_RETURN ;
}
if ( mysql_num_rows ( result ) )
fprintf ( sql_file , " \n /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; \n \
2005-10-06 16:54:43 +02:00
DELIMITER ; ; \ n " );
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( result ) ) )
2005-09-09 00:03:07 +02:00
{
2006-01-11 00:07:40 +01:00
fprintf ( sql_file ,
" /*!50003 SET SESSION SQL_MODE= \" %s \" */;; \n "
" /*!50003 CREATE */ " ,
row [ 6 ] /* sql_mode */ ) ;
if ( mysql_num_fields ( result ) > 7 )
{
/*
mysqldump can be run against the server , that does not support definer
in triggers ( there is no DEFINER column in SHOW TRIGGERS output ) . So ,
we should check if we have this column before accessing it .
*/
uint user_name_len ;
char user_name_str [ USERNAME_LENGTH + 1 ] ;
char quoted_user_name_str [ USERNAME_LENGTH * 2 + 3 ] ;
uint host_name_len ;
char host_name_str [ HOSTNAME_LENGTH + 1 ] ;
char quoted_host_name_str [ HOSTNAME_LENGTH * 2 + 3 ] ;
2006-05-25 10:00:28 +02:00
2006-01-11 00:07:40 +01:00
parse_user ( row [ 7 ] , strlen ( row [ 7 ] ) , user_name_str , & user_name_len ,
host_name_str , & host_name_len ) ;
fprintf ( sql_file ,
" /*!50017 DEFINER=%s@%s */ " ,
quote_name ( user_name_str , quoted_user_name_str , FALSE ) ,
quote_name ( host_name_str , quoted_host_name_str , FALSE ) ) ;
}
fprintf ( sql_file ,
" /*!50003 TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;; \n \n " ,
2005-09-09 00:03:07 +02:00
quote_name ( row [ 0 ] , name_buff , 0 ) , /* Trigger */
row [ 4 ] , /* Timing */
row [ 1 ] , /* Event */
result_table ,
2006-05-25 10:00:28 +02:00
( strchr ( " \t \n \r " , * ( row [ 3 ] ) ) ) ? " " : " " ,
2005-09-09 00:03:07 +02:00
row [ 3 ] /* Statement */ ) ;
}
if ( mysql_num_rows ( result ) )
fprintf ( sql_file ,
2005-10-06 16:54:43 +02:00
" DELIMITER ; \n "
" /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */; \n " ) ;
2005-09-09 00:03:07 +02:00
mysql_free_result ( result ) ;
2005-10-13 22:42:56 +02:00
/*
2006-05-25 10:00:28 +02:00
make sure to set back opt_compatible mode to
2005-10-13 22:42:56 +02:00
original value
*/
opt_compatible_mode = old_opt_compatible_mode ;
2005-09-09 00:03:07 +02:00
DBUG_VOID_RETURN ;
}
2000-07-31 21:29:14 +02:00
static char * add_load_option ( char * ptr , const char * object ,
2006-05-25 10:00:28 +02:00
const char * statement )
2000-07-31 21:29:14 +02:00
{
if ( object )
{
2001-01-02 13:29:47 +01:00
/* Don't escape hex constants */
if ( object [ 0 ] = = ' 0 ' & & ( object [ 1 ] = = ' x ' | | object [ 1 ] = = ' X ' ) )
ptr = strxmov ( ptr , " " , statement , " " , object , NullS ) ;
else
{
/* char constant; escape */
ptr = strxmov ( ptr , " " , statement , " ' " , NullS ) ;
ptr = field_escape ( ptr , object , ( uint ) strlen ( object ) ) ;
* ptr + + = ' \' ' ;
}
2000-07-31 21:29:14 +02:00
}
return ptr ;
} /* add_load_option */
/*
2005-10-06 16:54:43 +02:00
Allow the user to specify field terminator strings like :
" ' " , " \" , " \ \ " (escaped backslash), " \ t " (tab), " \ n " (newline)
This is done by doubling ' and add a end - \ if needed to avoid
syntax errors from the SQL parser .
2000-07-31 21:29:14 +02:00
*/
static char * field_escape ( char * to , const char * from , uint length )
{
const char * end ;
uint end_backslashes = 0 ;
for ( end = from + length ; from ! = end ; from + + )
{
* to + + = * from ;
if ( * from = = ' \\ ' )
end_backslashes ^ = 1 ; /* find odd number of backslashes */
else
{
if ( * from = = ' \' ' & & ! end_backslashes )
2006-05-25 10:00:28 +02:00
* to + + = * from ; /* We want a duplicate of "'" for MySQL */
2000-07-31 21:29:14 +02:00
end_backslashes = 0 ;
}
}
/* Add missing backslashes if user has specified odd number of backs.*/
if ( end_backslashes )
* to + + = ' \\ ' ;
return to ;
} /* field_escape */
2004-05-07 00:02:57 +02:00
static char * alloc_query_str ( ulong size )
{
char * query ;
if ( ! ( query = ( char * ) my_malloc ( size , MYF ( MY_WME ) ) ) )
{
2006-05-25 10:00:28 +02:00
ignore_errors = 0 ; /* Fatal error */
safe_exit ( EX_MYSQLERR ) ; /* Force exit */
2004-05-07 00:02:57 +02:00
}
return query ;
}
2005-04-04 23:32:48 +02:00
2000-07-31 21:29:14 +02:00
/*
2005-09-27 07:43:09 +02:00
SYNOPSIS
dump_table ( )
dump_table saves database contents as a series of INSERT statements .
ARGS
table - table name
db - db name
RETURNS
void
2000-07-31 21:29:14 +02:00
*/
2005-04-04 23:32:48 +02:00
2005-09-27 07:43:09 +02:00
static void dump_table ( char * table , char * db )
2000-07-31 21:29:14 +02:00
{
2005-09-27 07:43:09 +02:00
char ignore_flag ;
2004-05-07 00:02:57 +02:00
char query_buf [ QUERY_LENGTH ] , * end , buff [ 256 ] , table_buff [ NAME_LEN + 3 ] ;
2005-10-11 23:58:22 +02:00
char table_type [ NAME_LEN ] ;
2003-09-05 05:56:28 +02:00
char * result_table , table_buff2 [ NAME_LEN * 2 + 3 ] , * opt_quoted_table ;
2004-05-07 00:02:57 +02:00
char * query = query_buf ;
2005-09-27 07:43:09 +02:00
int error = 0 ;
2006-05-25 10:00:28 +02:00
ulong rownr , row_break , total_length , init_length ;
2005-09-27 07:43:09 +02:00
uint num_fields ;
2006-05-25 10:00:28 +02:00
MYSQL_RES * res ;
MYSQL_FIELD * field ;
MYSQL_ROW row ;
2005-09-27 07:43:09 +02:00
DBUG_ENTER ( " dump_table " ) ;
/*
Make sure you get the create table info before the following check for
- - no - data flag below . Otherwise , the create table info won ' t be printed .
*/
2005-10-11 23:58:22 +02:00
num_fields = get_table_structure ( table , db , table_type , & ignore_flag ) ;
2000-07-31 21:29:14 +02:00
2006-05-25 10:00:28 +02:00
/*
The " table " could be a view . If so , we don ' t do anything here .
*/
if ( strcmp ( table_type , " VIEW " ) = = 0 )
return ;
2005-06-22 15:43:49 +02:00
/* Check --no-data flag */
2006-07-24 11:56:01 +02:00
if ( opt_no_data )
2005-06-22 15:43:49 +02:00
{
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Skipping dump data for table '%s', --no-data was used \n " ,
table ) ;
2005-09-27 07:43:09 +02:00
DBUG_VOID_RETURN ;
2005-06-22 15:43:49 +02:00
}
2005-10-11 23:58:22 +02:00
DBUG_PRINT ( " info " ,
( " ignore_flag: %x num_fields: %d " , ( int ) ignore_flag ,
num_fields ) ) ;
2005-09-27 07:43:09 +02:00
/*
If the table type is a merge table or any type that has to be
_completely_ ignored and no data dumped
*/
if ( ignore_flag & IGNORE_DATA )
{
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Warning: Skipping data for table '%s' because " \
" it's of type %s \n " , table , table_type ) ;
2005-09-27 07:43:09 +02:00
DBUG_VOID_RETURN ;
}
2005-06-22 15:43:49 +02:00
/* Check that there are any fields in the table */
2005-09-27 07:43:09 +02:00
if ( num_fields = = 0 )
2005-06-22 15:43:49 +02:00
{
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Skipping dump data for table '%s', it has no fields \n " ,
table ) ;
2005-09-27 07:43:09 +02:00
DBUG_VOID_RETURN ;
2005-06-22 15:43:49 +02:00
}
2003-09-03 17:48:10 +02:00
result_table = quote_name ( table , table_buff , 1 ) ;
opt_quoted_table = quote_name ( table , table_buff2 , 0 ) ;
2003-12-14 05:39:52 +01:00
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Sending SELECT query... \n " ) ;
2000-07-31 21:29:14 +02:00
if ( path )
{
char filename [ FN_REFLEN ] , tmp_path [ FN_REFLEN ] ;
2001-10-08 03:58:07 +02:00
convert_dirname ( tmp_path , path , NullS ) ;
2000-07-31 21:29:14 +02:00
my_load_path ( tmp_path , tmp_path , NULL ) ;
fn_format ( filename , table , tmp_path , " .txt " , 4 ) ;
my_delete ( filename , MYF ( 0 ) ) ; /* 'INTO OUTFILE' doesn't work, if
2006-05-25 10:00:28 +02:00
filename wasn ' t deleted */
2000-07-31 21:29:14 +02:00
to_unix_path ( filename ) ;
2006-05-25 10:00:28 +02:00
my_snprintf ( query , QUERY_LENGTH ,
" SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s' " ,
filename ) ;
2000-07-31 21:29:14 +02:00
end = strend ( query ) ;
if ( fields_terminated | | enclosed | | opt_enclosed | | escaped )
end = strmov ( end , " FIELDS " ) ;
end = add_load_option ( end , fields_terminated , " TERMINATED BY " ) ;
end = add_load_option ( end , enclosed , " ENCLOSED BY " ) ;
end = add_load_option ( end , opt_enclosed , " OPTIONALLY ENCLOSED BY " ) ;
end = add_load_option ( end , escaped , " ESCAPED BY " ) ;
end = add_load_option ( end , lines_terminated , " LINES TERMINATED BY " ) ;
* end = ' \0 ' ;
2005-03-16 21:56:56 +01:00
my_snprintf ( buff , sizeof ( buff ) , " FROM %s " , result_table ) ;
2000-07-31 21:29:14 +02:00
end = strmov ( end , buff ) ;
2004-11-16 23:45:24 +01:00
if ( where | | order_by )
2004-05-07 00:02:57 +02:00
{
2006-08-02 03:18:47 +02:00
query = alloc_query_str ( ( ulong ) ( ( end - query ) + 1 +
2004-11-16 23:45:24 +01:00
( where ? strlen ( where ) + 7 : 0 ) +
( order_by ? strlen ( order_by ) + 10 : 0 ) ) ) ;
2006-08-02 03:18:47 +02:00
end = strmov ( query , query_buf ) ;
2004-11-16 23:45:24 +01:00
if ( where )
2006-08-02 03:18:47 +02:00
end = strxmov ( end , " WHERE " , where , NullS ) ;
2004-11-16 23:45:24 +01:00
if ( order_by )
2006-08-02 03:18:47 +02:00
end = strxmov ( end , " ORDER BY " , order_by , NullS ) ;
2004-05-07 00:02:57 +02:00
}
2006-07-24 12:00:44 +02:00
if ( mysql_real_query ( mysql , query , ( uint ) ( end - query ) ) )
2000-07-31 21:29:14 +02:00
{
2006-07-24 12:00:44 +02:00
DB_error ( mysql , " when executing 'SELECT INTO OUTFILE' " ) ;
2005-09-27 07:43:09 +02:00
DBUG_VOID_RETURN ;
2000-07-31 21:29:14 +02:00
}
}
else
{
2003-12-11 14:37:45 +01:00
if ( ! opt_xml & & opt_comments )
2004-06-24 22:14:12 +02:00
{
2003-09-03 17:48:10 +02:00
fprintf ( md_result_file , " \n -- \n -- Dumping data for table %s \n -- \n " ,
2006-05-25 10:00:28 +02:00
result_table ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2005-03-16 21:56:56 +01:00
my_snprintf ( query , QUERY_LENGTH ,
2006-05-25 10:00:28 +02:00
" SELECT /*!40001 SQL_NO_CACHE */ * FROM %s " ,
result_table ) ;
2004-11-16 23:45:24 +01:00
if ( where | | order_by )
2000-07-31 21:29:14 +02:00
{
2006-08-02 03:18:47 +02:00
query = alloc_query_str ( ( ulong ) ( strlen ( query ) + 1 +
2004-11-16 23:45:24 +01:00
( where ? strlen ( where ) + 7 : 0 ) +
( order_by ? strlen ( order_by ) + 10 : 0 ) ) ) ;
2006-08-02 03:18:47 +02:00
end = strmov ( query , query_buf ) ;
2004-11-16 23:45:24 +01:00
if ( where )
2004-06-24 22:14:12 +02:00
{
2004-11-16 23:45:24 +01:00
if ( ! opt_xml & & opt_comments )
{
fprintf ( md_result_file , " -- WHERE: %s \n " , where ) ;
check_io ( md_result_file ) ;
}
2006-08-02 03:18:47 +02:00
end = strxmov ( end , " WHERE " , where , NullS ) ;
2004-11-16 23:45:24 +01:00
}
if ( order_by )
{
if ( ! opt_xml & & opt_comments )
{
fprintf ( md_result_file , " -- ORDER BY: %s \n " , order_by ) ;
check_io ( md_result_file ) ;
}
2006-08-02 03:18:47 +02:00
end = strxmov ( end , " ORDER BY " , order_by , NullS ) ;
2004-06-24 22:14:12 +02:00
}
2000-07-31 21:29:14 +02:00
}
2004-02-09 12:31:03 +01:00
if ( ! opt_xml & & ! opt_compact )
2004-06-24 22:14:12 +02:00
{
2002-04-03 12:36:01 +02:00
fputs ( " \n " , md_result_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , 0 , query ) )
2006-08-17 23:09:24 +02:00
{
2006-07-24 12:00:44 +02:00
DB_error ( mysql , " when retrieving data from server " ) ;
2006-08-17 23:09:24 +02:00
goto err ;
}
2000-07-31 21:29:14 +02:00
if ( quick )
2006-07-24 12:00:44 +02:00
res = mysql_use_result ( mysql ) ;
2000-07-31 21:29:14 +02:00
else
2006-07-24 12:00:44 +02:00
res = mysql_store_result ( mysql ) ;
2000-07-31 21:29:14 +02:00
if ( ! res )
2006-01-03 17:54:54 +01:00
{
2006-07-24 12:00:44 +02:00
DB_error ( mysql , " when retrieving data from server " ) ;
2006-01-03 17:54:54 +01:00
goto err ;
}
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Retrieving rows... \n " ) ;
2005-09-27 07:43:09 +02:00
if ( mysql_num_fields ( res ) ! = num_fields )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
fprintf ( stderr , " %s: Error in field count for table: %s ! Aborting. \n " ,
2006-05-25 10:00:28 +02:00
my_progname , result_table ) ;
2004-05-07 00:02:57 +02:00
error = EX_CONSCHECK ;
goto err ;
2000-07-31 21:29:14 +02:00
}
2006-06-21 09:12:23 +02:00
if ( opt_lock )
2004-06-24 22:14:12 +02:00
{
2006-06-21 09:12:23 +02:00
fprintf ( md_result_file , " LOCK TABLES %s WRITE; \n " , opt_quoted_table ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2006-06-21 09:12:23 +02:00
/* Moved disable keys to after lock per bug 15977 */
if ( opt_disable_keys )
2004-06-24 22:14:12 +02:00
{
2006-06-21 09:12:23 +02:00
fprintf ( md_result_file , " /*!40000 ALTER TABLE %s DISABLE KEYS */; \n " ,
opt_quoted_table ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2000-07-31 21:29:14 +02:00
2006-05-25 10:00:28 +02:00
total_length = opt_net_buffer_length ; /* Force row break */
2000-07-31 21:29:14 +02:00
row_break = 0 ;
rownr = 0 ;
2005-05-08 21:02:46 +02:00
init_length = ( uint ) insert_pat . length + 4 ;
2001-11-05 22:48:03 +01:00
if ( opt_xml )
2006-10-19 00:43:51 +02:00
print_xml_tag ( md_result_file , " \t " , " \n " , " table_data " , " name= " , table ,
NullS ) ;
2001-10-04 19:43:06 +02:00
if ( opt_autocommit )
2004-06-24 22:14:12 +02:00
{
2001-10-04 19:43:06 +02:00
fprintf ( md_result_file , " set autocommit=0; \n " ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2001-10-04 19:43:06 +02:00
2005-10-25 19:04:31 +02:00
while ( ( row = mysql_fetch_row ( res ) ) )
2000-07-31 21:29:14 +02:00
{
uint i ;
2005-10-25 19:04:31 +02:00
ulong * lengths = mysql_fetch_lengths ( res ) ;
2000-07-31 21:29:14 +02:00
rownr + + ;
2001-11-05 22:48:03 +01:00
if ( ! extended_insert & & ! opt_xml )
2004-06-24 22:14:12 +02:00
{
2006-05-25 10:00:28 +02:00
fputs ( insert_pat . str , md_result_file ) ;
check_io ( md_result_file ) ;
2004-06-24 22:14:12 +02:00
}
2000-07-31 21:29:14 +02:00
mysql_field_seek ( res , 0 ) ;
2002-04-03 12:36:01 +02:00
if ( opt_xml )
2004-06-24 22:14:12 +02:00
{
2003-10-30 11:58:30 +01:00
fputs ( " \t <row> \n " , md_result_file ) ;
2006-05-25 10:00:28 +02:00
check_io ( md_result_file ) ;
2004-06-24 22:14:12 +02:00
}
2002-04-03 12:36:01 +02:00
2006-08-02 03:18:47 +02:00
for ( i = 0 ; i < mysql_num_fields ( res ) ; i + + )
2000-07-31 21:29:14 +02:00
{
2004-10-19 07:40:59 +02:00
int is_blob ;
2005-11-24 02:31:44 +01:00
ulong length = lengths [ i ] ;
2006-08-02 03:18:47 +02:00
if ( ! ( field = mysql_fetch_field ( res ) ) )
2006-05-25 10:00:28 +02:00
{
my_snprintf ( query , QUERY_LENGTH ,
" %s: Not enough fields from table %s! Aborting. \n " ,
my_progname , result_table ) ;
fputs ( query , stderr ) ;
error = EX_CONSCHECK ;
goto err ;
}
/*
63 is my_charset_bin . If charsetnr is not 63 ,
we have not a BLOB but a TEXT column .
we ' ll dump in hex only BLOB columns .
*/
2004-10-19 07:40:59 +02:00
is_blob = ( opt_hex_blob & & field - > charsetnr = = 63 & &
2005-09-14 15:46:31 +02:00
( field - > type = = MYSQL_TYPE_BIT | |
field - > type = = MYSQL_TYPE_STRING | |
2004-12-06 01:00:37 +01:00
field - > type = = MYSQL_TYPE_VAR_STRING | |
field - > type = = MYSQL_TYPE_VARCHAR | |
field - > type = = MYSQL_TYPE_BLOB | |
field - > type = = MYSQL_TYPE_LONG_BLOB | |
field - > type = = MYSQL_TYPE_MEDIUM_BLOB | |
field - > type = = MYSQL_TYPE_TINY_BLOB ) ) ? 1 : 0 ;
2006-10-19 00:43:51 +02:00
if ( extended_insert & & ! opt_xml )
2006-05-25 10:00:28 +02:00
{
if ( i = = 0 )
dynstr_set ( & extended_row , " ( " ) ;
else
dynstr_append ( & extended_row , " , " ) ;
if ( row [ i ] )
{
if ( length )
{
if ( ! IS_NUM_FIELD ( field ) )
{
/*
" length * 2 + 2 " is OK for both HEX and non - HEX modes :
- In HEX mode we need exactly 2 bytes per character
plus 2 bytes for ' 0 x ' prefix .
- In non - HEX mode we need up to 2 bytes per character ,
plus 2 bytes for leading and trailing ' \' ' characters .
*/
if ( dynstr_realloc ( & extended_row , length * 2 + 2 ) )
{
fputs ( " Aborting dump (out of memory) " , stderr ) ;
error = EX_EOM ;
goto err ;
}
2004-10-19 07:40:59 +02:00
if ( opt_hex_blob & & is_blob )
{
dynstr_append ( & extended_row , " 0x " ) ;
2006-05-25 10:00:28 +02:00
extended_row . length + = mysql_hex_string ( extended_row . str +
2004-11-05 05:54:52 +01:00
extended_row . length ,
row [ i ] , length ) ;
extended_row . str [ extended_row . length ] = ' \0 ' ;
2004-10-19 07:40:59 +02:00
}
else
{
dynstr_append ( & extended_row , " ' " ) ;
extended_row . length + =
mysql_real_escape_string ( & mysql_connection ,
& extended_row . str [ extended_row . length ] ,
row [ i ] , length ) ;
extended_row . str [ extended_row . length ] = ' \0 ' ;
dynstr_append ( & extended_row , " ' " ) ;
}
2006-05-25 10:00:28 +02:00
}
else
{
/* change any strings ("inf", "-inf", "nan") into NULL */
2006-08-02 03:18:47 +02:00
char * ptr = row [ i ] ;
2006-05-25 10:00:28 +02:00
if ( my_isalpha ( charset_info , * ptr ) | | ( * ptr = = ' - ' & &
my_isalpha ( charset_info , ptr [ 1 ] ) ) )
dynstr_append ( & extended_row , " NULL " ) ;
else
{
if ( field - > type = = FIELD_TYPE_DECIMAL )
{
/* add " signs around */
dynstr_append ( & extended_row , " ' " ) ;
dynstr_append ( & extended_row , ptr ) ;
dynstr_append ( & extended_row , " ' " ) ;
}
else
dynstr_append ( & extended_row , ptr ) ;
}
}
}
else
dynstr_append ( & extended_row , " '' " ) ;
}
else if ( dynstr_append ( & extended_row , " NULL " ) )
{
fputs ( " Aborting dump (out of memory) " , stderr ) ;
error = EX_EOM ;
goto err ;
}
}
else
{
if ( i & & ! opt_xml )
{
fputc ( ' , ' , md_result_file ) ;
check_io ( md_result_file ) ;
}
if ( row [ i ] )
{
if ( ! IS_NUM_FIELD ( field ) )
{
if ( opt_xml )
{
2006-10-19 00:43:51 +02:00
if ( opt_hex_blob & & is_blob & & length )
{
/* Define xsi:type="xs:hexBinary" for hex encoded data */
print_xml_tag ( md_result_file , " \t \t " , " " , " field " , " name= " ,
field - > name , " xsi:type= " , " xs:hexBinary " , NullS ) ;
print_blob_as_hex ( md_result_file , row [ i ] , length ) ;
}
else
{
print_xml_tag ( md_result_file , " \t \t " , " " , " field " , " name= " ,
field - > name , NullS ) ;
print_quoted_xml ( md_result_file , row [ i ] , length ) ;
}
2006-05-25 10:00:28 +02:00
fputs ( " </field> \n " , md_result_file ) ;
}
else if ( opt_hex_blob & & is_blob & & length )
2004-11-12 10:17:53 +01:00
{
2004-10-19 07:40:59 +02:00
fputs ( " 0x " , md_result_file ) ;
2006-10-19 00:43:51 +02:00
print_blob_as_hex ( md_result_file , row [ i ] , length ) ;
2004-10-19 07:40:59 +02:00
}
else
2005-11-24 02:31:44 +01:00
unescape ( md_result_file , row [ i ] , length ) ;
2006-05-25 10:00:28 +02:00
}
else
{
/* change any strings ("inf", "-inf", "nan") into NULL */
2006-08-02 03:18:47 +02:00
char * ptr = row [ i ] ;
2006-05-25 10:00:28 +02:00
if ( opt_xml )
{
2006-10-19 00:43:51 +02:00
print_xml_tag ( md_result_file , " \t \t " , " " , " field " , " name= " ,
field - > name , NullS ) ;
2006-05-25 10:00:28 +02:00
fputs ( ! my_isalpha ( charset_info , * ptr ) ? ptr : " NULL " ,
md_result_file ) ;
fputs ( " </field> \n " , md_result_file ) ;
}
else if ( my_isalpha ( charset_info , * ptr ) | |
( * ptr = = ' - ' & & my_isalpha ( charset_info , ptr [ 1 ] ) ) )
fputs ( " NULL " , md_result_file ) ;
else if ( field - > type = = FIELD_TYPE_DECIMAL )
{
/* add " signs around */
fputc ( ' \' ' , md_result_file ) ;
fputs ( ptr , md_result_file ) ;
fputc ( ' \' ' , md_result_file ) ;
}
else
fputs ( ptr , md_result_file ) ;
}
}
else
2005-06-22 20:22:54 +02:00
{
/* The field value is NULL */
if ( ! opt_xml )
fputs ( " NULL " , md_result_file ) ;
else
print_xml_null_tag ( md_result_file , " \t \t " , " field name= " ,
field - > name , " \n " ) ;
}
2004-06-24 23:29:27 +02:00
check_io ( md_result_file ) ;
2006-05-25 10:00:28 +02:00
}
2000-07-31 21:29:14 +02:00
}
2002-04-03 12:36:01 +02:00
if ( opt_xml )
2004-06-24 22:14:12 +02:00
{
2003-10-30 11:58:30 +01:00
fputs ( " \t </row> \n " , md_result_file ) ;
2006-05-25 10:00:28 +02:00
check_io ( md_result_file ) ;
2004-06-24 22:14:12 +02:00
}
2002-04-03 12:36:01 +02:00
2003-10-14 12:19:54 +02:00
if ( extended_insert )
2000-07-31 21:29:14 +02:00
{
2006-05-25 10:00:28 +02:00
ulong row_length ;
dynstr_append ( & extended_row , " ) " ) ;
2006-08-02 03:18:47 +02:00
row_length = 2 + extended_row . length ;
2004-05-27 01:47:04 +02:00
if ( total_length + row_length < opt_net_buffer_length )
2000-07-31 21:29:14 +02:00
{
2006-08-02 03:18:47 +02:00
total_length + = row_length ;
2006-05-25 10:00:28 +02:00
fputc ( ' , ' , md_result_file ) ; /* Always row break */
fputs ( extended_row . str , md_result_file ) ;
}
2000-07-31 21:29:14 +02:00
else
{
2006-05-25 10:00:28 +02:00
if ( row_break )
fputs ( " ; \n " , md_result_file ) ;
row_break = 1 ; /* This is first row */
2001-12-06 13:10:51 +01:00
2005-05-08 21:02:46 +02:00
fputs ( insert_pat . str , md_result_file ) ;
2003-10-14 12:19:54 +02:00
fputs ( extended_row . str , md_result_file ) ;
2006-08-02 03:18:47 +02:00
total_length = row_length + init_length ;
2000-07-31 21:29:14 +02:00
}
2006-05-25 10:00:28 +02:00
check_io ( md_result_file ) ;
2000-07-31 21:29:14 +02:00
}
2001-11-05 22:48:03 +01:00
else if ( ! opt_xml )
2004-06-24 22:14:12 +02:00
{
2006-05-25 10:00:28 +02:00
fputs ( " ); \n " , md_result_file ) ;
check_io ( md_result_file ) ;
2004-06-24 22:14:12 +02:00
}
2000-07-31 21:29:14 +02:00
}
2001-12-06 13:10:51 +01:00
2002-01-22 23:04:43 +01:00
/* XML - close table tag and supress regular output */
2001-11-05 22:48:03 +01:00
if ( opt_xml )
2006-05-25 10:00:28 +02:00
fputs ( " \t </table_data> \n " , md_result_file ) ;
2001-11-05 22:48:03 +01:00
else if ( extended_insert & & row_break )
2006-05-25 10:00:28 +02:00
fputs ( " ; \n " , md_result_file ) ; /* If not empty table */
2001-08-22 00:45:07 +02:00
fflush ( md_result_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_errno ( mysql ) )
2000-07-31 21:29:14 +02:00
{
2005-03-16 21:56:56 +01:00
my_snprintf ( query , QUERY_LENGTH ,
2006-05-25 10:00:28 +02:00
" %s: Error %d: %s when dumping table %s at row: %ld \n " ,
my_progname ,
2006-07-24 12:00:44 +02:00
mysql_errno ( mysql ) ,
mysql_error ( mysql ) ,
2006-05-25 10:00:28 +02:00
result_table ,
rownr ) ;
2000-07-31 21:29:14 +02:00
fputs ( query , stderr ) ;
2004-05-07 00:02:57 +02:00
error = EX_CONSCHECK ;
goto err ;
2000-07-31 21:29:14 +02:00
}
2006-06-21 09:12:23 +02:00
/* Moved enable keys to before unlock per bug 15977 */
2002-04-03 12:36:01 +02:00
if ( opt_disable_keys )
2004-06-24 22:14:12 +02:00
{
2002-04-03 12:36:01 +02:00
fprintf ( md_result_file , " /*!40000 ALTER TABLE %s ENABLE KEYS */; \n " ,
2006-05-25 10:00:28 +02:00
opt_quoted_table ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2006-06-21 09:12:23 +02:00
if ( opt_lock )
{
fputs ( " UNLOCK TABLES; \n " , md_result_file ) ;
check_io ( md_result_file ) ;
}
2001-10-04 19:43:06 +02:00
if ( opt_autocommit )
2004-06-24 22:14:12 +02:00
{
2001-10-04 19:43:06 +02:00
fprintf ( md_result_file , " commit; \n " ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2001-10-10 22:44:07 +02:00
mysql_free_result ( res ) ;
2004-05-07 00:02:57 +02:00
if ( query ! = query_buf )
my_free ( query , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
2005-09-27 07:43:09 +02:00
}
DBUG_VOID_RETURN ;
2004-05-07 00:02:57 +02:00
err :
if ( query ! = query_buf )
my_free ( query , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
safe_exit ( error ) ;
2005-09-27 07:43:09 +02:00
DBUG_VOID_RETURN ;
2005-04-04 23:32:48 +02:00
} /* dump_table */
2000-07-31 21:29:14 +02:00
static char * getTableName ( int reset )
{
2006-08-02 03:18:47 +02:00
static MYSQL_RES * res = NULL ;
2000-07-31 21:29:14 +02:00
MYSQL_ROW row ;
if ( ! res )
{
2006-09-15 01:26:28 +02:00
if ( ! ( res = mysql_list_tables ( mysql , NullS ) ) )
2000-07-31 21:29:14 +02:00
return ( NULL ) ;
}
2006-08-02 03:18:47 +02:00
if ( ( row = mysql_fetch_row ( res ) ) )
2000-07-31 21:29:14 +02:00
return ( ( char * ) row [ 0 ] ) ;
2000-09-07 03:55:17 +02:00
2000-07-31 21:29:14 +02:00
if ( reset )
mysql_data_seek ( res , 0 ) ; /* We want to read again */
else
{
mysql_free_result ( res ) ;
2006-08-02 03:18:47 +02:00
res = NULL ;
2000-07-31 21:29:14 +02:00
}
return ( NULL ) ;
} /* getTableName */
static int dump_all_databases ( )
{
MYSQL_ROW row ;
MYSQL_RES * tableres ;
int result = 0 ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & tableres , " SHOW DATABASES " ) )
2000-07-31 21:29:14 +02:00
return 1 ;
2006-08-02 03:18:47 +02:00
while ( ( row = mysql_fetch_row ( tableres ) ) )
2000-07-31 21:29:14 +02:00
{
if ( dump_all_tables_in_db ( row [ 0 ] ) )
result = 1 ;
}
2006-05-25 10:00:28 +02:00
if ( seen_views )
2004-11-12 04:01:46 +01:00
{
2006-07-24 12:00:44 +02:00
if ( mysql_query ( mysql , " SHOW DATABASES " ) | |
2006-09-15 01:26:28 +02:00
! ( tableres = mysql_store_result ( mysql ) ) )
2004-11-12 04:01:46 +01:00
{
my_printf_error ( 0 , " Error: Couldn't execute 'SHOW DATABASES': %s " ,
2006-07-24 12:00:44 +02:00
MYF ( 0 ) , mysql_error ( mysql ) ) ;
2004-11-12 04:01:46 +01:00
return 1 ;
}
2006-08-02 03:18:47 +02:00
while ( ( row = mysql_fetch_row ( tableres ) ) )
2004-11-12 04:01:46 +01:00
{
if ( dump_all_views_in_db ( row [ 0 ] ) )
result = 1 ;
}
}
2000-07-31 21:29:14 +02:00
return result ;
}
/* dump_all_databases */
static int dump_databases ( char * * db_names )
{
int result = 0 ;
2004-11-12 04:01:46 +01:00
char * * db ;
for ( db = db_names ; * db ; db + + )
2001-12-20 19:14:55 +01:00
{
2004-11-12 04:01:46 +01:00
if ( dump_all_tables_in_db ( * db ) )
2000-07-31 21:29:14 +02:00
result = 1 ;
}
2006-05-25 10:00:28 +02:00
if ( ! result & & seen_views )
2004-11-12 04:01:46 +01:00
{
for ( db = db_names ; * db ; db + + )
{
if ( dump_all_views_in_db ( * db ) )
result = 1 ;
}
}
2000-07-31 21:29:14 +02:00
return result ;
} /* dump_databases */
2006-08-28 23:48:06 +02:00
/*
View Specific database initalization .
SYNOPSIS
init_dumping_views
qdatabase quoted name of the database
RETURN VALUES
0 Success .
1 Failure .
*/
int init_dumping_views ( char * qdatabase )
{
return 0 ;
} /* init_dumping_views */
/*
Table Specific database initalization .
SYNOPSIS
init_dumping_tables
qdatabase quoted name of the database
RETURN VALUES
0 Success .
1 Failure .
*/
int init_dumping_tables ( char * qdatabase )
{
if ( ! opt_create_db )
{
char qbuf [ 256 ] ;
MYSQL_ROW row ;
MYSQL_RES * dbinfo ;
my_snprintf ( qbuf , sizeof ( qbuf ) ,
" SHOW CREATE DATABASE IF NOT EXISTS %s " ,
qdatabase ) ;
if ( mysql_query ( mysql , qbuf ) | | ! ( dbinfo = mysql_store_result ( mysql ) ) )
{
/* Old server version, dump generic CREATE DATABASE */
if ( opt_drop_database )
fprintf ( md_result_file ,
" \n /*!40000 DROP DATABASE IF EXISTS %s;*/ \n " ,
qdatabase ) ;
fprintf ( md_result_file ,
" \n CREATE DATABASE /*!32312 IF NOT EXISTS*/ %s; \n " ,
qdatabase ) ;
}
else
{
if ( opt_drop_database )
fprintf ( md_result_file ,
" \n /*!40000 DROP DATABASE IF EXISTS %s*/; \n " ,
qdatabase ) ;
row = mysql_fetch_row ( dbinfo ) ;
if ( row [ 1 ] )
{
fprintf ( md_result_file , " \n %s; \n " , row [ 1 ] ) ;
}
}
}
return 0 ;
} /* init_dumping_tables */
static int init_dumping ( char * database , int init_func ( char * ) )
2000-07-31 21:29:14 +02:00
{
2006-07-24 12:00:44 +02:00
if ( mysql_get_server_version ( mysql ) > = 50003 & &
2004-12-10 16:25:12 +01:00
! my_strcasecmp ( & my_charset_latin1 , database , " information_schema " ) )
2006-05-25 10:00:28 +02:00
return 1 ;
2004-12-10 10:07:11 +01:00
2006-07-24 12:00:44 +02:00
if ( mysql_select_db ( mysql , database ) )
2000-07-31 21:29:14 +02:00
{
2006-07-24 12:00:44 +02:00
DB_error ( mysql , " when selecting the database " ) ;
2006-05-25 10:00:28 +02:00
return 1 ; /* If --force */
2000-07-31 21:29:14 +02:00
}
2002-11-18 17:50:42 +01:00
if ( ! path & & ! opt_xml )
2000-07-31 21:29:14 +02:00
{
if ( opt_databases | | opt_alldbs )
{
2003-11-04 08:40:36 +01:00
/*
2006-05-25 10:00:28 +02:00
length of table name * 2 ( if name contains quotes ) , 2 quotes and 0
2003-11-04 08:40:36 +01:00
*/
2006-07-18 00:07:08 +02:00
char quoted_database_buf [ NAME_LEN * 2 + 3 ] ;
2003-10-24 23:26:26 +02:00
char * qdatabase = quote_name ( database , quoted_database_buf , opt_quoted ) ;
2003-12-11 14:37:45 +01:00
if ( opt_comments )
2004-06-24 22:14:12 +02:00
{
2006-05-25 10:00:28 +02:00
fprintf ( md_result_file , " \n -- \n -- Current Database: %s \n -- \n " , qdatabase ) ;
check_io ( md_result_file ) ;
2004-06-24 22:14:12 +02:00
}
2003-10-14 12:19:54 +02:00
2006-08-28 23:48:06 +02:00
/* Call the view or table specific function */
init_func ( qdatabase ) ;
2003-10-14 12:19:54 +02:00
2003-11-04 08:40:36 +01:00
fprintf ( md_result_file , " \n USE %s; \n " , qdatabase ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
2000-07-31 21:29:14 +02:00
}
}
2003-11-04 08:40:36 +01:00
if ( extended_insert & & init_dynamic_string ( & extended_row , " " , 1024 , 1024 ) )
exit ( EX_EOM ) ;
2000-07-31 21:29:14 +02:00
return 0 ;
} /* init_dumping */
2004-12-27 19:10:30 +01:00
my_bool include_table ( byte * hash_key , uint len )
{
2004-12-28 17:33:49 +01:00
if ( hash_search ( & ignore_table , ( byte * ) hash_key , len ) )
2004-12-27 19:10:30 +01:00
return FALSE ;
return TRUE ;
}
2003-11-04 08:40:36 +01:00
2000-07-31 21:29:14 +02:00
static int dump_all_tables_in_db ( char * database )
{
char * table ;
uint numrows ;
2003-09-03 17:48:10 +02:00
char table_buff [ NAME_LEN * 2 + 3 ] ;
2000-07-31 21:29:14 +02:00
2004-12-27 19:10:30 +01:00
char hash_key [ 2 * NAME_LEN + 2 ] ; /* "db.tablename" */
char * afterdot ;
2006-09-14 20:56:14 +02:00
int using_mysql_db = my_strcasecmp ( & my_charset_latin1 , database , " mysql " ) ;
2004-12-27 19:10:30 +01:00
afterdot = strmov ( hash_key , database ) ;
* afterdot + + = ' . ' ;
2006-08-28 23:48:06 +02:00
if ( init_dumping ( database , init_dumping_tables ) )
2000-07-31 21:29:14 +02:00
return 1 ;
2002-11-18 17:50:42 +01:00
if ( opt_xml )
2006-10-19 00:43:51 +02:00
print_xml_tag ( md_result_file , " " , " \n " , " database " , " name= " , database , NullS ) ;
2000-07-31 21:29:14 +02:00
if ( lock_tables )
{
DYNAMIC_STRING query ;
init_dynamic_string ( & query , " LOCK TABLES " , 256 , 1024 ) ;
2004-12-27 19:10:30 +01:00
for ( numrows = 0 ; ( table = getTableName ( 1 ) ) ; numrows + + )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
dynstr_append ( & query , quote_name ( table , table_buff , 1 ) ) ;
2000-07-31 21:29:14 +02:00
dynstr_append ( & query , " READ /*!32311 LOCAL */, " ) ;
}
2006-07-24 12:00:44 +02:00
if ( numrows & & mysql_real_query ( mysql , query . str , query . length - 1 ) )
DB_error ( mysql , " when using LOCK TABLES " ) ;
2000-07-31 21:29:14 +02:00
/* We shall continue here, if --force was given */
dynstr_free ( & query ) ;
}
if ( flush_logs )
{
2006-07-24 12:00:44 +02:00
if ( mysql_refresh ( mysql , REFRESH_LOG ) )
DB_error ( mysql , " when doing refresh " ) ;
2000-07-31 21:29:14 +02:00
/* We shall continue here, if --force was given */
}
2004-12-27 19:10:30 +01:00
while ( ( table = getTableName ( 0 ) ) )
2000-07-31 21:29:14 +02:00
{
2004-12-27 19:10:30 +01:00
char * end = strmov ( afterdot , table ) ;
if ( include_table ( hash_key , end - hash_key ) )
{
2005-09-27 07:43:09 +02:00
dump_table ( table , database ) ;
2004-12-27 19:10:30 +01:00
my_free ( order_by , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
order_by = 0 ;
2005-09-09 00:03:07 +02:00
if ( opt_dump_triggers & & ! opt_xml & &
2006-07-24 12:00:44 +02:00
mysql_get_server_version ( mysql ) > = 50009 )
2005-09-09 00:03:07 +02:00
dump_triggers_for_table ( table , database ) ;
2004-12-27 19:10:30 +01:00
}
2000-07-31 21:29:14 +02:00
}
2005-09-04 01:34:58 +02:00
if ( opt_routines & & ! opt_xml & &
2006-07-24 12:00:44 +02:00
mysql_get_server_version ( mysql ) > = 50009 )
2005-09-04 01:34:58 +02:00
{
DBUG_PRINT ( " info " , ( " Dumping routines for database %s " , database ) ) ;
dump_routines_for_db ( database ) ;
}
2002-11-18 17:50:42 +01:00
if ( opt_xml )
2004-06-24 22:14:12 +02:00
{
2003-10-30 11:58:30 +01:00
fputs ( " </database> \n " , md_result_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2000-07-31 21:29:14 +02:00
if ( lock_tables )
2006-07-24 12:00:44 +02:00
VOID ( mysql_query_with_error_report ( mysql , 0 , " UNLOCK TABLES " ) ) ;
2006-09-14 20:56:14 +02:00
if ( flush_privileges & & using_mysql_db = = 0 )
{
fprintf ( md_result_file , " \n -- \n -- Flush Grant Tables \n -- \n " ) ;
fprintf ( md_result_file , " \n /*! FLUSH PRIVILEGES */; \n " ) ;
}
2000-07-31 21:29:14 +02:00
return 0 ;
} /* dump_all_tables_in_db */
2004-11-12 04:01:46 +01:00
/*
dump structure of views of database
SYNOPSIS
dump_all_views_in_db ( )
database database name
2000-07-31 21:29:14 +02:00
2004-11-12 04:01:46 +01:00
RETURN
0 OK
1 ERROR
*/
static my_bool dump_all_views_in_db ( char * database )
{
char * table ;
uint numrows ;
char table_buff [ NAME_LEN * 2 + 3 ] ;
2006-08-28 23:48:06 +02:00
if ( init_dumping ( database , init_dumping_views ) )
2006-07-14 01:25:13 +02:00
return 1 ;
2004-11-12 04:01:46 +01:00
if ( opt_xml )
2006-10-19 00:43:51 +02:00
print_xml_tag ( md_result_file , " " , " \n " , " database " , " name= " , database , NullS ) ;
2004-11-12 04:01:46 +01:00
if ( lock_tables )
{
DYNAMIC_STRING query ;
init_dynamic_string ( & query , " LOCK TABLES " , 256 , 1024 ) ;
for ( numrows = 0 ; ( table = getTableName ( 1 ) ) ; numrows + + )
{
dynstr_append ( & query , quote_name ( table , table_buff , 1 ) ) ;
dynstr_append ( & query , " READ /*!32311 LOCAL */, " ) ;
}
2006-07-24 12:00:44 +02:00
if ( numrows & & mysql_real_query ( mysql , query . str , query . length - 1 ) )
DB_error ( mysql , " when using LOCK TABLES " ) ;
2004-11-12 04:01:46 +01:00
/* We shall continue here, if --force was given */
dynstr_free ( & query ) ;
}
if ( flush_logs )
{
2006-07-24 12:00:44 +02:00
if ( mysql_refresh ( mysql , REFRESH_LOG ) )
DB_error ( mysql , " when doing refresh " ) ;
2004-11-12 04:01:46 +01:00
/* We shall continue here, if --force was given */
}
while ( ( table = getTableName ( 0 ) ) )
2005-04-04 23:32:48 +02:00
get_view_structure ( table , database ) ;
2004-11-12 04:01:46 +01:00
if ( opt_xml )
{
fputs ( " </database> \n " , md_result_file ) ;
check_io ( md_result_file ) ;
}
if ( lock_tables )
2006-07-24 12:00:44 +02:00
VOID ( mysql_query_with_error_report ( mysql , 0 , " UNLOCK TABLES " ) ) ;
2004-11-12 04:01:46 +01:00
return 0 ;
} /* dump_all_tables_in_db */
2000-07-31 21:29:14 +02:00
2005-03-17 14:51:07 +01:00
2005-01-27 21:48:26 +01:00
/*
2006-01-03 17:54:54 +01:00
get_actual_table_name - - executes a SHOW TABLES LIKE ' % s ' to get the actual
table name from the server for the table name given on the command line .
we do this because the table name given on the command line may be a
2005-01-29 16:25:56 +01:00
different case ( e . g . T1 vs t1 )
2006-01-03 17:54:54 +01:00
2005-01-27 21:48:26 +01:00
RETURN
2006-05-29 08:17:38 +02:00
pointer to the table name
0 if error
2005-01-27 21:48:26 +01:00
*/
2006-05-29 08:17:38 +02:00
static char * get_actual_table_name ( const char * old_table_name , MEM_ROOT * root )
2005-02-01 15:27:08 +01:00
{
2006-05-29 08:17:38 +02:00
char * name = 0 ;
2005-04-04 23:32:48 +02:00
MYSQL_RES * table_res ;
2005-02-01 15:27:08 +01:00
MYSQL_ROW row ;
2005-03-16 21:56:56 +01:00
char query [ 50 + 2 * NAME_LEN ] ;
2005-03-16 13:57:59 +01:00
char show_name_buff [ FN_REFLEN ] ;
2005-02-01 15:27:08 +01:00
DBUG_ENTER ( " get_actual_table_name " ) ;
2005-01-27 21:48:26 +01:00
2005-03-16 21:56:56 +01:00
/* Check memory for quote_for_like() */
DBUG_ASSERT ( 2 * sizeof ( old_table_name ) < sizeof ( show_name_buff ) ) ;
2006-01-03 17:54:54 +01:00
my_snprintf ( query , sizeof ( query ) , " SHOW TABLES LIKE %s " ,
2006-05-25 10:00:28 +02:00
quote_for_like ( old_table_name , show_name_buff ) ) ;
2005-03-16 21:56:56 +01:00
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , 0 , query ) )
2005-02-01 15:27:08 +01:00
{
safe_exit ( EX_MYSQLERR ) ;
}
2005-01-27 21:48:26 +01:00
2006-07-24 12:00:44 +02:00
if ( ( table_res = mysql_store_result ( mysql ) ) )
2005-03-28 21:06:43 +02:00
{
2005-04-04 23:32:48 +02:00
my_ulonglong num_rows = mysql_num_rows ( table_res ) ;
if ( num_rows > 0 )
{
2006-05-29 09:32:08 +02:00
ulong * lengths ;
2005-04-04 23:32:48 +02:00
/*
Return first row
TODO : Return all matching rows
*/
row = mysql_fetch_row ( table_res ) ;
2006-05-29 09:32:08 +02:00
lengths = mysql_fetch_lengths ( table_res ) ;
2006-05-29 08:17:38 +02:00
name = strmake_root ( root , row [ 0 ] , lengths [ 0 ] ) ;
2005-04-04 23:32:48 +02:00
}
mysql_free_result ( table_res ) ;
2005-03-28 21:06:43 +02:00
}
2006-05-29 08:17:38 +02:00
DBUG_PRINT ( " exit " , ( " new_table_name: %s " , name ) ) ;
DBUG_RETURN ( name ) ;
2005-02-01 15:27:08 +01:00
}
2005-01-27 21:48:26 +01:00
2000-07-31 21:29:14 +02:00
static int dump_selected_tables ( char * db , char * * table_names , int tables )
{
2003-09-03 17:48:10 +02:00
char table_buff [ NAME_LEN * + 3 ] ;
2005-06-21 14:19:56 +02:00
DYNAMIC_STRING lock_tables_query ;
2006-05-29 08:17:38 +02:00
MEM_ROOT root ;
char * * dump_tables , * * pos , * * end ;
2005-06-21 14:19:56 +02:00
DBUG_ENTER ( " dump_selected_tables " ) ;
2000-07-31 21:29:14 +02:00
2006-08-28 23:48:06 +02:00
if ( init_dumping ( db , init_dumping_tables ) )
2000-07-31 21:29:14 +02:00
return 1 ;
2005-06-21 14:19:56 +02:00
2006-05-29 08:17:38 +02:00
init_alloc_root ( & root , 8192 , 0 ) ;
if ( ! ( dump_tables = pos = ( char * * ) alloc_root ( & root , tables * sizeof ( char * ) ) ) )
exit ( EX_EOM ) ;
2005-06-21 14:19:56 +02:00
init_dynamic_string ( & lock_tables_query , " LOCK TABLES " , 256 , 1024 ) ;
for ( ; tables > 0 ; tables - - , table_names + + )
2000-07-31 21:29:14 +02:00
{
2005-06-21 14:19:56 +02:00
/* the table name passed on commandline may be wrong case */
2006-05-29 08:17:38 +02:00
if ( ( * pos = get_actual_table_name ( * table_names , & root ) ) )
2000-07-31 21:29:14 +02:00
{
2005-06-21 14:19:56 +02:00
/* Add found table name to lock_tables_query */
if ( lock_tables )
{
2006-05-29 08:17:38 +02:00
dynstr_append ( & lock_tables_query , quote_name ( * pos , table_buff , 1 ) ) ;
2005-06-21 14:19:56 +02:00
dynstr_append ( & lock_tables_query , " READ /*!32311 LOCAL */, " ) ;
}
2006-05-29 08:17:38 +02:00
pos + + ;
2000-07-31 21:29:14 +02:00
}
2005-06-21 14:19:56 +02:00
else
2000-07-31 21:29:14 +02:00
{
2005-06-21 14:19:56 +02:00
my_printf_error ( 0 , " Couldn't find table: \" %s \" \n " , MYF ( 0 ) ,
* table_names ) ;
safe_exit ( EX_ILLEGAL_TABLE ) ;
/* We shall countinue here, if --force was given */
2000-07-31 21:29:14 +02:00
}
2005-06-21 14:19:56 +02:00
}
2006-05-29 08:17:38 +02:00
end = pos ;
2005-06-21 14:19:56 +02:00
if ( lock_tables )
{
2006-07-24 12:00:44 +02:00
if ( mysql_real_query ( mysql , lock_tables_query . str ,
2005-06-21 14:19:56 +02:00
lock_tables_query . length - 1 ) )
2006-07-24 12:00:44 +02:00
DB_error ( mysql , " when doing LOCK TABLES " ) ;
2000-07-31 21:29:14 +02:00
/* We shall countinue here, if --force was given */
}
2005-06-21 14:19:56 +02:00
dynstr_free ( & lock_tables_query ) ;
2000-07-31 21:29:14 +02:00
if ( flush_logs )
{
2006-07-24 12:00:44 +02:00
if ( mysql_refresh ( mysql , REFRESH_LOG ) )
DB_error ( mysql , " when doing refresh " ) ;
2000-07-31 21:29:14 +02:00
/* We shall countinue here, if --force was given */
}
2002-11-18 17:50:42 +01:00
if ( opt_xml )
2006-10-19 00:43:51 +02:00
print_xml_tag ( md_result_file , " " , " \n " , " database " , " name= " , db , NullS ) ;
2005-06-22 15:43:49 +02:00
2005-06-21 14:19:56 +02:00
/* Dump each selected table */
2006-05-29 08:17:38 +02:00
for ( pos = dump_tables ; pos < end ; pos + + )
2000-07-31 21:29:14 +02:00
{
2006-05-29 08:17:38 +02:00
DBUG_PRINT ( " info " , ( " Dumping table %s " , * pos ) ) ;
dump_table ( * pos , db ) ;
2005-09-09 00:03:07 +02:00
if ( opt_dump_triggers & &
2006-07-24 12:00:44 +02:00
mysql_get_server_version ( mysql ) > = 50009 )
2006-05-29 08:17:38 +02:00
dump_triggers_for_table ( * pos , db ) ;
2004-11-12 04:01:46 +01:00
}
2005-06-22 15:43:49 +02:00
/* Dump each selected view */
2006-05-25 10:00:28 +02:00
if ( seen_views )
2004-11-12 04:01:46 +01:00
{
2006-05-29 08:17:38 +02:00
for ( pos = dump_tables ; pos < end ; pos + + )
get_view_structure ( * pos , db ) ;
2000-07-31 21:29:14 +02:00
}
2005-09-04 01:34:58 +02:00
/* obtain dump of routines (procs/functions) */
if ( opt_routines & & ! opt_xml & &
2006-07-24 12:00:44 +02:00
mysql_get_server_version ( mysql ) > = 50009 )
2005-09-04 01:34:58 +02:00
{
DBUG_PRINT ( " info " , ( " Dumping routines for database %s " , db ) ) ;
dump_routines_for_db ( db ) ;
}
2006-05-29 08:17:38 +02:00
free_root ( & root , MYF ( 0 ) ) ;
2005-06-21 14:19:56 +02:00
my_free ( order_by , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
order_by = 0 ;
2002-11-18 17:50:42 +01:00
if ( opt_xml )
2004-06-24 22:14:12 +02:00
{
2003-10-30 11:58:30 +01:00
fputs ( " </database> \n " , md_result_file ) ;
2004-06-24 22:14:12 +02:00
check_io ( md_result_file ) ;
}
2000-07-31 21:29:14 +02:00
if ( lock_tables )
2006-07-24 12:00:44 +02:00
VOID ( mysql_query_with_error_report ( mysql , 0 , " UNLOCK TABLES " ) ) ;
2005-06-21 14:19:56 +02:00
DBUG_RETURN ( 0 ) ;
2000-07-31 21:29:14 +02:00
} /* dump_selected_tables */
2004-11-10 17:56:45 +01:00
static int do_show_master_status ( MYSQL * mysql_con )
{
MYSQL_ROW row ;
MYSQL_RES * master ;
const char * comment_prefix =
( opt_master_data = = MYSQL_OPT_MASTER_DATA_COMMENTED_SQL ) ? " -- " : " " ;
if ( mysql_query_with_error_report ( mysql_con , & master , " SHOW MASTER STATUS " ) )
{
return 1 ;
}
else
{
2006-08-02 03:18:47 +02:00
row = mysql_fetch_row ( master ) ;
2004-11-10 17:56:45 +01:00
if ( row & & row [ 0 ] & & row [ 1 ] )
{
2005-07-01 12:01:00 +02:00
/* SHOW MASTER STATUS reports file and position */
2004-11-10 17:56:45 +01:00
if ( opt_comments )
fprintf ( md_result_file ,
" \n -- \n -- Position to start replication or point-in-time "
" recovery from \n -- \n \n " ) ;
fprintf ( md_result_file ,
" %sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s; \n " ,
2006-05-25 10:00:28 +02:00
comment_prefix , row [ 0 ] , row [ 1 ] ) ;
2004-11-10 17:56:45 +01:00
check_io ( md_result_file ) ;
}
2005-07-01 12:01:00 +02:00
else if ( ! ignore_errors )
{
/* SHOW MASTER STATUS reports nothing and --force is not enabled */
2006-05-25 10:00:28 +02:00
my_printf_error ( 0 , " Error: Binlogging on server not active " ,
MYF ( 0 ) ) ;
2005-07-01 12:01:00 +02:00
mysql_free_result ( master ) ;
return 1 ;
}
2004-11-10 17:56:45 +01:00
mysql_free_result ( master ) ;
}
return 0 ;
}
static int do_flush_tables_read_lock ( MYSQL * mysql_con )
{
2004-11-14 17:45:37 +01:00
/*
We do first a FLUSH TABLES . If a long update is running , the FLUSH TABLES
will wait but will not stall the whole mysqld , and when the long update is
done the FLUSH TABLES WITH READ LOCK will start and succeed quickly . So ,
FLUSH TABLES is to lower the probability of a stage where both mysqldump
and most client connections are stalled . Of course , if a second long
update starts between the two FLUSHes , we have that bad stall .
*/
2006-05-25 10:00:28 +02:00
return
2004-11-14 17:45:37 +01:00
( mysql_query_with_error_report ( mysql_con , 0 , " FLUSH TABLES " ) | |
mysql_query_with_error_report ( mysql_con , 0 ,
" FLUSH TABLES WITH READ LOCK " ) ) ;
2004-11-10 17:56:45 +01:00
}
static int do_unlock_tables ( MYSQL * mysql_con )
{
return mysql_query_with_error_report ( mysql_con , 0 , " UNLOCK TABLES " ) ;
}
static int do_reset_master ( MYSQL * mysql_con )
{
return mysql_query_with_error_report ( mysql_con , 0 , " RESET MASTER " ) ;
}
2006-10-03 17:26:50 +02:00
static int start_transaction ( MYSQL * mysql_con )
2004-11-10 17:56:45 +01:00
{
/*
We use BEGIN for old servers . - - single - transaction - - master - data will fail
on old servers , but that ' s ok as it was already silently broken ( it didn ' t
do a consistent read , so better tell people frankly , with the error ) .
2005-01-13 00:44:13 +01:00
We want the first consistent read to be used for all tables to dump so we
need the REPEATABLE READ level ( not anything lower , for example READ
COMMITTED would give one new consistent read per dumped table ) .
2004-11-10 17:56:45 +01:00
*/
return ( mysql_query_with_error_report ( mysql_con , 0 ,
2005-01-13 00:44:13 +01:00
" SET SESSION TRANSACTION ISOLATION "
" LEVEL REPEATABLE READ " ) | |
mysql_query_with_error_report ( mysql_con , 0 ,
2004-11-10 17:56:45 +01:00
" START TRANSACTION "
2006-10-03 17:26:50 +02:00
" /*!40100 WITH CONSISTENT SNAPSHOT */ " ) ) ;
2004-11-10 17:56:45 +01:00
}
2003-01-16 04:35:59 +01:00
static ulong find_set ( TYPELIB * lib , const char * x , uint length ,
2006-05-25 10:00:28 +02:00
char * * err_pos , uint * err_len )
2003-01-16 04:35:59 +01:00
{
const char * end = x + length ;
ulong found = 0 ;
uint find ;
char buff [ 255 ] ;
2003-03-06 13:51:37 +01:00
* err_pos = 0 ; /* No error yet */
2003-03-16 08:20:45 +01:00
while ( end > x & & my_isspace ( charset_info , end [ - 1 ] ) )
2003-01-16 04:35:59 +01:00
end - - ;
* err_len = 0 ;
if ( x ! = end )
{
const char * start = x ;
for ( ; ; )
{
const char * pos = start ;
uint var_len ;
for ( ; pos ! = end & & * pos ! = ' , ' ; pos + + ) ;
var_len = ( uint ) ( pos - start ) ;
strmake ( buff , start , min ( sizeof ( buff ) , var_len ) ) ;
find = find_type ( buff , lib , var_len ) ;
if ( ! find )
{
* err_pos = ( char * ) start ;
* err_len = var_len ;
}
else
found | = ( ( longlong ) 1 < < ( find - 1 ) ) ;
if ( pos = = end )
break ;
start = pos + 1 ;
}
}
return found ;
}
2000-07-31 21:29:14 +02:00
/* Print a value with a prefix on file */
static void print_value ( FILE * file , MYSQL_RES * result , MYSQL_ROW row ,
2006-05-25 10:00:28 +02:00
const char * prefix , const char * name ,
int string_value )
2000-07-31 21:29:14 +02:00
{
2006-05-25 10:00:28 +02:00
MYSQL_FIELD * field ;
2000-07-31 21:29:14 +02:00
mysql_field_seek ( result , 0 ) ;
2006-08-02 03:18:47 +02:00
for ( ; ( field = mysql_fetch_field ( result ) ) ; row + + )
2000-07-31 21:29:14 +02:00
{
if ( ! strcmp ( field - > name , name ) )
{
if ( row [ 0 ] & & row [ 0 ] [ 0 ] & & strcmp ( row [ 0 ] , " 0 " ) ) /* Skip default */
{
2006-05-25 10:00:28 +02:00
fputc ( ' ' , file ) ;
fputs ( prefix , file ) ;
if ( string_value )
unescape ( file , row [ 0 ] , ( uint ) strlen ( row [ 0 ] ) ) ;
else
fputs ( row [ 0 ] , file ) ;
check_io ( file ) ;
return ;
2000-07-31 21:29:14 +02:00
}
}
}
2006-05-25 10:00:28 +02:00
return ; /* This shouldn't happen */
2000-07-31 21:29:14 +02:00
} /* print_value */
2003-12-14 05:39:52 +01:00
/*
SYNOPSIS
2005-09-27 07:43:09 +02:00
Check if we the table is one of the table types that should be ignored :
MRG_ISAM , MRG_MYISAM , if opt_delayed , if that table supports delayed inserts .
If the table should be altogether ignored , it returns a TRUE , FALSE if it
2006-05-25 10:00:28 +02:00
should not be ignored . If the user has selected to use INSERT DELAYED , it
sets the value of the bool pointer supports_delayed_inserts to 0 if not
2005-09-27 07:43:09 +02:00
supported , 1 if it is supported .
ARGS
2003-12-14 05:39:52 +01:00
check_if_ignore_table ( )
2006-05-25 10:00:28 +02:00
table_name Table name to check
2005-09-27 07:43:09 +02:00
table_type Type of table
2003-12-14 05:39:52 +01:00
GLOBAL VARIABLES
2006-07-24 12:00:44 +02:00
mysql MySQL connection
2006-05-25 10:00:28 +02:00
verbose Write warning messages
2003-12-14 05:39:52 +01:00
RETURN
2005-09-27 07:43:09 +02:00
char ( bit value ) See IGNORE_ values at top
2003-12-14 05:39:52 +01:00
*/
2005-09-27 07:43:09 +02:00
char check_if_ignore_table ( const char * table_name , char * table_type )
2003-12-14 05:39:52 +01:00
{
2005-09-27 18:40:51 +02:00
char result = IGNORE_NONE ;
2003-12-14 05:39:52 +01:00
char buff [ FN_REFLEN + 80 ] , show_name_buff [ FN_REFLEN ] ;
MYSQL_RES * res ;
MYSQL_ROW row ;
2005-09-27 07:43:09 +02:00
DBUG_ENTER ( " check_if_ignore_table " ) ;
2003-12-14 05:39:52 +01:00
2005-03-16 21:56:56 +01:00
/* Check memory for quote_for_like() */
DBUG_ASSERT ( 2 * sizeof ( table_name ) < sizeof ( show_name_buff ) ) ;
my_snprintf ( buff , sizeof ( buff ) , " show table status like %s " ,
2006-05-25 10:00:28 +02:00
quote_for_like ( table_name , show_name_buff ) ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & res , buff ) )
2003-12-14 05:39:52 +01:00
{
2006-07-24 12:00:44 +02:00
if ( mysql_errno ( mysql ) ! = ER_PARSE_ERROR )
2006-05-25 10:00:28 +02:00
{ /* If old MySQL version */
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Warning: Couldn't get status information for " \
2006-07-24 12:00:44 +02:00
" table %s (%s) \n " , table_name , mysql_error ( mysql ) ) ;
2005-09-27 18:40:51 +02:00
DBUG_RETURN ( result ) ; /* assume table is ok */
2003-12-14 05:39:52 +01:00
}
}
2004-11-10 17:56:45 +01:00
if ( ! ( row = mysql_fetch_row ( res ) ) )
2003-12-14 05:39:52 +01:00
{
fprintf ( stderr ,
2006-05-25 10:00:28 +02:00
" Error: Couldn't read status information for table %s (%s) \n " ,
2006-07-24 12:00:44 +02:00
table_name , mysql_error ( mysql ) ) ;
2005-01-24 15:48:25 +01:00
mysql_free_result ( res ) ;
2005-09-27 18:40:51 +02:00
DBUG_RETURN ( result ) ; /* assume table is ok */
2003-12-14 05:39:52 +01:00
}
2004-11-12 04:01:46 +01:00
if ( ! ( row [ 1 ] ) )
2005-10-11 23:58:22 +02:00
strmake ( table_type , " VIEW " , NAME_LEN - 1 ) ;
2004-11-12 04:01:46 +01:00
else
{
2005-09-27 07:43:09 +02:00
/*
If the table type matches any of these , we do support delayed inserts .
Note : we do not want to skip dumping this table if if is not one of
these types , but we do want to use delayed inserts in the dump if
the table type is _NOT_ one of these types
*/
2005-09-27 18:40:51 +02:00
strmake ( table_type , row [ 1 ] , NAME_LEN - 1 ) ;
2005-09-27 07:43:09 +02:00
if ( opt_delayed )
{
if ( strcmp ( table_type , " MyISAM " ) & &
strcmp ( table_type , " ISAM " ) & &
strcmp ( table_type , " ARCHIVE " ) & &
strcmp ( table_type , " HEAP " ) & &
strcmp ( table_type , " MEMORY " ) )
result = IGNORE_INSERT_DELAYED ;
}
/*
If these two types , we do want to skip dumping the table
*/
2006-07-24 11:56:01 +02:00
if ( ! opt_no_data & &
2005-09-27 07:43:09 +02:00
( ! strcmp ( table_type , " MRG_MyISAM " ) | | ! strcmp ( table_type , " MRG_ISAM " ) ) )
result = IGNORE_DATA ;
2004-11-12 04:01:46 +01:00
}
2005-01-24 15:48:25 +01:00
mysql_free_result ( res ) ;
2005-09-27 07:43:09 +02:00
DBUG_RETURN ( result ) ;
2003-12-14 05:39:52 +01:00
}
2006-07-24 12:00:44 +02:00
2004-11-16 23:45:24 +01:00
/*
Get string of comma - separated primary key field names
SYNOPSIS
char * primary_key_fields ( const char * table_name )
RETURNS pointer to allocated buffer ( must be freed by caller )
table_name quoted table name
DESCRIPTION
Use SHOW KEYS FROM table_name , allocate a buffer to hold the
field names , and then build that string and return the pointer
to that buffer .
Returns NULL if there is no PRIMARY or UNIQUE key on the table ,
or if there is some failure . It is better to continue to dump
the table unsorted , rather than exit without dumping the data .
*/
2005-07-18 14:33:18 +02:00
2004-11-16 23:45:24 +01:00
static char * primary_key_fields ( const char * table_name )
{
2006-08-02 03:18:47 +02:00
MYSQL_RES * res = NULL ;
2004-11-16 23:45:24 +01:00
MYSQL_ROW row ;
/* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */
2006-07-18 00:07:08 +02:00
char show_keys_buff [ 15 + NAME_LEN * 2 + 3 ] ;
2006-08-02 03:18:47 +02:00
uint result_length = 0 ;
char * result = 0 ;
2006-08-02 03:56:08 +02:00
char buff [ NAME_LEN * 2 + 3 ] ;
char * quoted_field ;
2004-11-16 23:45:24 +01:00
2006-05-25 10:00:28 +02:00
my_snprintf ( show_keys_buff , sizeof ( show_keys_buff ) ,
" SHOW KEYS FROM %s " , table_name ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query ( mysql , show_keys_buff ) | |
2006-09-15 01:26:28 +02:00
! ( res = mysql_store_result ( mysql ) ) )
2004-11-16 23:45:24 +01:00
{
fprintf ( stderr , " Warning: Couldn't read keys from table %s; "
" records are NOT sorted (%s) \n " ,
2006-07-24 12:00:44 +02:00
table_name , mysql_error ( mysql ) ) ;
2004-11-16 23:45:24 +01:00
/* Don't exit, because it's better to print out unsorted records */
goto cleanup ;
}
2004-11-30 02:26:24 +01:00
/*
* Figure out the length of the ORDER BY clause result .
* Note that SHOW KEYS is ordered : a PRIMARY key is always the first
* row , and UNIQUE keys come before others . So we only need to check
* the first key , not all keys .
*/
2006-08-02 03:18:47 +02:00
if ( ( row = mysql_fetch_row ( res ) ) & & atoi ( row [ 1 ] ) = = 0 )
2004-11-16 23:45:24 +01:00
{
2004-11-30 02:26:24 +01:00
/* Key is unique */
do
2006-08-02 03:56:08 +02:00
{
quoted_field = quote_name ( row [ 4 ] , buff , 0 ) ;
result_length + = strlen ( quoted_field ) + 1 ; /* + 1 for ',' or \0 */
} while ( ( row = mysql_fetch_row ( res ) ) & & atoi ( row [ 3 ] ) > 1 ) ;
2004-11-16 23:45:24 +01:00
}
/* Build the ORDER BY clause result */
2005-07-18 14:33:18 +02:00
if ( result_length )
{
2004-11-16 23:45:24 +01:00
char * end ;
/* result (terminating \0 is already in result_length) */
2006-08-02 03:18:47 +02:00
result = my_malloc ( result_length + 10 , MYF ( MY_WME ) ) ;
2005-07-18 14:33:18 +02:00
if ( ! result )
{
2004-11-16 23:45:24 +01:00
fprintf ( stderr , " Error: Not enough memory to store ORDER BY clause \n " ) ;
goto cleanup ;
}
2004-11-30 02:26:24 +01:00
mysql_data_seek ( res , 0 ) ;
2006-08-02 03:18:47 +02:00
row = mysql_fetch_row ( res ) ;
2006-08-02 03:56:08 +02:00
quoted_field = quote_name ( row [ 4 ] , buff , 0 ) ;
end = strmov ( result , quoted_field ) ;
2006-08-02 03:18:47 +02:00
while ( ( row = mysql_fetch_row ( res ) ) & & atoi ( row [ 3 ] ) > 1 )
2006-08-02 03:56:08 +02:00
{
quoted_field = quote_name ( row [ 4 ] , buff , 0 ) ;
end = strxmov ( end , " , " , quoted_field , NullS ) ;
}
2004-11-16 23:45:24 +01:00
}
cleanup :
if ( res )
mysql_free_result ( res ) ;
return result ;
}
2003-12-14 05:39:52 +01:00
2006-02-21 13:21:17 +01:00
/*
Replace a substring
SYNOPSIS
replace
ds_str The string to search and perform the replace in
search_str The string to search for
search_len Length of the string to search for
replace_str The string to replace with
replace_len Length of the string to replace with
RETURN
0 String replaced
1 Could not find search_str in str
*/
static int replace ( DYNAMIC_STRING * ds_str ,
const char * search_str , ulong search_len ,
const char * replace_str , ulong replace_len )
{
2006-02-23 14:06:29 +01:00
DYNAMIC_STRING ds_tmp ;
2006-02-21 13:21:17 +01:00
const char * start = strstr ( ds_str - > str , search_str ) ;
if ( ! start )
return 1 ;
init_dynamic_string ( & ds_tmp , " " ,
2006-05-25 10:00:28 +02:00
ds_str - > length + replace_len , 256 ) ;
2006-02-21 13:21:17 +01:00
dynstr_append_mem ( & ds_tmp , ds_str - > str , start - ds_str - > str ) ;
dynstr_append_mem ( & ds_tmp , replace_str , replace_len ) ;
dynstr_append ( & ds_tmp , start + search_len ) ;
dynstr_set ( ds_str , ds_tmp . str ) ;
dynstr_free ( & ds_tmp ) ;
return 0 ;
}
2004-11-12 04:01:46 +01:00
/*
Getting VIEW structure
SYNOPSIS
2005-04-04 23:32:48 +02:00
get_view_structure ( )
2004-11-12 04:01:46 +01:00
table view name
db db name
RETURN
0 OK
1 ERROR
*/
2005-04-04 23:32:48 +02:00
static my_bool get_view_structure ( char * table , char * db )
2004-11-12 04:01:46 +01:00
{
2005-04-04 23:32:48 +02:00
MYSQL_RES * table_res ;
2004-11-12 04:01:46 +01:00
MYSQL_ROW row ;
MYSQL_FIELD * field ;
2006-05-25 10:00:28 +02:00
char * result_table , * opt_quoted_table ;
char table_buff [ NAME_LEN * 2 + 3 ] ;
char table_buff2 [ NAME_LEN * 2 + 3 ] ;
2006-02-21 13:21:17 +01:00
char query [ QUERY_LENGTH ] ;
2006-08-02 03:18:47 +02:00
FILE * sql_file = md_result_file ;
2005-04-04 23:32:48 +02:00
DBUG_ENTER ( " get_view_structure " ) ;
2004-11-12 04:01:46 +01:00
2006-07-24 11:56:01 +02:00
if ( opt_no_create_info ) /* Don't write table creation info */
2004-11-12 04:01:46 +01:00
DBUG_RETURN ( 0 ) ;
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- Retrieving view structure for table %s... \n " , table ) ;
2004-11-12 04:01:46 +01:00
2005-05-19 00:40:34 +02:00
# ifdef NOT_REALLY_USED_YET
2004-11-12 04:01:46 +01:00
sprintf ( insert_pat , " SET OPTION SQL_QUOTE_SHOW_CREATE=%d " ,
2006-05-25 10:00:28 +02:00
( opt_quoted | | opt_keywords ) ) ;
2005-05-19 00:40:34 +02:00
# endif
2004-11-12 04:01:46 +01:00
result_table = quote_name ( table , table_buff , 1 ) ;
opt_quoted_table = quote_name ( table , table_buff2 , 0 ) ;
2006-02-23 16:08:28 +01:00
my_snprintf ( query , sizeof ( query ) , " SHOW CREATE TABLE %s " , result_table ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query_with_error_report ( mysql , & table_res , query ) )
2004-11-12 04:01:46 +01:00
{
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 0 ) ;
}
2006-02-21 13:21:17 +01:00
/* Check if this is a view */
field = mysql_fetch_field_direct ( table_res , 0 ) ;
if ( strcmp ( field - > name , " View " ) ! = 0 )
{
2006-07-24 11:51:52 +02:00
verbose_msg ( " -- It's base table, skipped \n " ) ;
2006-02-21 13:21:17 +01:00
DBUG_RETURN ( 0 ) ;
}
/* If requested, open separate .sql file for this view */
2004-11-12 04:01:46 +01:00
if ( path )
{
2006-02-21 13:21:17 +01:00
if ( ! ( sql_file = open_sql_file_for_table ( table ) ) )
2004-11-12 04:01:46 +01:00
{
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 1 ) ;
}
write_header ( sql_file , db ) ;
}
if ( ! opt_xml & & opt_comments )
{
2006-05-25 10:00:28 +02:00
fprintf ( sql_file , " \n -- \n -- Final view structure for view %s \n -- \n \n " ,
2004-11-12 04:01:46 +01:00
result_table ) ;
check_io ( sql_file ) ;
}
if ( opt_drop )
{
2005-07-29 22:39:08 +02:00
fprintf ( sql_file , " /*!50001 DROP TABLE IF EXISTS %s*/; \n " ,
opt_quoted_table ) ;
fprintf ( sql_file , " /*!50001 DROP VIEW IF EXISTS %s*/; \n " ,
opt_quoted_table ) ;
2004-11-12 04:01:46 +01:00
check_io ( sql_file ) ;
}
2006-02-23 16:08:28 +01:00
my_snprintf ( query , sizeof ( query ) ,
" SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE " \
" FROM information_schema.views " \
" WHERE table_name= \" %s \" AND table_schema= \" %s \" " , table , db ) ;
2006-07-24 12:00:44 +02:00
if ( mysql_query ( mysql , query ) )
2006-02-21 13:21:17 +01:00
{
/*
Use the raw output from SHOW CREATE TABLE if
information_schema query fails .
*/
row = mysql_fetch_row ( table_res ) ;
fprintf ( sql_file , " /*!50001 %s */; \n " , row [ 1 ] ) ;
check_io ( sql_file ) ;
mysql_free_result ( table_res ) ;
}
else
{
char * ptr ;
ulong * lengths ;
char search_buf [ 256 ] , replace_buf [ 256 ] ;
ulong search_len , replace_len ;
DYNAMIC_STRING ds_view ;
/* Save the result of SHOW CREATE TABLE in ds_view */
row = mysql_fetch_row ( table_res ) ;
lengths = mysql_fetch_lengths ( table_res ) ;
init_dynamic_string ( & ds_view , row [ 1 ] , lengths [ 1 ] + 1 , 1024 ) ;
mysql_free_result ( table_res ) ;
/* Get the result from "select ... information_schema" */
2006-07-24 12:00:44 +02:00
if ( ! ( table_res = mysql_store_result ( mysql ) ) | |
2006-07-14 01:25:13 +02:00
! ( row = mysql_fetch_row ( table_res ) ) )
2006-02-21 13:21:17 +01:00
{
safe_exit ( EX_MYSQLERR ) ;
DBUG_RETURN ( 1 ) ;
}
2006-07-14 01:25:13 +02:00
2006-02-21 13:21:17 +01:00
lengths = mysql_fetch_lengths ( table_res ) ;
/*
" WITH %s CHECK OPTION " is available from 5.0 .2
Surround it with ! 50002 comments
*/
if ( strcmp ( row [ 0 ] , " NONE " ) )
{
ptr = search_buf ;
search_len = ( ulong ) ( strxmov ( ptr , " WITH " , row [ 0 ] ,
" CHECK OPTION " , NullS ) - ptr ) ;
ptr = replace_buf ;
replace_len = ( ulong ) ( strxmov ( ptr , " */ \n /*!50002 WITH " , row [ 0 ] ,
" CHECK OPTION " , NullS ) - ptr ) ;
replace ( & ds_view , search_buf , search_len , replace_buf , replace_len ) ;
}
/*
" DEFINER=%s SQL SECURITY %s " is available from 5.0 .13
Surround it with ! 50013 comments
*/
{
uint user_name_len ;
char user_name_str [ USERNAME_LENGTH + 1 ] ;
char quoted_user_name_str [ USERNAME_LENGTH * 2 + 3 ] ;
uint host_name_len ;
char host_name_str [ HOSTNAME_LENGTH + 1 ] ;
char quoted_host_name_str [ HOSTNAME_LENGTH * 2 + 3 ] ;
parse_user ( row [ 1 ] , lengths [ 1 ] , user_name_str , & user_name_len ,
2006-05-25 10:00:28 +02:00
host_name_str , & host_name_len ) ;
2006-02-21 13:21:17 +01:00
ptr = search_buf ;
search_len =
( ulong ) ( strxmov ( ptr , " DEFINER= " ,
quote_name ( user_name_str , quoted_user_name_str , FALSE ) ,
" @ " ,
quote_name ( host_name_str , quoted_host_name_str , FALSE ) ,
" SQL SECURITY " , row [ 2 ] , NullS ) - ptr ) ;
ptr = replace_buf ;
replace_len =
( ulong ) ( strxmov ( ptr , " */ \n /*!50013 DEFINER= " ,
quote_name ( user_name_str , quoted_user_name_str , FALSE ) ,
" @ " ,
quote_name ( host_name_str , quoted_host_name_str , FALSE ) ,
" SQL SECURITY " , row [ 2 ] ,
" */ \n /*!50001 " , NullS ) - ptr ) ;
replace ( & ds_view , search_buf , search_len , replace_buf , replace_len ) ;
}
/* Dump view structure to file */
fprintf ( sql_file , " /*!50001 %s */; \n " , ds_view . str ) ;
check_io ( sql_file ) ;
mysql_free_result ( table_res ) ;
dynstr_free ( & ds_view ) ;
}
/* If a separate .sql file was opened, close it now */
2004-11-12 04:01:46 +01:00
if ( sql_file ! = md_result_file )
{
fputs ( " \n " , sql_file ) ;
write_footer ( sql_file ) ;
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
}
DBUG_RETURN ( 0 ) ;
}
2000-07-31 21:29:14 +02:00
int main ( int argc , char * * argv )
{
2005-07-31 11:49:55 +02:00
MY_INIT ( " mysqldump " ) ;
2004-03-11 15:46:27 +01:00
compatible_mode_normal_str [ 0 ] = 0 ;
2005-01-06 18:13:58 +01:00
default_charset = ( char * ) mysql_universal_client_charset ;
2005-06-27 19:31:00 +02:00
bzero ( ( char * ) & ignore_table , sizeof ( ignore_table ) ) ;
2001-10-04 19:43:06 +02:00
2000-07-31 21:29:14 +02:00
if ( get_options ( & argc , & argv ) )
{
my_end ( 0 ) ;
exit ( EX_USAGE ) ;
}
2000-11-13 22:55:10 +01:00
if ( dbConnect ( current_host , current_user , opt_password ) )
2000-07-31 21:29:14 +02:00
exit ( EX_MYSQLERR ) ;
if ( ! path )
2002-01-02 20:29:41 +01:00
write_header ( md_result_file , * argv ) ;
2004-11-10 17:56:45 +01:00
if ( ( opt_lock_all_tables | | opt_master_data ) & &
2006-07-24 12:00:44 +02:00
do_flush_tables_read_lock ( mysql ) )
2004-11-10 17:56:45 +01:00
goto err ;
2006-10-04 22:44:51 +02:00
if ( opt_single_transaction & & start_transaction ( mysql ) )
2004-11-10 17:56:45 +01:00
goto err ;
2006-07-24 12:00:44 +02:00
if ( opt_delete_master_logs & & do_reset_master ( mysql ) )
2004-11-10 17:56:45 +01:00
goto err ;
if ( opt_lock_all_tables | | opt_master_data )
2002-06-14 13:14:30 +02:00
{
2006-07-24 12:00:44 +02:00
if ( flush_logs & & mysql_refresh ( mysql , REFRESH_LOG ) )
2004-11-10 17:56:45 +01:00
goto err ;
flush_logs = 0 ; /* not anymore; that would not be sensible */
2002-06-14 13:14:30 +02:00
}
2006-07-24 12:00:44 +02:00
if ( opt_master_data & & do_show_master_status ( mysql ) )
2004-11-10 17:56:45 +01:00
goto err ;
2006-07-24 12:00:44 +02:00
if ( opt_single_transaction & & do_unlock_tables ( mysql ) ) /* unlock but no commit! */
2004-11-10 17:56:45 +01:00
goto err ;
2000-07-31 21:29:14 +02:00
if ( opt_alldbs )
dump_all_databases ( ) ;
else if ( argc > 1 & & ! opt_databases )
2002-06-11 10:20:31 +02:00
{
/* Only one database and selected table(s) */
2000-07-31 21:29:14 +02:00
dump_selected_tables ( * argv , ( argv + 1 ) , ( argc - 1 ) ) ;
2002-06-11 10:20:31 +02:00
}
2000-09-07 03:55:17 +02:00
else
2002-06-11 10:20:31 +02:00
{
/* One or more databases, all tables */
2000-07-31 21:29:14 +02:00
dump_databases ( argv ) ;
2002-06-11 10:20:31 +02:00
}
2002-11-14 20:16:30 +01:00
# ifdef HAVE_SMEM
my_free ( shared_memory_base_name , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
# endif
2004-11-10 17:56:45 +01:00
/*
No reason to explicitely COMMIT the transaction , neither to explicitely
UNLOCK TABLES : these will be automatically be done by the server when we
disconnect now . Saves some code here , some network trips , adds nothing to
server .
*/
err :
2000-07-31 21:29:14 +02:00
dbDisconnect ( current_host ) ;
2004-02-13 22:21:46 +01:00
if ( ! path )
write_footer ( md_result_file ) ;
2001-08-22 00:45:07 +02:00
if ( md_result_file ! = stdout )
my_fclose ( md_result_file , MYF ( 0 ) ) ;
2000-11-13 22:55:10 +01:00
my_free ( opt_password , MYF ( MY_ALLOW_ZERO_PTR ) ) ;
2005-06-27 19:31:00 +02:00
if ( hash_inited ( & ignore_table ) )
hash_free ( & ignore_table ) ;
2003-10-14 12:19:54 +02:00
if ( extended_insert )
2000-07-31 21:29:14 +02:00
dynstr_free ( & extended_row ) ;
2005-05-08 21:02:46 +02:00
if ( insert_pat_inited )
dynstr_free ( & insert_pat ) ;
2000-07-31 21:29:14 +02:00
my_end ( 0 ) ;
return ( first_error ) ;
} /* main */