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
* * or other
* * 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 >
* * T <EFBFBD> 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
2001-11-05 22:48:03 +01:00
*/
2000-07-31 21:29:14 +02:00
2003-09-05 05:56:28 +02:00
# define DUMP_VERSION "9.09"
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>
# include <m_string.h>
# include <m_ctype.h>
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
/* 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
# define QUOTE_CHAR '`'
2002-04-27 11:09:59 +02:00
/* Size of buffer for dump's select query */
# define QUERY_LENGTH 1536
2000-07-31 21:29:14 +02:00
static char * add_load_option ( char * ptr , const char * object ,
const char * statement ) ;
static char * field_escape ( char * to , const char * from , uint length ) ;
static my_bool verbose = 0 , tFlag = 0 , cFlag = 0 , dFlag = 0 , quick = 0 , extended_insert = 0 ,
lock_tables = 0 , ignore_errors = 0 , flush_logs = 0 , replace = 0 ,
ignore = 0 , opt_drop = 0 , opt_keywords = 0 , opt_lock = 0 , opt_compress = 0 ,
opt_delayed = 0 , create_options = 0 , opt_quoted = 0 , opt_databases = 0 ,
2001-12-20 19:14:55 +01:00
opt_alldbs = 0 , opt_create_db = 0 , opt_first_slave = 0 ,
2002-04-02 19:29:53 +02:00
opt_autocommit = 0 , opt_master_data , opt_disable_keys = 0 , opt_xml = 0 ,
2003-04-03 11:33:13 +02:00
opt_delete_master_logs = 0 , tty_password = 0 ,
opt_single_transaction = 0 ;
2000-07-31 21:29:14 +02:00
static MYSQL mysql_connection , * sock = 0 ;
2000-11-13 22:55:10 +01:00
static char insert_pat [ 12 * 1024 ] , * 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 ,
* where = 0 , * default_charset ;
static uint opt_mysql_port = 0 ;
static my_string opt_mysql_unix_port = 0 ;
static int first_error = 0 ;
extern ulong net_buffer_length ;
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 ;
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
{
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 } ,
2002-05-14 20:41:55 +02:00
{ " all " , ' a ' , " Include all MySQL specific create options. " ,
( gptr * ) & create_options , ( gptr * ) & create_options , 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. " ,
( gptr * ) & opt_drop , ( gptr * ) & opt_drop , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 ,
0 } ,
{ " add-locks " , OPT_LOCKS , " Add locks around insert statements. " ,
( gptr * ) & opt_lock , ( gptr * ) & opt_lock , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 ,
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 } ,
{ " character-sets-dir " , OPT_CHARSETS_DIR ,
" Directory where character sets are " , ( gptr * ) & charsets_dir ,
( gptr * ) & charsets_dir , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-05-14 20:41:55 +02:00
{ " complete-insert " , ' c ' , " Use complete insert statements. " , ( gptr * ) & cFlag ,
( gptr * ) & cFlag , 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 } ,
{ " 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 } ,
{ " debug " , ' # ' , " Output debug log. Often this is 'd:t:o,filename'. " ,
0 , 0 , 0 , GET_STR , OPT_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " 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 } ,
{ " delayed-insert " , OPT_DELAYED , " Insert rows with INSERT DELAYED. " ,
( 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 ,
" Delete logs on master after backup. This will automagically enable --first-slave. " ,
0 , 0 , 0 , GET_NO_ARG , 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 ,
( gptr * ) & opt_disable_keys , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " extended-insert " , ' e ' ,
" Allows utilization of the new, much faster INSERT syntax. " ,
( gptr * ) & extended_insert , ( gptr * ) & extended_insert , 0 , GET_BOOL , NO_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
{ " 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 ... " ,
( gptr * ) & escaped , ( gptr * ) & escaped , 0 , GET_STR , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " first-slave " , ' x ' , " Locks all tables across all databases. " ,
( gptr * ) & opt_first_slave , ( gptr * ) & opt_first_slave , 0 , GET_BOOL , NO_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
{ " flush-logs " , ' F ' , " Flush logs file in server before starting dump. " ,
( gptr * ) & flush_logs , ( gptr * ) & flush_logs , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
0 , 0 } ,
{ " 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 } ,
{ " 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 } ,
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 } ,
{ " lock-tables " , ' l ' , " Lock all tables for read. " , ( gptr * ) & lock_tables ,
( gptr * ) & lock_tables , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " master-data " , OPT_MASTER_DATA ,
" This will cause the master position and filename to be appended to your output. This will automagically enable --first-slave. " ,
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " 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 } ,
2002-06-11 11:37:48 +02:00
{ " single-transaction " , OPT_TRANSACTION ,
" Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables. " ,
( gptr * ) & opt_single_transaction , ( gptr * ) & opt_single_transaction , 0 , GET_BOOL , NO_ARG ,
0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " no-create-db " , ' n ' ,
" '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.} " ,
( 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. " ,
2002-05-14 20:41:55 +02:00
( gptr * ) & tFlag , ( gptr * ) & tFlag , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " no-data " , ' d ' , " No row information. " , ( gptr * ) & dFlag , ( gptr * ) & dFlag , 0 ,
GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
2002-04-02 19:29:53 +02:00
{ " set-variable " , ' O ' ,
2002-06-01 10:46:06 +02:00
" Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value. " ,
2002-04-02 19:29:53 +02:00
0 , 0 , 0 , GET_STR , REQUIRED_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " opt " , OPT_OPTIMIZE ,
" Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys " ,
0 , 0 , 0 , GET_NO_ARG , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " 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__
2002-04-02 19:29:53 +02:00
{ " pipe " , ' W ' , " Use named pipes to connect to server " , 0 , 0 , 0 , GET_NO_ARG ,
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 ,
( gptr * ) & opt_mysql_port , 0 , GET_UINT , REQUIRED_ARG , MYSQL_PORT , 0 , 0 , 0 , 0 ,
0 } ,
2002-04-02 19:29:53 +02:00
{ " quick " , ' q ' , " Don't buffer query, dump directly to stdout. " ,
( gptr * ) & quick , ( gptr * ) & quick , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 , 0 , 0 } ,
{ " quote-names " , ' Q ' , " Quote table and column names with a ` " ,
( gptr * ) & opt_quoted , ( gptr * ) & opt_quoted , 0 , GET_BOOL , NO_ARG , 0 , 0 , 0 , 0 ,
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 } ,
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 } ,
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 } ,
2002-05-11 13:36:34 +02:00
{ " max_allowed_packet " , OPT_MAX_ALLOWED_PACKET , " " ,
2002-04-02 19:29:53 +02:00
( gptr * ) & max_allowed_packet , ( gptr * ) & max_allowed_packet , 0 ,
2002-09-19 16:49:41 +02:00
GET_ULONG , REQUIRED_ARG , 24 * 1024 * 1024 , 4096 , 1024 * 1024L * 1024L ,
2002-04-02 19:29:53 +02:00
MALLOC_OVERHEAD , 1024 , 0 } ,
2002-05-11 13:36:34 +02:00
{ " net_buffer_length " , OPT_NET_BUFFER_LENGTH , " " ,
2002-04-02 19:29:53 +02:00
( gptr * ) & net_buffer_length , ( gptr * ) & net_buffer_length , 0 ,
2002-05-11 13:36:34 +02:00
GET_ULONG , REQUIRED_ARG , 1024 * 1024L - 1025 , 4096 , 16 * 1024L * 1024L ,
2002-04-03 12:36:01 +02:00
MALLOC_OVERHEAD - 1024 , 1024 , 0 } ,
2002-05-11 13:36:34 +02: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 ,
const char * prefix , const char * name ,
int string_value ) ;
static int dump_selected_tables ( char * db , char * * table_names , int tables ) ;
static int dump_all_tables_in_db ( char * db ) ;
static int init_dumping ( char * ) ;
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 ) ;
2001-11-26 18:14:26 +01:00
static void print_quoted_xml ( FILE * output , char * fname , char * str , uint len ) ;
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 ,
MYSQL_SERVER_VERSION , SYSTEM_TYPE , MACHINE_TYPE ) ;
} /* 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 " ,
my_progname ) ;
printf ( " OR %s [OPTIONS] --all-databases [OPTIONS] \n " , my_progname ) ;
}
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 ) ;
}
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
{
2001-11-05 22:48:03 +01:00
fprintf ( sql_file , " <?xml version= \" 1.0 \" ?> \n " ) ;
2002-11-18 17:50:42 +01:00
fprintf ( sql_file , " <mysqldump> \n " ) ;
}
2001-11-05 22:48:03 +01:00
else
{
fprintf ( sql_file , " -- MySQL dump %s \n -- \n " , DUMP_VERSION ) ;
fprintf ( sql_file , " -- Host: %s Database: %s \n " ,
current_host ? current_host : " localhost " , db_name ? db_name : " " ) ;
2003-09-06 21:06:08 +02:00
fputs ( " -- ------------------------------------------------------ \n " ,
2001-11-05 22:48:03 +01:00
sql_file ) ;
fprintf ( sql_file , " -- Server version \t %s \n " ,
mysql_get_server_info ( & mysql_connection ) ) ;
}
2000-07-31 21:29:14 +02:00
return ;
2002-01-02 20:29:41 +01:00
} /* write_header */
2000-07-31 21:29:14 +02:00
2002-11-18 17:50:42 +01:00
static void write_footer ( FILE * sql_file )
{
if ( opt_xml )
fprintf ( sql_file , " </mysqldump> " ) ;
fputs ( " \n " , sql_file ) ;
} /* write_footer */
2000-07-31 21:29:14 +02:00
2003-04-03 11:33:13 +02:00
2002-04-02 19:29:53 +02:00
static my_bool
get_one_option ( int optid , const struct my_option * opt __attribute__ ( ( unused ) ) ,
char * argument )
2000-07-31 21:29:14 +02:00
{
2003-04-03 11:33:13 +02:00
switch ( optid ) {
2002-04-02 19:29:53 +02:00
case OPT_MASTER_DATA :
opt_master_data = 1 ;
opt_first_slave = 1 ;
break ;
2003-04-03 11:33:13 +02:00
case OPT_DELETE_MASTER_LOGS :
opt_delete_master_logs = 1 ;
opt_first_slave = 1 ;
break ;
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 ) ) ;
while ( * argument ) * argument + + = ' x ' ; /* Destroy argument */
if ( * start )
start [ 1 ] = 0 ; /* Cut length of argument */
}
else
tty_password = 1 ;
break ;
case ' r ' :
2003-01-28 07:38:28 +01:00
if ( ! ( md_result_file = my_fopen ( argument , O_WRONLY | FILE_BINARY ,
2002-04-02 19:29:53 +02:00
MYF ( MY_WME ) ) ) )
exit ( 1 ) ;
break ;
case ' W ' :
2000-07-31 21:29:14 +02:00
# ifdef __WIN__
2002-04-02 19:29:53 +02:00
opt_mysql_unix_port = MYSQL_NAMEDPIPE ;
2000-07-31 21:29:14 +02:00
# endif
2002-04-02 19:29:53 +02:00
break ;
case ' T ' :
opt_disable_keys = 0 ;
break ;
case ' # ' :
DBUG_PUSH ( argument ? argument : " d:t:o " ) ;
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 ' :
opt_xml = 1 ;
opt_disable_keys = 0 ;
break ;
case ' I ' :
case ' ? ' :
usage ( ) ;
exit ( 0 ) ;
case ( int ) OPT_OPTIMIZE :
2002-06-11 11:37:48 +02:00
extended_insert = opt_drop = opt_lock = quick = create_options = opt_disable_keys =
lock_tables = 1 ;
if ( opt_single_transaction ) lock_tables = 0 ;
2002-04-02 19:29:53 +02:00
break ;
case ( int ) OPT_TABLES :
opt_databases = 0 ;
break ;
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 ;
md_result_file = stdout ;
load_defaults ( " my " , load_default_groups , argc , argv ) ;
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
2000-07-31 21:29:14 +02:00
if ( opt_delayed )
opt_lock = 0 ; /* Can't have lock with delayed */
if ( ! path & & ( enclosed | | opt_enclosed | | escaped | | lines_terminated | |
fields_terminated ) )
{
2002-04-02 19:29:53 +02:00
fprintf ( stderr ,
" %s: You must use option --tab with --fields-... \n " , my_progname ) ;
2000-07-31 21:29:14 +02:00
return ( 1 ) ;
}
2002-06-11 11:37:48 +02:00
if ( opt_single_transaction & & lock_tables )
{
fprintf ( stderr , " %s: You can't use --lock-tables and --single-transaction at the same time. \n " , my_progname ) ;
return ( 1 ) ;
}
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 ( replace & & ignore )
{
fprintf ( stderr , " %s: You can't use --ignore (-i) and --replace (-r) at the same time. \n " , my_progname ) ;
return ( 1 ) ;
}
if ( ( opt_databases | | opt_alldbs ) & & path )
{
fprintf ( stderr ,
" %s: --databases or --all-databases can't be used with --tab. \n " ,
my_progname ) ;
return ( 1 ) ;
}
if ( default_charset )
{
if ( set_default_charset_by_name ( default_charset , MYF ( MY_WME ) ) )
exit ( 1 ) ;
}
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 */
/*
* * DBerror - - prints mysql error message and exits the program .
*/
static void DBerror ( MYSQL * mysql , const char * when )
{
DBUG_ENTER ( " DBerror " ) ;
2000-08-30 19:40:59 +02:00
my_printf_error ( 0 , " Got error: %d: %s %s " , MYF ( 0 ) ,
2000-07-31 21:29:14 +02:00
mysql_errno ( mysql ) , mysql_error ( mysql ) , when ) ;
safe_exit ( EX_MYSQLERR ) ;
DBUG_VOID_RETURN ;
} /* DBerror */
static void safe_exit ( int error )
{
if ( ! first_error )
first_error = error ;
if ( ignore_errors )
return ;
if ( sock )
mysql_close ( sock ) ;
exit ( error ) ;
}
/* safe_exit */
/*
* * dbConnect - - connects to the host and selects DB .
* * Also checks whether the tablename is a valid table name .
*/
static int dbConnect ( char * host , char * user , char * passwd )
{
DBUG_ENTER ( " dbConnect " ) ;
if ( verbose )
{
2001-07-04 08:39:58 +02:00
fprintf ( stderr , " -- 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 ,
2001-09-30 04:46:20 +02:00
opt_ssl_capath , opt_ssl_cipher ) ;
2000-07-31 21:29:14 +02:00
# endif
if ( ! ( sock = mysql_real_connect ( & mysql_connection , host , user , passwd ,
NULL , opt_mysql_port , opt_mysql_unix_port ,
0 ) ) )
{
DBerror ( & mysql_connection , " when trying to connect " ) ;
return 1 ;
}
return 0 ;
} /* dbConnect */
/*
* * dbDisconnect - - disconnects from the host .
*/
static void dbDisconnect ( char * host )
{
if ( verbose )
2001-07-04 08:39:58 +02:00
fprintf ( stderr , " -- Disconnecting from %s... \n " , host ? host : " localhost " ) ;
2000-07-31 21:29:14 +02:00
mysql_close ( sock ) ;
} /* 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 ) ) ) )
{
ignore_errors = 0 ; /* Fatal error */
safe_exit ( EX_MYSQLERR ) ; /* Force exit */
}
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 ) ;
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 + + )
if ( ! isvar ( * str ) & & * str ! = ' $ ' )
return 1 ;
# endif
return 0 ;
} /* test_if_special_chars */
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 ;
if ( ! force & & ! opt_quoted & & ! test_if_special_chars ( name ) )
return ( char * ) name ;
* to + + = QUOTE_CHAR ;
while ( * name )
{
if ( * name = = QUOTE_CHAR )
* to = QUOTE_CHAR ;
* to + + = * name + + ;
}
to [ 0 ] = QUOTE_CHAR ;
to [ 1 ] = 0 ;
2000-07-31 21:29:14 +02:00
return buff ;
} /* quote_name */
/*
2003-09-03 17:48:10 +02:00
getStructure - - retrievs database structure , prints out corresponding
CREATE statement and fills out insert_pat .
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
2000-07-31 21:29:14 +02:00
static uint getTableStructure ( char * table , char * db )
{
MYSQL_RES * tableRes ;
MYSQL_ROW row ;
my_bool init = 0 ;
uint numFields ;
2003-09-03 17:48:10 +02:00
char * strpos , * result_table , * opt_quoted_table ;
2000-07-31 21:29:14 +02:00
const char * delayed ;
2003-09-03 17:48:10 +02:00
char name_buff [ NAME_LEN + 3 ] , table_buff [ NAME_LEN * 2 + 3 ] ;
char table_buff2 [ NAME_LEN * 2 + 3 ] ;
2001-08-22 00:45:07 +02:00
FILE * sql_file = md_result_file ;
2000-07-31 21:29:14 +02:00
DBUG_ENTER ( " getTableStructure " ) ;
delayed = opt_delayed ? " DELAYED " : " " ;
if ( verbose )
2001-07-04 08:39:58 +02:00
fprintf ( stderr , " -- Retrieving table structure for table %s... \n " , table ) ;
2000-07-31 21:29:14 +02:00
2003-02-12 20:46:40 +01:00
sprintf ( insert_pat , " SET OPTION SQL_QUOTE_SHOW_CREATE=%d " , ( opt_quoted | | opt_keywords ) ) ;
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 ) ;
2000-12-08 19:12:12 +01:00
if ( ! mysql_query ( sock , insert_pat ) )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
/* using SHOW CREATE statement */
if ( ! tFlag )
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 ] ;
2003-09-03 17:48:10 +02:00
sprintf ( buff , " show create table %s " , result_table ) ;
2000-10-29 13:49:42 +01:00
if ( mysql_query ( sock , buff ) )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
fprintf ( stderr , " %s: Can't get CREATE TABLE for table %s (%s) \n " ,
my_progname , result_table , mysql_error ( sock ) ) ;
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 )
{
char filename [ FN_REFLEN ] , tmp_path [ FN_REFLEN ] ;
2001-10-08 03:58:07 +02:00
convert_dirname ( tmp_path , path , NullS ) ;
2000-10-29 13:49:42 +01:00
sql_file = my_fopen ( fn_format ( filename , table , tmp_path , " .sql " , 4 ) ,
2001-12-20 19:14:55 +01:00
O_WRONLY , MYF ( MY_WME ) ) ;
2000-10-29 13:49:42 +01:00
if ( ! sql_file ) /* If file couldn't be opened */
{
2001-04-23 23:31:34 +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
}
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
2003-09-03 17:48:10 +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 )
2003-09-03 17:48:10 +02:00
fprintf ( sql_file , " DROP TABLE IF EXISTS %s; \n " , opt_quoted_table ) ;
2000-10-29 13:49:42 +01:00
tableRes = mysql_store_result ( sock ) ;
row = mysql_fetch_row ( tableRes ) ;
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
fprintf ( sql_file , " %s; \n " , row [ 1 ] ) ;
2000-10-29 13:49:42 +01:00
mysql_free_result ( tableRes ) ;
}
2003-09-03 17:48:10 +02:00
sprintf ( insert_pat , " show fields from %s " , result_table ) ;
2000-10-29 13:49:42 +01:00
if ( mysql_query ( sock , insert_pat ) | | ! ( tableRes = mysql_store_result ( sock ) ) )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
fprintf ( stderr , " %s: Can't get info about table: %s \n error: %s \n " ,
my_progname , result_table , mysql_error ( sock ) ) ;
2002-01-02 20:29:41 +01:00
if ( path )
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
2000-07-31 21:29:14 +02:00
if ( cFlag )
2003-09-03 17:48:10 +02:00
sprintf ( insert_pat , " INSERT %sINTO %s ( " , delayed , opt_quoted_table ) ;
2000-10-29 13:49:42 +01:00
else
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
sprintf ( insert_pat , " INSERT %sINTO %s VALUES " , delayed ,
opt_quoted_table ) ;
2000-10-29 13:49:42 +01:00
if ( ! extended_insert )
strcat ( insert_pat , " ( " ) ;
}
strpos = strend ( insert_pat ) ;
while ( ( row = mysql_fetch_row ( tableRes ) ) )
{
if ( init )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
if ( cFlag )
2000-12-15 09:58:17 +01:00
strpos = strmov ( strpos , " , " ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
init = 1 ;
if ( cFlag )
2003-09-03 17:48:10 +02:00
strpos = strmov ( strpos , quote_name ( row [ SHOW_FIELDNAME ] , name_buff , 0 ) ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
numFields = ( uint ) mysql_num_rows ( tableRes ) ;
mysql_free_result ( tableRes ) ;
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
{
2000-10-29 13:49:42 +01:00
/* fprintf(stderr, "%s: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
my_progname , mysql_error ( sock ) ) ; */
2003-09-03 17:48:10 +02:00
sprintf ( insert_pat , " show fields from %s " , result_table ) ;
2000-10-29 13:49:42 +01:00
if ( mysql_query ( sock , insert_pat ) | | ! ( tableRes = mysql_store_result ( sock ) ) )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
fprintf ( stderr , " %s: Can't get info about table: %s \n error: %s \n " ,
my_progname , result_table , mysql_error ( sock ) ) ;
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 */
if ( ! tFlag )
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
{
2000-10-29 13:49:42 +01:00
char filename [ FN_REFLEN ] , tmp_path [ FN_REFLEN ] ;
2001-10-08 03:58:07 +02:00
convert_dirname ( tmp_path , path , NullS ) ;
2000-10-29 13:49:42 +01:00
sql_file = my_fopen ( fn_format ( filename , table , tmp_path , " .sql " , 4 ) ,
O_WRONLY , MYF ( MY_WME ) ) ;
if ( ! sql_file ) /* If file couldn't be opened */
{
2002-01-02 20:29:41 +01: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
}
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
2003-09-03 17:48:10 +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 )
2003-09-02 18:30:34 +02:00
fprintf ( sql_file , " DROP TABLE IF EXISTS %s; \n " , result_table ) ;
fprintf ( sql_file , " CREATE TABLE %s ( \n " , result_table ) ;
2000-10-29 13:49:42 +01:00
}
if ( cFlag )
2003-09-02 18:30:34 +02:00
sprintf ( insert_pat , " INSERT %sINTO %s ( " , delayed , result_table ) ;
2000-10-29 13:49:42 +01:00
else
{
2003-09-02 18:30:34 +02:00
sprintf ( insert_pat , " INSERT %sINTO %s VALUES " , delayed , result_table ) ;
2000-10-29 13:49:42 +01:00
if ( ! extended_insert )
strcat ( insert_pat , " ( " ) ;
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
strpos = strend ( insert_pat ) ;
2000-07-31 21:29:14 +02:00
while ( ( row = mysql_fetch_row ( tableRes ) ) )
{
2000-10-29 13:49:42 +01:00
ulong * lengths = mysql_fetch_lengths ( tableRes ) ;
if ( init )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
if ( ! tFlag )
2001-04-25 23:10:43 +02:00
fputs ( " , \n " , sql_file ) ;
2000-10-29 13:49:42 +01:00
if ( cFlag )
2001-04-25 23:10:43 +02:00
strpos = strmov ( strpos , " , " ) ;
2000-10-29 13:49:42 +01:00
}
init = 1 ;
if ( cFlag )
2003-09-03 17:48:10 +02:00
strpos = strmov ( strpos , quote_name ( row [ SHOW_FIELDNAME ] , name_buff , 0 ) ) ;
2000-10-29 13:49:42 +01:00
if ( ! tFlag )
{
if ( opt_keywords )
2003-09-02 18:30:34 +02:00
fprintf ( sql_file , " %s.%s %s " , result_table ,
2003-09-03 17:48:10 +02:00
quote_name ( row [ SHOW_FIELDNAME ] , name_buff , 0 ) ,
row [ SHOW_TYPE ] ) ;
2000-10-29 13:49:42 +01:00
else
2001-04-23 23:31:34 +02:00
fprintf ( sql_file , " %s %s " , quote_name ( row [ SHOW_FIELDNAME ] ,
2003-09-03 17:48:10 +02:00
name_buff , 0 ) ,
row [ SHOW_TYPE ] ) ;
2000-10-29 13:49:42 +01:00
if ( row [ SHOW_DEFAULT ] )
{
2001-04-23 23:31:34 +02:00
fputs ( " DEFAULT " , sql_file ) ;
2001-11-05 22:48:03 +01:00
unescape ( sql_file , row [ SHOW_DEFAULT ] , lengths [ SHOW_DEFAULT ] ) ;
2000-10-29 13:49:42 +01:00
}
if ( ! row [ SHOW_NULL ] [ 0 ] )
2001-04-23 23:31:34 +02:00
fputs ( " NOT NULL " , sql_file ) ;
2000-10-29 13:49:42 +01:00
if ( row [ SHOW_EXTRA ] [ 0 ] )
2001-04-23 23:31:34 +02:00
fprintf ( sql_file , " %s " , row [ SHOW_EXTRA ] ) ;
2000-07-31 21:29:14 +02:00
}
}
2000-10-29 13:49:42 +01:00
numFields = ( uint ) mysql_num_rows ( tableRes ) ;
mysql_free_result ( tableRes ) ;
if ( ! tFlag )
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 ;
2003-09-03 17:48:10 +02:00
sprintf ( buff , " show keys from %s " , result_table ) ;
2000-07-31 21:29:14 +02:00
if ( mysql_query ( sock , buff ) )
{
2003-09-03 17:48:10 +02:00
fprintf ( stderr , " %s: Can't get keys for table %s (%s) \n " ,
my_progname , result_table , mysql_error ( sock ) ) ;
2002-01-02 20:29:41 +01:00
if ( path )
2001-04-23 23:31:34 +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
tableRes = mysql_store_result ( sock ) ;
/* Find first which key is primary key */
keynr = 0 ;
primary_key = INT_MAX ;
while ( ( row = mysql_fetch_row ( tableRes ) ) )
2000-07-31 21:29:14 +02:00
{
2000-10-29 13:49:42 +01:00
if ( atoi ( row [ 3 ] ) = = 1 )
{
2001-04-23 23:31:34 +02:00
keynr + + ;
# ifdef FORCE_PRIMARY_KEY
if ( atoi ( row [ 1 ] ) = = 0 & & primary_key = = INT_MAX )
primary_key = keynr ;
# endif
if ( ! strcmp ( row [ 2 ] , " PRIMARY " ) )
{
primary_key = keynr ;
break ;
}
2000-10-29 13:49:42 +01:00
}
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
mysql_data_seek ( tableRes , 0 ) ;
keynr = 0 ;
while ( ( row = mysql_fetch_row ( tableRes ) ) )
{
if ( atoi ( row [ 3 ] ) = = 1 )
{
2001-04-23 23:31:34 +02:00
if ( keynr + + )
putc ( ' ) ' , sql_file ) ;
if ( atoi ( row [ 1 ] ) ) /* Test if duplicate key */
/* Duplicate allowed */
2003-09-03 17:48:10 +02:00
fprintf ( sql_file , " , \n KEY %s ( " , quote_name ( row [ 2 ] , name_buff , 0 ) ) ;
2001-04-23 23:31:34 +02:00
else if ( keynr = = primary_key )
fputs ( " , \n PRIMARY KEY ( " , sql_file ) ; /* First UNIQUE is primary */
else
2003-09-03 17:48:10 +02:00
fprintf ( sql_file , " , \n UNIQUE %s ( " , quote_name ( row [ 2 ] , name_buff , 0 ) ) ;
2000-10-29 13:49:42 +01:00
}
else
2001-04-23 23:31:34 +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 ] )
2001-04-23 23:31:34 +02:00
fprintf ( sql_file , " (%s) " , row [ 7 ] ) ; /* Sub key */
2000-10-29 13:49:42 +01:00
}
if ( keynr )
putc ( ' ) ' , sql_file ) ;
fputs ( " \n ) " , sql_file ) ;
/* Get MySQL specific create options */
if ( create_options )
2000-07-31 21:29:14 +02:00
{
2003-09-03 17:48:10 +02:00
sprintf ( buff , " show table status like %s " , result_table ) ;
2000-10-29 13:49:42 +01:00
if ( mysql_query ( sock , buff ) )
{
2001-04-23 23:31:34 +02:00
if ( mysql_errno ( sock ) ! = ER_PARSE_ERROR )
{ /* If old MySQL version */
if ( verbose )
fprintf ( stderr ,
2003-09-03 17:48:10 +02:00
" -- Warning: Couldn't get status information for table %s (%s) \n " ,
result_table , mysql_error ( sock ) ) ;
2001-04-23 23:31:34 +02:00
}
2000-10-29 13:49:42 +01:00
}
else if ( ! ( tableRes = mysql_store_result ( sock ) ) | |
2001-04-23 23:31:34 +02:00
! ( row = mysql_fetch_row ( tableRes ) ) )
2000-10-29 13:49:42 +01:00
{
2001-04-23 23:31:34 +02:00
fprintf ( stderr ,
2003-09-03 17:48:10 +02:00
" Error: Couldn't read status information for table %s (%s) \n " ,
result_table , mysql_error ( sock ) ) ;
2000-10-29 13:49:42 +01:00
}
else
{
2001-04-23 23:31:34 +02:00
fputs ( " /*! " , sql_file ) ;
print_value ( sql_file , tableRes , row , " type= " , " Type " , 0 ) ;
print_value ( sql_file , tableRes , row , " " , " Create_options " , 0 ) ;
print_value ( sql_file , tableRes , row , " comment= " , " Comment " , 1 ) ;
fputs ( " */ " , sql_file ) ;
2000-10-29 13:49:42 +01:00
}
mysql_free_result ( tableRes ) ; /* Is always safe to free */
2000-07-31 21:29:14 +02:00
}
2000-10-29 13:49:42 +01:00
fputs ( " ; \n " , sql_file ) ;
2000-07-31 21:29:14 +02:00
}
}
if ( cFlag )
{
strpos = strmov ( strpos , " ) VALUES " ) ;
if ( ! extended_insert )
strpos = strmov ( strpos , " ( " ) ;
}
2002-01-02 20:29:41 +01:00
if ( sql_file ! = md_result_file )
my_fclose ( sql_file , MYF ( MY_WME ) ) ;
2000-07-31 21:29:14 +02:00
DBUG_RETURN ( numFields ) ;
} /* getTableStructure */
static char * add_load_option ( char * ptr , const char * object ,
const char * statement )
{
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 */
/*
* * Allow the user to specify field terminator strings like :
* * " ' " , " \" , " \ \ " (escaped backslash), " \ t " (tab), " \ n " (newline)
* * This is done by doubleing ' and add a end - \ if needed to avoid
* * syntax errors from the SQL parser .
*/
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 )
* to + + = * from ; /* We want a duplicate of "'" for MySQL */
end_backslashes = 0 ;
}
}
/* Add missing backslashes if user has specified odd number of backs.*/
if ( end_backslashes )
* to + + = ' \\ ' ;
return to ;
} /* field_escape */
/*
* * dumpTable saves database contents as a series of INSERT statements .
*/
static void dumpTable ( uint numFields , char * table )
{
2002-04-27 11:09:59 +02:00
char query [ QUERY_LENGTH ] , * end , buff [ 256 ] , table_buff [ NAME_LEN + 3 ] ;
2003-09-05 05:56:28 +02:00
char * result_table , table_buff2 [ NAME_LEN * 2 + 3 ] , * opt_quoted_table ;
2000-07-31 21:29:14 +02:00
MYSQL_RES * res ;
2003-02-16 21:50:00 +01:00
MYSQL_FIELD * field ;
MYSQL_ROW row ;
2000-07-31 21:29:14 +02:00
ulong rownr , row_break , total_length , init_length ;
if ( verbose )
2001-07-04 08:39:58 +02:00
fprintf ( stderr , " -- Sending SELECT query... \n " ) ;
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 ) ;
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
filename wasn ' t deleted */
to_unix_path ( filename ) ;
2002-04-27 11:09:59 +02:00
sprintf ( query , " SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s' " ,
filename ) ;
2000-07-31 21:29:14 +02:00
end = strend ( query ) ;
if ( replace )
end = strmov ( end , " REPLACE " ) ;
if ( ignore )
end = strmov ( end , " IGNORE " ) ;
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 ' ;
2003-09-03 17:48:10 +02:00
sprintf ( buff , " FROM %s " , result_table ) ;
2000-07-31 21:29:14 +02:00
end = strmov ( end , buff ) ;
if ( where )
end = strxmov ( end , " WHERE " , where , NullS ) ;
if ( mysql_query ( sock , query ) )
{
DBerror ( sock , " when executing 'SELECT INTO OUTFILE' " ) ;
return ;
}
}
else
{
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
2003-09-03 17:48:10 +02:00
fprintf ( md_result_file , " \n -- \n -- Dumping data for table %s \n -- \n " ,
result_table ) ;
2002-04-27 11:09:59 +02:00
sprintf ( query , " SELECT /*!40001 SQL_NO_CACHE */ * FROM %s " ,
2003-09-05 05:56:28 +02:00
result_table ) ;
2000-07-31 21:29:14 +02:00
if ( where )
{
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
fprintf ( md_result_file , " -- WHERE: %s \n " , where ) ;
2000-07-31 21:29:14 +02:00
strxmov ( strend ( query ) , " WHERE " , where , NullS ) ;
}
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
2002-04-03 12:36:01 +02:00
fputs ( " \n " , md_result_file ) ;
2000-07-31 21:29:14 +02:00
if ( mysql_query ( sock , query ) )
{
DBerror ( sock , " when retrieving data from server " ) ;
return ;
}
if ( quick )
res = mysql_use_result ( sock ) ;
else
res = mysql_store_result ( sock ) ;
if ( ! res )
{
DBerror ( sock , " when retrieving data from server " ) ;
return ;
}
if ( verbose )
2001-07-04 08:39:58 +02:00
fprintf ( stderr , " -- Retrieving rows... \n " ) ;
2000-07-31 21:29:14 +02:00
if ( mysql_num_fields ( res ) ! = numFields )
{
2003-09-03 17:48:10 +02:00
fprintf ( stderr , " %s: Error in field count for table: %s ! Aborting. \n " ,
my_progname , result_table ) ;
2000-07-31 21:29:14 +02:00
safe_exit ( EX_CONSCHECK ) ;
return ;
}
2002-04-03 12:36:01 +02:00
if ( opt_disable_keys )
2003-09-05 07:16:13 +02:00
fprintf ( md_result_file , " \n /*!40000 ALTER TABLE %s DISABLE KEYS */; \n " ,
2003-09-05 05:56:28 +02:00
opt_quoted_table ) ;
2000-07-31 21:29:14 +02:00
if ( opt_lock )
2003-09-03 17:48:10 +02:00
fprintf ( md_result_file , " LOCK TABLES %s WRITE; \n " , opt_quoted_table ) ;
2000-07-31 21:29:14 +02:00
total_length = net_buffer_length ; /* Force row break */
row_break = 0 ;
rownr = 0 ;
2000-08-21 23:18:32 +02:00
init_length = ( uint ) strlen ( insert_pat ) + 4 ;
2001-11-05 22:48:03 +01:00
if ( opt_xml )
2002-11-18 17:50:42 +01:00
fprintf ( md_result_file , " \t <table name= \" %s \" > \n " , table ) ;
2000-07-31 21:29:14 +02:00
2001-10-04 19:43:06 +02:00
if ( opt_autocommit )
fprintf ( md_result_file , " set autocommit=0; \n " ) ;
2000-07-31 21:29:14 +02:00
while ( ( row = mysql_fetch_row ( res ) ) )
{
uint i ;
ulong * lengths = mysql_fetch_lengths ( res ) ;
rownr + + ;
2001-11-05 22:48:03 +01:00
if ( ! extended_insert & & ! opt_xml )
2001-08-22 00:45:07 +02:00
fputs ( insert_pat , md_result_file ) ;
2000-07-31 21:29:14 +02:00
mysql_field_seek ( res , 0 ) ;
2002-04-03 12:36:01 +02:00
if ( opt_xml )
fprintf ( md_result_file , " \t <row> \n " ) ;
2000-07-31 21:29:14 +02:00
for ( i = 0 ; i < mysql_num_fields ( res ) ; i + + )
{
if ( ! ( field = mysql_fetch_field ( res ) ) )
{
2003-09-03 17:48:10 +02:00
sprintf ( query , " %s: Not enough fields from table %s! Aborting. \n " ,
my_progname , result_table ) ;
2000-07-31 21:29:14 +02:00
fputs ( query , stderr ) ;
safe_exit ( EX_CONSCHECK ) ;
return ;
}
if ( extended_insert )
{
ulong length = lengths [ i ] ;
if ( i = = 0 )
dynstr_set ( & extended_row , " ( " ) ;
else
dynstr_append ( & extended_row , " , " ) ;
if ( row [ i ] )
{
if ( length )
{
2000-09-02 06:58:42 +02:00
if ( ! IS_NUM_FIELD ( field ) )
2000-07-31 21:29:14 +02:00
{
if ( dynstr_realloc ( & extended_row , length * 2 + 2 ) )
{
fputs ( " Aborting dump (out of memory) " , stderr ) ;
safe_exit ( EX_EOM ) ;
}
dynstr_append ( & extended_row , " \' " ) ;
2000-08-30 19:40:59 +02:00
extended_row . length + =
2000-07-31 21:29:14 +02:00
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 , " \' " ) ;
}
else
2001-09-03 15:09:25 +02:00
{
2003-12-09 14:33:29 +01:00
/* change any strings ("inf", "-inf", "nan") into NULL */
2001-09-03 15:09:25 +02:00
char * ptr = row [ i ] ;
2003-12-09 14:33:29 +01:00
if ( isalpha ( * ptr ) | | ( * ptr = = ' - ' & & * ( ptr + 1 ) = = ' i ' ) )
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 ) ;
}
2001-09-03 15:09:25 +02:00
}
2000-07-31 21:29:14 +02:00
}
else
dynstr_append ( & extended_row , " \' \' " ) ;
}
else if ( dynstr_append ( & extended_row , " NULL " ) )
{
fputs ( " Aborting dump (out of memory) " , stderr ) ;
safe_exit ( EX_EOM ) ;
}
}
else
{
2001-11-05 22:48:03 +01:00
if ( i & & ! opt_xml )
fputc ( ' , ' , md_result_file ) ;
2000-07-31 21:29:14 +02:00
if ( row [ i ] )
{
2000-09-02 06:58:42 +02:00
if ( ! IS_NUM_FIELD ( field ) )
2001-12-20 19:14:55 +01:00
{
2001-11-26 18:14:26 +01:00
if ( opt_xml )
print_quoted_xml ( md_result_file , field - > name , row [ i ] ,
lengths [ i ] ) ;
else
unescape ( md_result_file , row [ i ] , lengths [ i ] ) ;
2001-11-05 22:48:03 +01:00
}
2000-07-31 21:29:14 +02:00
else
2001-09-03 15:09:25 +02:00
{
2003-12-09 14:33:29 +01:00
/* change any strings ("inf", "-inf", "nan") into NULL */
2001-09-03 15:09:25 +02:00
char * ptr = row [ i ] ;
2001-11-26 18:14:26 +01:00
if ( opt_xml )
2002-11-18 17:50:42 +01:00
fprintf ( md_result_file , " \t \t <field name= \" %s \" >%s</field> \n " ,
field - > name , ! isalpha ( * ptr ) ? ptr : " NULL " ) ;
2003-12-09 14:33:29 +01:00
else if ( isalpha ( * ptr ) | | ( * ptr = = ' - ' & & * ( ptr + 1 ) = = ' i ' ) )
fputs ( " NULL " , md_result_file ) ;
2001-11-26 18:14:26 +01:00
else
2003-12-09 14:33:29 +01:00
{
if ( field - > type = = FIELD_TYPE_DECIMAL )
{
/* add " signs around */
fputs ( " \" " , md_result_file ) ;
fputs ( ptr , md_result_file ) ;
fputs ( " \" " , md_result_file ) ;
}
else
fputs ( ptr , md_result_file ) ;
}
2001-09-03 15:09:25 +02:00
}
2000-07-31 21:29:14 +02:00
}
else
{
2001-11-05 22:48:03 +01:00
if ( opt_xml )
2002-11-18 17:50:42 +01:00
fprintf ( md_result_file , " \t \t <field name= \" %s \" >%s</field> \n " ,
field - > name , " NULL " ) ;
2001-11-05 22:48:03 +01:00
else
fputs ( " NULL " , md_result_file ) ;
2000-07-31 21:29:14 +02:00
}
}
}
2002-04-03 12:36:01 +02:00
if ( opt_xml )
fprintf ( md_result_file , " \t </row> \n " ) ;
2000-07-31 21:29:14 +02:00
if ( extended_insert )
{
ulong row_length ;
dynstr_append ( & extended_row , " ) " ) ;
row_length = 2 + extended_row . length ;
if ( total_length + row_length < net_buffer_length )
{
total_length + = row_length ;
2001-08-22 00:45:07 +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
{
2001-11-05 22:48:03 +01:00
if ( row_break & & ! opt_xml )
2001-08-22 00:45:07 +02:00
fputs ( " ; \n " , md_result_file ) ;
2000-07-31 21:29:14 +02:00
row_break = 1 ; /* This is first row */
2001-12-06 13:10:51 +01:00
2001-11-05 22:48:03 +01:00
if ( ! opt_xml )
{
fputs ( insert_pat , md_result_file ) ;
fputs ( extended_row . str , md_result_file ) ;
}
2000-07-31 21:29:14 +02:00
total_length = row_length + init_length ;
}
}
2001-11-05 22:48:03 +01:00
else if ( ! opt_xml )
2001-08-22 00:45:07 +02:00
fputs ( " ); \n " , md_result_file ) ;
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 )
2002-11-18 17:50:42 +01:00
fprintf ( md_result_file , " \t </table> \n " ) ;
2001-11-05 22:48:03 +01:00
else if ( extended_insert & & row_break )
2001-08-22 00:45:07 +02:00
fputs ( " ; \n " , md_result_file ) ; /* If not empty table */
fflush ( md_result_file ) ;
2000-07-31 21:29:14 +02:00
if ( mysql_errno ( sock ) )
{
2003-09-03 17:48:10 +02:00
sprintf ( query , " %s: Error %d: %s when dumping table %s at row: %ld \n " ,
2000-07-31 21:29:14 +02:00
my_progname ,
mysql_errno ( sock ) ,
mysql_error ( sock ) ,
2003-09-03 17:48:10 +02:00
result_table ,
2000-07-31 21:29:14 +02:00
rownr ) ;
fputs ( query , stderr ) ;
safe_exit ( EX_CONSCHECK ) ;
return ;
}
if ( opt_lock )
2001-08-22 00:45:07 +02:00
fputs ( " UNLOCK TABLES; \n " , md_result_file ) ;
2002-04-03 12:36:01 +02:00
if ( opt_disable_keys )
fprintf ( md_result_file , " /*!40000 ALTER TABLE %s ENABLE KEYS */; \n " ,
2003-09-05 05:56:28 +02:00
opt_quoted_table ) ;
2001-10-04 19:43:06 +02:00
if ( opt_autocommit )
fprintf ( md_result_file , " commit; \n " ) ;
2001-10-10 22:44:07 +02:00
mysql_free_result ( res ) ;
2000-07-31 21:29:14 +02:00
}
} /* dumpTable */
2001-11-26 18:14:26 +01:00
static void print_quoted_xml ( FILE * output , char * fname , char * str , uint len )
{
const char * end ;
2001-12-06 13:10:51 +01:00
2002-11-18 17:50:42 +01:00
fprintf ( output , " \t \t <field name= \" %s \" > " , fname ) ;
2001-11-26 18:14:26 +01:00
for ( end = str + len ; str ! = end ; str + + )
{
if ( * str = = ' < ' )
fputs ( " < " , output ) ;
else if ( * str = = ' > ' )
fputs ( " > " , output ) ;
else if ( * str = = ' & ' )
fputs ( " & " , output ) ;
else if ( * str = = ' \" ' )
fputs ( " " " , output ) ;
else
fputc ( * str , output ) ;
}
2002-11-18 17:50:42 +01:00
fprintf ( output , " </field> \n " ) ;
2001-11-26 18:14:26 +01:00
}
2000-07-31 21:29:14 +02:00
static char * getTableName ( int reset )
{
static MYSQL_RES * res = NULL ;
MYSQL_ROW row ;
if ( ! res )
{
if ( ! ( res = mysql_list_tables ( sock , NullS ) ) )
return ( NULL ) ;
}
if ( ( row = mysql_fetch_row ( res ) ) )
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 ) ;
res = NULL ;
}
return ( NULL ) ;
} /* getTableName */
static int dump_all_databases ( )
{
MYSQL_ROW row ;
MYSQL_RES * tableres ;
int result = 0 ;
if ( mysql_query ( sock , " SHOW DATABASES " ) | |
! ( tableres = mysql_store_result ( sock ) ) )
{
my_printf_error ( 0 , " Error: Couldn't execute 'SHOW DATABASES': %s " ,
MYF ( 0 ) , mysql_error ( sock ) ) ;
return 1 ;
}
while ( ( row = mysql_fetch_row ( tableres ) ) )
{
if ( dump_all_tables_in_db ( row [ 0 ] ) )
result = 1 ;
}
return result ;
}
/* dump_all_databases */
static int dump_databases ( char * * db_names )
{
int result = 0 ;
for ( ; * db_names ; db_names + + )
2001-12-20 19:14:55 +01:00
{
2000-07-31 21:29:14 +02:00
if ( dump_all_tables_in_db ( * db_names ) )
result = 1 ;
}
return result ;
} /* dump_databases */
static int init_dumping ( char * database )
{
if ( mysql_select_db ( sock , database ) )
{
DBerror ( sock , " when selecting the database " ) ;
return 1 ; /* If --force */
}
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-10-24 23:26:26 +02:00
/* length of table name * 2 (if name contain quotas), 2 quotas and 0 */
char quoted_database_buf [ 64 * 2 + 3 ] ;
char * qdatabase = quote_name ( database , quoted_database_buf , opt_quoted ) ;
2001-10-04 19:43:06 +02:00
fprintf ( md_result_file , " \n -- \n -- Current Database: %s \n -- \n " , database ) ;
2000-07-31 21:29:14 +02:00
if ( ! opt_create_db )
2001-08-22 00:45:07 +02:00
fprintf ( md_result_file , " \n CREATE DATABASE /*!32312 IF NOT EXISTS*/ %s; \n " ,
2003-10-24 23:26:26 +02:00
qdatabase ) ;
2001-08-22 00:45:07 +02:00
fprintf ( md_result_file , " \n USE %s; \n " , database ) ;
2000-07-31 21:29:14 +02:00
}
}
if ( extended_insert )
if ( init_dynamic_string ( & extended_row , " " , 1024 , 1024 ) )
exit ( EX_EOM ) ;
return 0 ;
} /* init_dumping */
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
if ( init_dumping ( database ) )
return 1 ;
2002-11-18 17:50:42 +01:00
if ( opt_xml )
fprintf ( md_result_file , " <database name= \" %s \" > \n " , database ) ;
2000-07-31 21:29:14 +02:00
if ( lock_tables )
{
DYNAMIC_STRING query ;
init_dynamic_string ( & query , " LOCK TABLES " , 256 , 1024 ) ;
for ( numrows = 0 ; ( table = getTableName ( 1 ) ) ; numrows + + )
{
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 */, " ) ;
}
if ( numrows & & mysql_real_query ( sock , query . str , query . length - 1 ) )
2000-09-07 03:55:17 +02:00
DBerror ( sock , " 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 )
{
if ( mysql_refresh ( sock , REFRESH_LOG ) )
2000-09-07 03:55:17 +02:00
DBerror ( sock , " when doing refresh " ) ;
2000-07-31 21:29:14 +02:00
/* We shall continue here, if --force was given */
}
while ( ( table = getTableName ( 0 ) ) )
{
numrows = getTableStructure ( table , database ) ;
if ( ! dFlag & & numrows > 0 )
dumpTable ( numrows , table ) ;
}
2002-11-18 17:50:42 +01:00
if ( opt_xml )
fprintf ( md_result_file , " </database> \n " ) ;
2000-07-31 21:29:14 +02:00
if ( lock_tables )
mysql_query ( sock , " UNLOCK_TABLES " ) ;
return 0 ;
} /* dump_all_tables_in_db */
static int dump_selected_tables ( char * db , char * * table_names , int tables )
{
uint numrows ;
2003-09-03 17:48:10 +02:00
char table_buff [ NAME_LEN * + 3 ] ;
2000-07-31 21:29:14 +02:00
if ( init_dumping ( db ) )
return 1 ;
if ( lock_tables )
{
DYNAMIC_STRING query ;
int i ;
init_dynamic_string ( & query , " LOCK TABLES " , 256 , 1024 ) ;
for ( i = 0 ; i < tables ; i + + )
{
2003-09-03 17:48:10 +02:00
dynstr_append ( & query , quote_name ( table_names [ i ] , table_buff , 1 ) ) ;
2000-07-31 21:29:14 +02:00
dynstr_append ( & query , " READ /*!32311 LOCAL */, " ) ;
}
if ( mysql_real_query ( sock , query . str , query . length - 1 ) )
2000-09-07 03:55:17 +02:00
DBerror ( sock , " when doing LOCK TABLES " ) ;
2000-07-31 21:29:14 +02:00
/* We shall countinue here, if --force was given */
dynstr_free ( & query ) ;
}
if ( flush_logs )
{
if ( mysql_refresh ( sock , REFRESH_LOG ) )
2000-09-07 03:55:17 +02:00
DBerror ( sock , " 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 )
fprintf ( md_result_file , " <database name= \" %s \" > \n " , db ) ;
2000-07-31 21:29:14 +02:00
for ( ; tables > 0 ; tables - - , table_names + + )
{
numrows = getTableStructure ( * table_names , db ) ;
if ( ! dFlag & & numrows > 0 )
dumpTable ( numrows , * table_names ) ;
}
2002-11-18 17:50:42 +01:00
if ( opt_xml )
fprintf ( md_result_file , " </database> \n " ) ;
2000-07-31 21:29:14 +02:00
if ( lock_tables )
mysql_query ( sock , " UNLOCK_TABLES " ) ;
return 0 ;
} /* dump_selected_tables */
/* Print a value with a prefix on file */
static void print_value ( FILE * file , MYSQL_RES * result , MYSQL_ROW row ,
const char * prefix , const char * name ,
int string_value )
{
MYSQL_FIELD * field ;
mysql_field_seek ( result , 0 ) ;
for ( ; ( field = mysql_fetch_field ( result ) ) ; row + + )
{
if ( ! strcmp ( field - > name , name ) )
{
if ( row [ 0 ] & & row [ 0 ] [ 0 ] & & strcmp ( row [ 0 ] , " 0 " ) ) /* Skip default */
{
fputc ( ' ' , file ) ;
fputs ( prefix , file ) ;
if ( string_value )
2000-08-21 23:18:32 +02:00
unescape ( file , row [ 0 ] , ( uint ) strlen ( row [ 0 ] ) ) ;
2000-07-31 21:29:14 +02:00
else
fputs ( row [ 0 ] , file ) ;
return ;
}
}
}
return ; /* This shouldn't happen */
} /* print_value */
int main ( int argc , char * * argv )
{
2001-10-04 19:43:06 +02:00
MYSQL_ROW row ;
MYSQL_RES * master ;
2000-07-31 21:29:14 +02:00
MY_INIT ( argv [ 0 ] ) ;
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 ) ;
if ( opt_first_slave )
{
lock_tables = 0 ; /* No other locks needed */
if ( mysql_query ( sock , " FLUSH TABLES WITH READ LOCK " ) )
{
my_printf_error ( 0 , " Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s " ,
MYF ( 0 ) , mysql_error ( sock ) ) ;
my_end ( 0 ) ;
return ( first_error ) ;
}
}
2002-06-11 11:37:48 +02:00
else if ( opt_single_transaction )
2002-06-14 13:14:30 +02:00
{
/* There is no sense to start transaction if all tables are locked */
if ( mysql_query ( sock , " BEGIN " ) )
2002-06-11 11:37:48 +02:00
{
2002-06-14 13:14:30 +02:00
my_printf_error ( 0 , " Error: Couldn't execute 'BEGIN': %s " ,
2002-06-11 11:37:48 +02:00
MYF ( 0 ) , mysql_error ( sock ) ) ;
2002-06-14 13:14:30 +02:00
my_end ( 0 ) ;
return ( first_error ) ;
}
}
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
}
2000-07-31 21:29:14 +02:00
if ( opt_first_slave )
{
2003-03-19 15:16:51 +01:00
if ( opt_delete_master_logs & & mysql_query ( sock , " FLUSH MASTER " ) )
{
my_printf_error ( 0 , " Error: Couldn't execute 'FLUSH MASTER': %s " ,
MYF ( 0 ) , mysql_error ( sock ) ) ;
}
2001-10-04 19:43:06 +02:00
if ( opt_master_data )
{
if ( mysql_query ( sock , " SHOW MASTER STATUS " ) | |
! ( master = mysql_store_result ( sock ) ) )
my_printf_error ( 0 , " Error: Couldn't execute 'SHOW MASTER STATUS': %s " ,
MYF ( 0 ) , mysql_error ( sock ) ) ;
2001-12-20 19:14:55 +01:00
else
2001-10-04 19:43:06 +02:00
{
row = mysql_fetch_row ( master ) ;
2003-05-07 23:12:46 +02:00
if ( row & & row [ 0 ] & & row [ 1 ] )
2002-06-11 10:20:31 +02:00
{
2001-10-04 19:43:06 +02:00
fprintf ( md_result_file ,
" \n -- \n -- Position to start replication from \n -- \n \n " ) ;
fprintf ( md_result_file ,
2 minor edits, plus
fix for BUG#1113 "INSERT into non-trans table SELECT ; ROLLBACK" does not send warning"
and
fix for BUG#873 "In transaction, INSERT to non-trans table is written too early to binlog".
Now we don't always write the non-trans update immediately to the binlog;
if there is something in the binlog cache we write it to the binlog cache
(because the non-trans update could depend on a trans table which was modified
earlier in the transaction); then in case of ROLLBACK, we write the binlog
cache to the binlog, wrapped with BEGIN/ROLLBACK.
This guarantees that the slave does the same updates.
For ROLLBACK TO SAVEPOINT: when we execute a SAVEPOINT command we write it
to the binlog cache. At ROLLBACK TO SAVEPOINT, if some non-trans table was updated,
we write ROLLBACK TO SAVEPOINT to the binlog cache; when the transaction
terminates (COMMIT/ROLLBACK), the binlog cache will be flushed to the binlog
(because of the non-trans update) so we'll have SAVEPOINT and ROLLBACK TO
SAVEPOINT in the binlog.
Apart from this rare case of updates of mixed table types in transaction, the
usual way is still clear the binlog cache at ROLLBACK, or chop it at
ROLLBACK TO SAVEPOINT (meaning the SAVEPOINT command is also chopped, which
is fine).
Note that BUG#873 encompasses subbugs 1) and 2) of BUG#333 "3 binlogging bugs when doing INSERT with mixed InnoDB/MyISAM".
2003-08-22 15:39:24 +02:00
" CHANGE MASTER TO MASTER_LOG_FILE='%s', \
MASTER_LOG_POS = % s ; \ n " ,row[0],row[1]);
2001-10-04 19:43:06 +02:00
}
mysql_free_result ( master ) ;
}
}
2000-07-31 21:29:14 +02:00
if ( mysql_query ( sock , " UNLOCK TABLES " ) )
my_printf_error ( 0 , " Error: Couldn't execute 'UNLOCK TABLES': %s " ,
MYF ( 0 ) , mysql_error ( sock ) ) ;
}
2002-06-11 11:37:48 +02:00
else if ( opt_single_transaction ) /* Just to make it beautiful enough */
{
2002-06-14 13:14:30 +02:00
/*
2002-06-18 23:22:30 +02:00
In case we were locking all tables , we did not start transaction
so there is no need to commit it .
2002-06-14 13:14:30 +02:00
*/
2002-06-11 11:37:48 +02:00
/* This should just free locks as we did not change anything */
if ( mysql_query ( sock , " COMMIT " ) )
{
my_printf_error ( 0 , " Error: Couldn't execute 'COMMIT': %s " ,
MYF ( 0 ) , mysql_error ( sock ) ) ;
}
}
2000-07-31 21:29:14 +02:00
dbDisconnect ( current_host ) ;
2002-11-18 17:50:42 +01:00
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 ) ) ;
2000-07-31 21:29:14 +02:00
if ( extended_insert )
dynstr_free ( & extended_row ) ;
my_end ( 0 ) ;
return ( first_error ) ;
} /* main */