~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzledump.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
2
 
 
3
 
  This program is free software; you can redistribute it and/or modify
4
 
  it under the terms of the GNU General Public License as published by
5
 
  the Free Software Foundation; version 2 of the License.
6
 
 
7
 
  This program is distributed in the hope that it will be useful,
8
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
  GNU General Public License for more details.
11
 
 
12
 
  You should have received a copy of the GNU General Public License
13
 
  along with this program; if not, write to the Free Software
14
 
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
1
/* Copyright (C) 2008 Drizzle Open Source Development Project
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/* drizzledump.cc  - Dump a tables contents and format to an ASCII file
17
 
 
18
 
 * Derived from mysqldump, which originally came from:
19
 
 **
20
 
 ** The author's original notes follow :-
21
 
 **
22
 
 ** AUTHOR: Igor Romanenko (igor@frog.kiev.ua)
23
 
 ** DATE:   December 3, 1994
24
 
 ** WARRANTY: None, expressed, impressed, implied
25
 
 **          or other
26
 
 ** STATUS: Public domain
27
 
 
28
 
 * and more work by Monty, Jani & Sinisa
29
 
 * and all the MySQL developers over the years.
 
17
**
 
18
** The author's original notes follow :-
 
19
**
 
20
** AUTHOR: Igor Romanenko (igor@frog.kiev.ua)
 
21
** DATE:   December 3, 1994
 
22
** WARRANTY: None, expressed, impressed, implied
 
23
**          or other
 
24
** STATUS: Public domain
30
25
*/
31
26
 
 
27
#define DUMP_VERSION "10.13"
 
28
 
32
29
#include "client_priv.h"
33
30
#include <string>
34
31
 
35
 
#include "drizzled/internal/my_sys.h"
36
 
#include "drizzled/internal/m_string.h"
37
 
#include "drizzled/charset_info.h"
38
 
#include "drizzled/hash.h"
 
32
#include <mysys/my_sys.h>
 
33
#include <mystrings/m_string.h>
 
34
#include <mystrings/m_ctype.h>
 
35
#include <mysys/hash.h>
39
36
#include <stdarg.h>
40
37
#include <algorithm>
41
38
 
44
41
#include <drizzled/error.h>
45
42
 
46
43
using namespace std;
47
 
using namespace drizzled;
48
 
 
49
44
/* Exit codes */
50
45
 
51
46
#define EX_USAGE 1
76
71
static void add_load_option(string &str, const char *option,
77
72
                            const char *option_value);
78
73
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
79
 
                         char **err_pos, uint32_t *err_len);
 
74
                      char **err_pos, uint32_t *err_len);
80
75
 
81
76
static void field_escape(string &in, const char *from);
82
 
static bool  verbose= false;
83
 
static bool opt_no_create_info= false;
84
 
static bool opt_no_data= false;
85
 
static bool opt_mysql= false;
86
 
static bool quick= true;
87
 
static bool extended_insert= true;
88
 
static bool ignore_errors= false;
89
 
static bool flush_logs= false;
90
 
static bool opt_drop= true; 
91
 
static bool opt_keywords= false;
92
 
static bool opt_compress= false;
93
 
static bool opt_delayed= false; 
94
 
static bool create_options= true; 
95
 
static bool opt_quoted= false;
96
 
static bool opt_databases= false; 
97
 
static bool opt_alldbs= false; 
98
 
static bool opt_create_db= false;
99
 
static bool opt_lock_all_tables= false;
100
 
static bool opt_set_charset= false; 
101
 
static bool opt_dump_date= true;
102
 
static bool opt_autocommit= false; 
103
 
static bool opt_disable_keys= true;
104
 
static bool opt_xml= false;
105
 
static bool tty_password= false;
106
 
static bool opt_single_transaction= false; 
107
 
static bool opt_comments= false;
108
 
static bool opt_compact= false;
109
 
static bool opt_hex_blob= false;
110
 
static bool opt_order_by_primary=false; 
111
 
static bool opt_ignore= false;
112
 
static bool opt_complete_insert= false;
113
 
static bool opt_drop_database= false;
114
 
static bool opt_replace_into= false;
115
 
static bool opt_routines= false;
116
 
static bool opt_alltspcs= false;
 
77
static bool  verbose= false, opt_no_create_info= false, opt_no_data= false,
 
78
                quick= true, extended_insert= true,
 
79
                lock_tables= true, ignore_errors= false, flush_logs= false,
 
80
                opt_drop= true, opt_keywords= false,
 
81
                opt_lock= true, opt_compress= false,
 
82
                opt_delayed= false, create_options= true, opt_quoted= false,
 
83
                opt_databases= false, opt_alldbs= false, opt_create_db= false,
 
84
                opt_lock_all_tables= false,
 
85
                opt_set_charset= false, opt_dump_date= true,
 
86
                opt_autocommit= false, opt_disable_keys= true, opt_xml= false,
 
87
                opt_delete_master_logs= false, tty_password= false,
 
88
                opt_single_transaction= false, opt_comments= false,
 
89
                opt_compact= false, opt_hex_blob= false, 
 
90
                opt_order_by_primary=false, opt_ignore= false,
 
91
                opt_complete_insert= false, opt_drop_database= false,
 
92
                opt_replace_into= false,
 
93
                opt_routines= false,
 
94
                opt_slave_apply= false,
 
95
                opt_include_master_host_port= false,
 
96
                opt_alltspcs= false;
 
97
static bool debug_info_flag= false, debug_check_flag= false;
117
98
static uint32_t show_progress_size= 0;
118
99
static uint64_t total_rows= 0;
119
100
static drizzle_st drizzle;
120
101
static drizzle_con_st dcon;
121
102
static string insert_pat;
122
 
static char  *opt_password= NULL;
123
 
static char *current_user= NULL;
124
 
static char  *current_host= NULL;
125
 
static char *path= NULL;
126
 
static char *fields_terminated= NULL;
127
 
static char *lines_terminated= NULL; 
128
 
static char *enclosed= NULL;
129
 
static char *opt_enclosed= NULL;
130
 
static char *escaped= NULL;
131
 
static char *where= NULL; 
132
 
static char *order_by= NULL;
133
 
static char *opt_compatible_mode_str= NULL;
134
 
static char *err_ptr= NULL;
 
103
static char  *opt_password= NULL, *current_user= NULL,
 
104
             *current_host= NULL, *path= NULL, *fields_terminated= NULL,
 
105
             *lines_terminated= NULL, *enclosed= NULL, *opt_enclosed= NULL,
 
106
             *escaped= NULL,
 
107
             *where= NULL, *order_by= NULL,
 
108
             *opt_compatible_mode_str= NULL,
 
109
             *err_ptr= NULL;
135
110
static char **defaults_argv= NULL;
136
111
static char compatible_mode_normal_str[255];
137
112
static uint32_t opt_compatible_mode= 0;
 
113
#define DRIZZLE_OPT_MASTER_DATA_EFFECTIVE_SQL 1
 
114
#define DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL 2
 
115
#define DRIZZLE_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
 
116
#define DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL 2
138
117
static uint32_t opt_drizzle_port= 0;
 
118
static uint32_t opt_master_data;
 
119
static uint32_t opt_slave_data;
 
120
static uint32_t my_end_arg;
139
121
static int first_error= 0;
140
122
static string extended_row;
141
123
FILE *md_result_file= 0;
142
124
FILE *stderror_file= 0;
143
125
 
 
126
/*
 
127
  Constant for detection of default value of default_charset.
 
128
  If default_charset is equal to drizzle_universal_client_charset, then
 
129
  it is the default value which assigned at the very beginning of main().
 
130
*/
 
131
static const char *drizzle_universal_client_charset=
 
132
  DRIZZLE_UNIVERSAL_CLIENT_CHARSET;
 
133
static char *default_charset;
144
134
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
145
 
 
146
 
static const char *compatible_mode_names[]=
 
135
const char *default_dbug_option="d:t:o,/tmp/drizzledump.trace";
 
136
const char *compatible_mode_names[]=
147
137
{
148
138
  "MYSQL323", "MYSQL40", "POSTGRESQL", "ORACLE", "MSSQL", "DB2",
149
139
  "MAXDB", "NO_KEY_OPTIONS", "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS",
150
140
  "ANSI",
151
141
  NULL
152
142
};
153
 
static TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
154
 
  "", compatible_mode_names, NULL};
155
 
 
156
 
drizzled::hash_set<string> ignore_table;
157
 
 
158
 
static struct option my_long_options[] =
 
143
#define MASK_ANSI_QUOTES \
 
144
(\
 
145
 (1<<2)  | /* POSTGRESQL */\
 
146
 (1<<3)  | /* ORACLE     */\
 
147
 (1<<4)  | /* MSSQL      */\
 
148
 (1<<5)  | /* DB2        */\
 
149
 (1<<6)  | /* MAXDB      */\
 
150
 (1<<10)   /* ANSI       */\
 
151
)
 
152
TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
 
153
                                  "", compatible_mode_names, NULL};
 
154
 
 
155
HASH ignore_table;
 
156
 
 
157
static struct my_option my_long_options[] =
159
158
{
160
159
  {"all", 'a', "Deprecated. Use --create-options instead.",
161
 
    (char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
162
 
    0, 0, 0, 0, 0},
 
160
   (char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
 
161
   0, 0, 0, 0, 0},
163
162
  {"all-databases", 'A',
164
 
    "Dump all the databases. This will be same as --databases with all databases selected.",
165
 
    (char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
166
 
    0, 0},
 
163
   "Dump all the databases. This will be same as --databases with all databases selected.",
 
164
   (char**) &opt_alldbs, (char**) &opt_alldbs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
165
   0, 0},
167
166
  {"all-tablespaces", 'Y',
168
 
    "Dump all the tablespaces.",
169
 
    (char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
170
 
    0, 0},
 
167
   "Dump all the tablespaces.",
 
168
   (char**) &opt_alltspcs, (char**) &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
169
   0, 0},
171
170
  {"add-drop-database", OPT_DROP_DATABASE, "Add a 'DROP DATABASE' before each create.",
172
 
    (char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
173
 
    0},
 
171
   (char**) &opt_drop_database, (char**) &opt_drop_database, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
172
   0},
174
173
  {"add-drop-table", OPT_DROP, "Add a 'drop table' before each create.",
175
 
    (char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
176
 
    0},
 
174
   (char**) &opt_drop, (char**) &opt_drop, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
 
175
   0},
 
176
  {"add-locks", OPT_LOCKS, "Add locks around insert statements.",
 
177
   (char**) &opt_lock, (char**) &opt_lock, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0,
 
178
   0},
177
179
  {"allow-keywords", OPT_KEYWORDS,
178
 
    "Allow creation of column names that are keywords.", (char**) &opt_keywords,
179
 
    (char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
180
   "Allow creation of column names that are keywords.", (char**) &opt_keywords,
 
181
   (char**) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
182
  {"apply-slave-statements", OPT_DRIZZLEDUMP_SLAVE_APPLY,
 
183
   "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
 
184
   (char**) &opt_slave_apply, (char**) &opt_slave_apply, 0, GET_BOOL, NO_ARG,
 
185
   0, 0, 0, 0, 0, 0},
180
186
  {"comments", 'i', "Write additional information.",
181
 
    (char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
182
 
    1, 0, 0, 0, 0, 0},
 
187
   (char**) &opt_comments, (char**) &opt_comments, 0, GET_BOOL, NO_ARG,
 
188
   1, 0, 0, 0, 0, 0},
183
189
  {"compatible", OPT_COMPATIBLE,
184
 
    "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 DRIZZLE server version 4.1.0 or higher. This option is ignored with earlier server versions.",
185
 
    (char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
186
 
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
190
   "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 DRIZZLE server version 4.1.0 or higher. This option is ignored with earlier server versions.",
 
191
   (char**) &opt_compatible_mode_str, (char**) &opt_compatible_mode_str, 0,
 
192
   GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
187
193
  {"compact", OPT_COMPACT,
188
 
    "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",
189
 
    (char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
190
 
    0, 0},
 
194
   "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",
 
195
   (char**) &opt_compact, (char**) &opt_compact, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
196
   0, 0},
191
197
  {"complete-insert", 'c', "Use complete insert statements.",
192
 
    (char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
193
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
 
198
   (char**) &opt_complete_insert, (char**) &opt_complete_insert, 0, GET_BOOL,
 
199
   NO_ARG, 0, 0, 0, 0, 0, 0},
194
200
  {"compress", 'C', "Use compression in server/client protocol.",
195
 
    (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
196
 
    0, 0, 0},
 
201
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
202
   0, 0, 0},
197
203
  {"create-options", OPT_CREATE_OPTIONS,
198
 
    "Include all DRIZZLE specific create options.",
199
 
    (char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
200
 
    0, 0, 0, 0, 0},
 
204
   "Include all DRIZZLE specific create options.",
 
205
   (char**) &create_options, (char**) &create_options, 0, GET_BOOL, NO_ARG, 1,
 
206
   0, 0, 0, 0, 0},
201
207
  {"databases", 'B',
202
 
    "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.",
203
 
    (char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
204
 
    0, 0, 0, 0},
 
208
   "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.",
 
209
   (char**) &opt_databases, (char**) &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0,
 
210
   0, 0, 0, 0},
 
211
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
 
212
   (char**) &debug_check_flag, (char**) &debug_check_flag, 0,
 
213
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
214
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
215
   (char**) &debug_info_flag, (char**) &debug_info_flag,
 
216
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
217
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
218
   "Set the default character set.", (char**) &default_charset,
 
219
   (char**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
205
220
  {"delayed-insert", OPT_DELAYED, "Insert rows with INSERT DELAYED; ",
206
 
    (char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
207
 
    0, 0},
 
221
   (char**) &opt_delayed, (char**) &opt_delayed, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
222
   0, 0},
 
223
  {"delete-master-logs", OPT_DELETE_MASTER_LOGS,
 
224
   "Delete logs on master after backup. This automatically enables --master-data.",
 
225
   (char**) &opt_delete_master_logs, (char**) &opt_delete_master_logs, 0,
 
226
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
208
227
  {"disable-keys", 'K',
209
 
    "'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.", (char**) &opt_disable_keys,
210
 
    (char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
228
   "'ALTER TABLE tb_name DISABLE KEYS; and 'ALTER TABLE tb_name ENABLE KEYS; will be put in the output.", (char**) &opt_disable_keys,
 
229
   (char**) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
230
  {"dump-slave", OPT_DRIZZLEDUMP_SLAVE_DATA,
 
231
   "This causes the binary log position and filename of the master to be "
 
232
   "appended to the dumped data output. Setting the value to 1, will print"
 
233
   "it as a CHANGE MASTER command in the dumped data output; if equal"
 
234
   " to 2, that command will be prefixed with a comment symbol. "
 
235
   "This option will turn --lock-all-tables on, unless "
 
236
   "--single-transaction is specified too (in which case a "
 
237
   "global read lock is only taken a short time at the beginning of the dump "
 
238
   "- don't forget to read about --single-transaction below). In all cases "
 
239
   "any action on logs will happen at the exact moment of the dump."
 
240
   "Option automatically turns --lock-tables off.",
 
241
   (char**) &opt_slave_data, (char**) &opt_slave_data, 0,
 
242
   GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
211
243
  {"extended-insert", 'e',
212
 
    "Allows utilization of the new, much faster INSERT syntax.",
213
 
    (char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
214
 
    1, 0, 0, 0, 0, 0},
 
244
   "Allows utilization of the new, much faster INSERT syntax.",
 
245
   (char**) &extended_insert, (char**) &extended_insert, 0, GET_BOOL, NO_ARG,
 
246
   1, 0, 0, 0, 0, 0},
215
247
  {"fields-terminated-by", OPT_FTB,
216
 
    "Fields in the textfile are terminated by ...", (char**) &fields_terminated,
217
 
    (char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
248
   "Fields in the textfile are terminated by ...", (char**) &fields_terminated,
 
249
   (char**) &fields_terminated, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
218
250
  {"fields-enclosed-by", OPT_ENC,
219
 
    "Fields in the importfile are enclosed by ...", (char**) &enclosed,
220
 
    (char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
 
251
   "Fields in the importfile are enclosed by ...", (char**) &enclosed,
 
252
   (char**) &enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
221
253
  {"fields-optionally-enclosed-by", OPT_O_ENC,
222
 
    "Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
223
 
    (char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
 
254
   "Fields in the i.file are opt. enclosed by ...", (char**) &opt_enclosed,
 
255
   (char**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0},
224
256
  {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...",
225
 
    (char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
257
   (char**) &escaped, (char**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
258
  {"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.",
 
259
   (char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
 
260
   0, 0, 0, 0, 0, 0},
226
261
  {"flush-logs", 'F', "Flush logs file in server before starting dump. "
227
 
    "Note that if you dump many databases at once (using the option "
228
 
      "--databases= or --all-databases), the logs will be flushed for "
229
 
      "each database dumped. The exception is when using --lock-all-tables "
230
 
      "in this case the logs will be flushed only once, corresponding "
231
 
      "to the moment all tables are locked. So if you want your dump and "
232
 
      "the log flush to happen at the same exact moment you should use "
233
 
      "--lock-all-tables or --flush-logs",
234
 
    (char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
235
 
    0, 0},
 
262
   "Note that if you dump many databases at once (using the option "
 
263
   "--databases= or --all-databases), the logs will be flushed for "
 
264
   "each database dumped. The exception is when using --lock-all-tables "
 
265
   "or --master-data: "
 
266
   "in this case the logs will be flushed only once, corresponding "
 
267
   "to the moment all tables are locked. So if you want your dump and "
 
268
   "the log flush to happen at the same exact moment you should use "
 
269
   "--lock-all-tables or --master-data with --flush-logs",
 
270
   (char**) &flush_logs, (char**) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
271
   0, 0},
236
272
  {"force", 'f', "Continue even if we get an sql-error.",
237
 
    (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
238
 
    0, 0, 0, 0, 0, 0},
 
273
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG,
 
274
   0, 0, 0, 0, 0, 0},
239
275
  {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
240
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
 
276
   NO_ARG, 0, 0, 0, 0, 0, 0},
241
277
  {"hex-blob", OPT_HEXBLOB, "Dump binary strings (BINARY, "
242
278
    "VARBINARY, BLOB) in hexadecimal format.",
243
 
    (char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
279
   (char**) &opt_hex_blob, (char**) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
244
280
  {"host", 'h', "Connect to host.", (char**) &current_host,
245
 
    (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
281
   (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
246
282
  {"ignore-table", OPT_IGNORE_TABLE,
247
 
    "Do not dump the specified table. To specify more than one table to ignore, "
248
 
      "use the directive multiple times, once for each table.  Each table must "
249
 
      "be specified with both database and table names, e.g. --ignore-table=database.table",
250
 
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
283
   "Do not dump the specified table. To specify more than one table to ignore, "
 
284
   "use the directive multiple times, once for each table.  Each table must "
 
285
   "be specified with both database and table names, e.g. --ignore-table=database.table",
 
286
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
287
  {"include-master-host-port", OPT_DRIZZLEDUMP_INCLUDE_MASTER_HOST_PORT,
 
288
   "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in dump produced with --dump-slave.",
 
289
   (char**) &opt_include_master_host_port,
 
290
   (char**) &opt_include_master_host_port,
 
291
   0, GET_BOOL, NO_ARG,
 
292
   0, 0, 0, 0, 0, 0},
251
293
  {"insert-ignore", OPT_INSERT_IGNORE, "Insert rows with INSERT IGNORE.",
252
 
    (char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
253
 
    0, 0},
 
294
   (char**) &opt_ignore, (char**) &opt_ignore, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
295
   0, 0},
254
296
  {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...",
255
 
    (char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
256
 
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
297
   (char**) &lines_terminated, (char**) &lines_terminated, 0, GET_STR,
 
298
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
257
299
  {"lock-all-tables", 'x', "Locks all tables across all databases. This "
258
 
    "is achieved by taking a global read lock for the duration of the whole "
259
 
      "dump. Automatically turns --single-transaction and --lock-tables off.",
260
 
    (char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
261
 
    0, 0, 0, 0, 0, 0},
262
 
  {"mysql", 'm', N_("Use MySQL Protocol."),
263
 
    (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
264
 
    0, 0, 0},
 
300
   "is achieved by taking a global read lock for the duration of the whole "
 
301
   "dump. Automatically turns --single-transaction and --lock-tables off.",
 
302
   (char**) &opt_lock_all_tables, (char**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG,
 
303
   0, 0, 0, 0, 0, 0},
 
304
  {"lock-tables", 'l', "Lock all tables for read.", (char**) &lock_tables,
 
305
   (char**) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
306
  {"master-data", OPT_MASTER_DATA,
 
307
   "This causes the binary log position and filename to be appended to the "
 
308
   "output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
 
309
   " to 2, that command will be prefixed with a comment symbol. "
 
310
   "This option will turn --lock-all-tables on, unless "
 
311
   "--single-transaction is specified too (in which case a "
 
312
   "global read lock is only taken a short time at the beginning of the dump "
 
313
   "- don't forget to read about --single-transaction below). In all cases "
 
314
   "any action on logs will happen at the exact moment of the dump."
 
315
   "Option automatically turns --lock-tables off.",
 
316
   (char**) &opt_master_data, (char**) &opt_master_data, 0,
 
317
   GET_UINT, OPT_ARG, 0, 0, DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL, 0, 0, 0},
265
318
  {"no-autocommit", OPT_AUTOCOMMIT,
266
 
    "Wrap tables with autocommit/commit statements.",
267
 
    (char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
268
 
    0, 0, 0, 0, 0, 0},
 
319
   "Wrap tables with autocommit/commit statements.",
 
320
   (char**) &opt_autocommit, (char**) &opt_autocommit, 0, GET_BOOL, NO_ARG,
 
321
   0, 0, 0, 0, 0, 0},
269
322
  {"no-create-db", 'n',
270
 
    "'CREATE DATABASE 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.}.",
271
 
    (char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
272
 
    0, 0, 0, 0},
 
323
   "'CREATE DATABASE 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.}.",
 
324
   (char**) &opt_create_db, (char**) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0,
 
325
   0, 0, 0, 0},
273
326
  {"no-create-info", 't', "Don't write table creation info.",
274
 
    (char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
275
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
 
327
   (char**) &opt_no_create_info, (char**) &opt_no_create_info, 0, GET_BOOL,
 
328
   NO_ARG, 0, 0, 0, 0, 0, 0},
276
329
  {"no-data", 'd', "No row information.", (char**) &opt_no_data,
277
 
    (char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
330
   (char**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
278
331
  {"no-set-names", 'N',
279
 
    "Deprecated. Use --skip-set-charset instead.",
280
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
332
   "Deprecated. Use --skip-set-charset instead.",
 
333
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
281
334
  {"opt", OPT_OPTIMIZE,
282
 
    "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.",
283
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
335
   "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.",
 
336
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
284
337
  {"order-by-primary", OPT_ORDER_BY_PRIMARY,
285
 
    "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.",
286
 
    (char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
338
   "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.",
 
339
   (char**) &opt_order_by_primary, (char**) &opt_order_by_primary, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
287
340
  {"password", 'P',
288
 
    "Password to use when connecting to server. If password is not given it's solicited on the tty.",
289
 
    0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
341
   "Password to use when connecting to server. If password is not given it's solicited on the tty.",
 
342
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
290
343
  {"port", 'p', "Port number to use for connection.", 
291
 
    0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
344
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
292
345
  {"quick", 'q', "Don't buffer query, dump directly to stdout.",
293
 
    (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
346
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
294
347
  {"quote-names",'Q', "Quote table and column names with backticks (`).",
295
 
    (char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
296
 
    0, 0},
 
348
   (char**) &opt_quoted, (char**) &opt_quoted, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
 
349
   0, 0},
297
350
  {"replace", OPT_DRIZZLE_REPLACE_INTO, "Use REPLACE INTO instead of INSERT INTO.",
298
 
    (char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
299
 
    0, 0},
 
351
   (char**) &opt_replace_into, (char**) &opt_replace_into, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
352
   0, 0},
300
353
  {"result-file", 'r',
301
 
    "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).",
302
 
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
354
   "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).",
 
355
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
303
356
  {"routines", 'R', "Dump stored routines (functions and procedures).",
304
 
    (char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
305
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
 
357
     (char**) &opt_routines, (char**) &opt_routines, 0, GET_BOOL,
 
358
     NO_ARG, 0, 0, 0, 0, 0, 0},
 
359
  /*
 
360
    Note that the combination --single-transaction --master-data
 
361
    will give bullet-proof binlog position only if server >=4.1.3. That's the
 
362
    old "FLUSH TABLES WITH READ LOCK does not block commit" fixed bug.
 
363
  */
306
364
  {"single-transaction", OPT_TRANSACTION,
307
 
    "Creates a consistent snapshot by dumping all tables in a single "
308
 
      "transaction. Works ONLY for tables stored in storage engines which "
309
 
      "support multiversioning (currently only InnoDB does); the dump is NOT "
310
 
      "guaranteed to be consistent for other storage engines. "
311
 
      "While a --single-transaction dump is in process, to ensure a valid "
312
 
      "dump file (correct table contents), no other "
313
 
      "connection should use the following statements: ALTER TABLE, DROP "
314
 
      "TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
315
 
      "isolated from them. Option automatically turns off --lock-tables.",
316
 
    (char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
317
 
    GET_BOOL, NO_ARG,  0, 0, 0, 0, 0, 0},
 
365
   "Creates a consistent snapshot by dumping all tables in a single "
 
366
   "transaction. Works ONLY for tables stored in storage engines which "
 
367
   "support multiversioning (currently only InnoDB does); the dump is NOT "
 
368
   "guaranteed to be consistent for other storage engines. "
 
369
   "While a --single-transaction dump is in process, to ensure a valid "
 
370
   "dump file (correct table contents and binary log position), no other "
 
371
   "connection should use the following statements: ALTER TABLE, DROP "
 
372
   "TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not "
 
373
   "isolated from them. Option automatically turns off --lock-tables.",
 
374
   (char**) &opt_single_transaction, (char**) &opt_single_transaction, 0,
 
375
   GET_BOOL, NO_ARG,  0, 0, 0, 0, 0, 0},
318
376
  {"dump-date", OPT_DUMP_DATE, "Put a dump date to the end of the output.",
319
 
    (char**) &opt_dump_date, (char**) &opt_dump_date, 0,
320
 
    GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
377
   (char**) &opt_dump_date, (char**) &opt_dump_date, 0,
 
378
   GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
321
379
  {"skip-opt", OPT_SKIP_OPTIMIZATION,
322
 
    "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
323
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
380
   "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
 
381
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
324
382
  {"tab",'T',
325
 
    "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if drizzledump is run on the same machine as the drizzled daemon.",
326
 
    (char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
383
   "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.",
 
384
   (char**) &path, (char**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
327
385
  {"tables", OPT_TABLES, "Overrides option --databases (-B).",
328
 
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
386
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
329
387
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of rows before each output progress report (requires --verbose)."),
330
 
    (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
331
 
    10000, 0, 0, 0, 0, 0},
 
388
   (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
 
389
   10000, 0, 0, 0, 0, 0},
 
390
#ifndef DONT_ALLOW_USER_CHANGE
332
391
  {"user", 'u', "User for login if not current user.",
333
 
    (char**) &current_user, (char**) &current_user, 0, GET_STR, REQUIRED_ARG,
334
 
    0, 0, 0, 0, 0, 0},
 
392
   (char**) &current_user, (char**) &current_user, 0, GET_STR, REQUIRED_ARG,
 
393
   0, 0, 0, 0, 0, 0},
 
394
#endif
335
395
  {"verbose", 'v', "Print info about the various stages.",
336
 
    (char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
396
   (char**) &verbose, (char**) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
337
397
  {"version",'V', "Output version information and exit.", 0, 0, 0,
338
 
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
398
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
339
399
  {"where", 'w', "Dump only selected records; QUOTES mandatory!",
340
 
    (char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
400
   (char**) &where, (char**) &where, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
341
401
  {"xml", 'X', "Dump a database as well formed XML.", 0, 0, 0, GET_NO_ARG,
342
 
    NO_ARG, 0, 0, 0, 0, 0, 0},
 
402
   NO_ARG, 0, 0, 0, 0, 0, 0},
343
403
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
344
404
};
345
405
 
368
428
  Print the supplied message if in verbose mode
369
429
 
370
430
  SYNOPSIS
371
 
  verbose_msg()
372
 
  fmt   format specifier
373
 
  ...   variable number of parameters
 
431
    verbose_msg()
 
432
    fmt   format specifier
 
433
    ...   variable number of parameters
374
434
*/
375
435
static void verbose_msg(const char *fmt, ...)
376
436
{
383
443
  va_start(args, fmt);
384
444
  vfprintf(stderr, fmt, args);
385
445
  va_end(args);
 
446
 
 
447
  return;
386
448
}
387
449
 
388
450
/*
389
451
  exit with message if ferror(file)
390
452
 
391
453
  SYNOPSIS
392
 
  check_io()
393
 
  file        - checked file
 
454
    check_io()
 
455
    file        - checked file
394
456
*/
395
457
 
396
458
static void check_io(FILE *file)
401
463
 
402
464
static void print_version(void)
403
465
{
404
 
  printf(_("%s  Drizzle %s libdrizzle %s, for %s-%s (%s)\n"), internal::my_progname,
405
 
         VERSION, drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
 
466
  printf(_("%s  Ver %s Distrib %s, for %s (%s)\n"),my_progname,DUMP_VERSION,
 
467
         drizzle_version(),SYSTEM_TYPE,MACHINE_TYPE);
406
468
} /* print_version */
407
469
 
408
470
 
409
471
static void short_usage_sub(void)
410
472
{
411
 
  printf(_("Usage: %s [OPTIONS] database [tables]\n"), internal::my_progname);
 
473
  printf(_("Usage: %s [OPTIONS] database [tables]\n"), my_progname);
412
474
  printf(_("OR     %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
413
 
         internal::my_progname);
414
 
  printf(_("OR     %s [OPTIONS] --all-databases [OPTIONS]\n"), internal::my_progname);
 
475
         my_progname);
 
476
  printf(_("OR     %s [OPTIONS] --all-databases [OPTIONS]\n"), my_progname);
415
477
}
416
478
 
417
479
 
418
480
static void usage(void)
419
481
{
420
482
  print_version();
421
 
  puts("");
 
483
  puts(_("By Igor Romanenko, Monty, Jani & Sinisa"));
422
484
  puts(_("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"));
423
 
  puts(_("Dumps definitions and data from a Drizzle database server"));
 
485
  puts(_("Dumping definition and data DRIZZLE database or table"));
424
486
  short_usage_sub();
425
 
  internal::print_defaults("drizzle",load_default_groups);
 
487
  print_defaults("drizzle",load_default_groups);
426
488
  my_print_help(my_long_options);
427
489
  my_print_variables(my_long_options);
428
490
} /* usage */
431
493
static void short_usage(void)
432
494
{
433
495
  short_usage_sub();
434
 
  printf(_("For more options, use %s --help\n"), internal::my_progname);
 
496
  printf(_("For more options, use %s --help\n"), my_progname);
435
497
}
436
498
 
437
499
static void write_header(FILE *sql_file, char *db_name)
441
503
    fputs("<?xml version=\"1.0\"?>\n", sql_file);
442
504
    /*
443
505
      Schema reference.  Allows use of xsi:nil for NULL values and
444
 
xsi:type to define an element's data type.
 
506
      xsi:type to define an element's data type.
445
507
    */
446
508
    fputs("<drizzledump ", sql_file);
447
509
    fputs("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"",
454
516
    if (opt_comments)
455
517
    {
456
518
      fprintf(sql_file,
457
 
              "-- drizzledump %s libdrizzle %s, for %s-%s (%s)\n--\n",
458
 
              VERSION, drizzle_version(), HOST_VENDOR, HOST_OS, HOST_CPU);
 
519
              "-- DRIZZLE dump %s  Distrib %s, for %s (%s)\n--\n",
 
520
              DUMP_VERSION, drizzle_version(), SYSTEM_TYPE, MACHINE_TYPE);
459
521
      fprintf(sql_file, "-- Host: %s    Database: %s\n",
460
522
              current_host ? current_host : "localhost", db_name ? db_name :
461
523
              "");
466
528
    }
467
529
    if (opt_set_charset)
468
530
      fprintf(sql_file,
469
 
              "\nSET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;\n");
 
531
"\nSET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;"
 
532
"\nSET NAMES %s;\n",default_charset);
470
533
 
471
 
    if (path == NULL)
 
534
    if (!path)
472
535
    {
473
 
      fprintf(md_result_file,"SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;\nSET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;\n");
 
536
      fprintf(md_result_file,"\
 
537
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;\n\
 
538
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;\n\
 
539
");
474
540
    }
475
541
    check_io(sql_file);
476
542
  }
484
550
    fputs("</drizzledump>\n", sql_file);
485
551
    check_io(sql_file);
486
552
  }
487
 
  else if (opt_compact == false)
 
553
  else if (!opt_compact)
488
554
  {
489
 
    if (path == NULL)
 
555
    if (!path)
490
556
    {
491
 
      fprintf(md_result_file,"SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;\nSET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;\n");
 
557
      fprintf(md_result_file,"\
 
558
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;\n\
 
559
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;\n");
492
560
    }
493
561
    if (opt_set_charset)
494
562
      fprintf(sql_file, "SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;\n");
497
565
      if (opt_dump_date)
498
566
      {
499
567
        char time_str[20];
500
 
        internal::get_date(time_str, GETDATE_DATE_TIME, 0);
 
568
        get_date(time_str, GETDATE_DATE_TIME, 0);
501
569
        fprintf(sql_file, "-- Dump completed on %s\n",
502
570
                time_str);
503
571
      }
509
577
} /* write_footer */
510
578
 
511
579
 
512
 
static int get_one_option(int optid, const struct option *, char *argument)
 
580
static void free_table_ent(char *key)
 
581
{
 
582
  free(key);
 
583
}
 
584
 
 
585
 
 
586
static unsigned char* get_table_key(const char *entry, size_t *length, bool)
 
587
{
 
588
  *length= strlen(entry);
 
589
  return (unsigned char*) entry;
 
590
}
 
591
 
 
592
 
 
593
extern "C"
 
594
bool get_one_option(int optid, const struct my_option *, char *argument)
513
595
{
514
596
  char *endchar= NULL;
515
597
  uint64_t temp_drizzle_port= 0;
521
603
    if (strlen(endchar) != 0)
522
604
    {
523
605
      fprintf(stderr, _("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead.\n"));
524
 
      return EXIT_ARGUMENT_INVALID;
 
606
      exit(EX_USAGE);
525
607
    }
526
608
    /* If the port number is > 65535 it is not a valid port
527
 
     *        This also helps with potential data loss casting unsigned long to a
528
 
     *               uint32_t. */
 
609
 *        This also helps with potential data loss casting unsigned long to a
 
610
 *               uint32_t. */
529
611
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
530
612
    {
531
613
      fprintf(stderr, _("Value supplied for port is not valid.\n"));
532
 
      return EXIT_ARGUMENT_INVALID;
 
614
      exit(EX_USAGE);
533
615
    }
534
616
    else
535
617
    {
546
628
      if (opt_password == NULL)
547
629
      {
548
630
        fprintf(stderr, _("Memory allocation error while copying password. "
549
 
                          "Aborting.\n"));
550
 
        return EXIT_OUT_OF_MEMORY;
 
631
                        "Aborting.\n"));
 
632
        exit(ENOMEM);
551
633
      }
552
634
      while (*argument)
553
635
      {
584
666
        a crash even if the input destination buffer is large enough
585
667
        to hold the output.
586
668
      */
587
 
      fprintf(stderr, _("Input filename too long: %s"), argument);
588
 
      return EXIT_ARGUMENT_INVALID;
 
669
      die(EX_USAGE, _("Input filename too long: %s"), argument);
589
670
    }
590
671
 
591
672
    break;
592
673
  case 'V': print_version(); exit(0);
593
674
  case 'X':
594
 
            opt_xml= 1;
595
 
            extended_insert= opt_drop=
596
 
              opt_disable_keys= opt_autocommit= opt_create_db= 0;
597
 
            break;
 
675
    opt_xml= 1;
 
676
    extended_insert= opt_drop= opt_lock=
 
677
      opt_disable_keys= opt_autocommit= opt_create_db= 0;
 
678
    break;
598
679
  case 'I':
599
680
  case '?':
600
 
            usage();
601
 
            exit(0);
 
681
    usage();
 
682
    exit(0);
 
683
  case (int) OPT_MASTER_DATA:
 
684
    if (!argument) /* work like in old versions */
 
685
      opt_master_data= DRIZZLE_OPT_MASTER_DATA_EFFECTIVE_SQL;
 
686
    break;
 
687
  case (int) OPT_DRIZZLEDUMP_SLAVE_DATA:
 
688
    if (!argument) /* work like in old versions */
 
689
      opt_slave_data= DRIZZLE_OPT_SLAVE_DATA_EFFECTIVE_SQL;
 
690
    break;
602
691
  case (int) OPT_OPTIMIZE:
603
 
            extended_insert= opt_drop= quick= create_options=
604
 
              opt_disable_keys= opt_set_charset= 1;
605
 
            break;
 
692
    extended_insert= opt_drop= opt_lock= quick= create_options=
 
693
      opt_disable_keys= lock_tables= opt_set_charset= 1;
 
694
    break;
606
695
  case (int) OPT_SKIP_OPTIMIZATION:
607
 
            extended_insert= opt_drop= quick= create_options=
608
 
              opt_disable_keys= opt_set_charset= 0;
609
 
            break;
 
696
    extended_insert= opt_drop= opt_lock= quick= create_options=
 
697
      opt_disable_keys= lock_tables= opt_set_charset= 0;
 
698
    break;
610
699
  case (int) OPT_COMPACT:
611
 
            if (opt_compact)
612
 
            {
613
 
              opt_comments= opt_drop= opt_disable_keys= 0;
614
 
              opt_set_charset= 0;
615
 
            }
 
700
  if (opt_compact)
 
701
  {
 
702
    opt_comments= opt_drop= opt_disable_keys= opt_lock= 0;
 
703
    opt_set_charset= 0;
 
704
  }
616
705
  case (int) OPT_TABLES:
617
 
            opt_databases=0;
618
 
            break;
 
706
    opt_databases=0;
 
707
    break;
619
708
  case (int) OPT_IGNORE_TABLE:
620
 
            {
621
 
              if (!strchr(argument, '.'))
622
 
              {
623
 
                fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
624
 
                return EXIT_ARGUMENT_INVALID;
625
 
              }
626
 
              string tmpptr(argument);
627
 
              ignore_table.insert(tmpptr); 
628
 
              break;
629
 
            }
 
709
  {
 
710
    if (!strchr(argument, '.'))
 
711
    {
 
712
      fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
 
713
      exit(1);
 
714
    }
 
715
    char * tmpptr= strdup(argument);
 
716
    if (!(tmpptr) || my_hash_insert(&ignore_table, (unsigned char*)tmpptr))
 
717
      exit(EX_EOM);
 
718
    break;
 
719
  }
630
720
  case (int) OPT_COMPATIBLE:
631
 
            {
632
 
              char buff[255];
633
 
              char *end= compatible_mode_normal_str;
634
 
              uint32_t i;
635
 
              uint32_t mode;
636
 
              uint32_t error_len;
 
721
    {
 
722
      char buff[255];
 
723
      char *end= compatible_mode_normal_str;
 
724
      uint32_t i;
 
725
      uint32_t mode;
 
726
      uint32_t error_len;
637
727
 
638
 
              opt_quoted= 1;
639
 
              opt_set_charset= 0;
640
 
              opt_compatible_mode_str= argument;
641
 
              opt_compatible_mode= find_set(&compatible_mode_typelib,
642
 
                                            argument, strlen(argument),
643
 
                                            &err_ptr, &error_len);
644
 
              if (error_len)
645
 
              {
646
 
                strncpy(buff, err_ptr, min((uint32_t)sizeof(buff), error_len+1));
647
 
                fprintf(stderr, _("Invalid mode to --compatible: %s\n"), buff);
648
 
                return EXIT_ARGUMENT_INVALID;
649
 
              }
650
 
              mode= opt_compatible_mode;
651
 
              for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
652
 
              {
653
 
                if (mode & 1)
654
 
                {
655
 
                  uint32_t len = strlen(compatible_mode_names[i]);
656
 
                  end= strcpy(end, compatible_mode_names[i]) + len;
657
 
                  end= strcpy(end, ",")+1;
658
 
                }
659
 
              }
660
 
              if (end!=compatible_mode_normal_str)
661
 
                end[-1]= 0;
662
 
            }
 
728
      opt_quoted= 1;
 
729
      opt_set_charset= 0;
 
730
      opt_compatible_mode_str= argument;
 
731
      opt_compatible_mode= find_set(&compatible_mode_typelib,
 
732
                                    argument, strlen(argument),
 
733
                                    &err_ptr, &error_len);
 
734
      if (error_len)
 
735
      {
 
736
        strncpy(buff, err_ptr, min((uint32_t)sizeof(buff), error_len));
 
737
        fprintf(stderr, _("Invalid mode to --compatible: %s\n"), buff);
 
738
        exit(1);
 
739
      }
 
740
      mode= opt_compatible_mode;
 
741
      for (i= 0, mode= opt_compatible_mode; mode; mode>>= 1, i++)
 
742
      {
 
743
        if (mode & 1)
 
744
        {
 
745
          uint32_t len = strlen(compatible_mode_names[i]);
 
746
          end= strcpy(end, compatible_mode_names[i]) + len;
 
747
          end= strcpy(end, ",")+1;
 
748
        }
 
749
      }
 
750
      if (end!=compatible_mode_normal_str)
 
751
        end[-1]= 0;
 
752
      /*
 
753
        Set charset to the default compiled value if it hasn't
 
754
        been reset yet by --default-character-set=xxx.
 
755
      */
 
756
      if (default_charset == drizzle_universal_client_charset)
 
757
        default_charset= (char*) DRIZZLE_DEFAULT_CHARSET_NAME;
 
758
      break;
 
759
    }
663
760
  }
664
761
  return 0;
665
762
}
669
766
  int ho_error;
670
767
 
671
768
  md_result_file= stdout;
672
 
  internal::load_defaults("drizzle",load_default_groups,argc,argv);
 
769
  load_defaults("drizzle",load_default_groups,argc,argv);
673
770
  defaults_argv= *argv;
674
771
 
 
772
  if (hash_init(&ignore_table, charset_info, 16, 0, 0,
 
773
                (hash_get_key) get_table_key,
 
774
                (hash_free_key) free_table_ent, 0))
 
775
    return(EX_EOM);
 
776
 
675
777
  if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
676
778
    return(ho_error);
677
779
 
 
780
  if (debug_info_flag)
 
781
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
782
  if (debug_check_flag)
 
783
    my_end_arg= MY_CHECK_ERROR;
 
784
 
 
785
  if (opt_delayed)
 
786
    opt_lock=0;                         /* Can't have lock with delayed */
678
787
  if (!path && (enclosed || opt_enclosed || escaped || lines_terminated ||
679
788
                fields_terminated))
680
789
  {
681
790
    fprintf(stderr,
682
 
            _("%s: You must use option --tab with --fields-...\n"), internal::my_progname);
 
791
            _("%s: You must use option --tab with --fields-...\n"), my_progname);
683
792
    return(EX_USAGE);
684
793
  }
685
794
 
 
795
  /* We don't delete master logs if slave data option */
 
796
  if (opt_slave_data)
 
797
  {
 
798
    opt_lock_all_tables= !opt_single_transaction;
 
799
    opt_master_data= 0;
 
800
    opt_delete_master_logs= 0;
 
801
  }
 
802
 
 
803
  /* Ensure consistency of the set of binlog & locking options */
 
804
  if (opt_delete_master_logs && !opt_master_data)
 
805
    opt_master_data= DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL;
686
806
  if (opt_single_transaction && opt_lock_all_tables)
687
807
  {
688
808
    fprintf(stderr, _("%s: You can't use --single-transaction and "
689
 
                      "--lock-all-tables at the same time.\n"), internal::my_progname);
 
809
            "--lock-all-tables at the same time.\n"), my_progname);
690
810
    return(EX_USAGE);
691
811
  }
 
812
  if (opt_master_data)
 
813
  {
 
814
    opt_lock_all_tables= !opt_single_transaction;
 
815
    opt_slave_data= 0;
 
816
  }
 
817
  if (opt_single_transaction || opt_lock_all_tables)
 
818
    lock_tables= 0;
692
819
  if (enclosed && opt_enclosed)
693
820
  {
694
 
    fprintf(stderr, _("%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n"), internal::my_progname);
 
821
    fprintf(stderr, _("%s: You can't use ..enclosed.. and ..optionally-enclosed.. at the same time.\n"), my_progname);
695
822
    return(EX_USAGE);
696
823
  }
697
824
  if ((opt_databases || opt_alldbs) && path)
698
825
  {
699
826
    fprintf(stderr,
700
827
            _("%s: --databases or --all-databases can't be used with --tab.\n"),
701
 
            internal::my_progname);
 
828
            my_progname);
702
829
    return(EX_USAGE);
703
830
  }
 
831
  if (strcmp(default_charset, charset_info->csname) &&
 
832
      !(charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY)))
 
833
    exit(1);
704
834
  if ((*argc < 1 && !opt_alldbs) || (*argc > 0 && opt_alldbs))
705
835
  {
706
836
    short_usage();
713
843
 
714
844
 
715
845
/*
716
 
 ** DB_error -- prints DRIZZLE error message and exits the program.
 
846
** DB_error -- prints DRIZZLE error message and exits the program.
717
847
*/
718
848
static void DB_error(drizzle_result_st *res, drizzle_return_t ret,
719
849
                     const char *when)
720
850
{
721
851
  if (ret == DRIZZLE_RETURN_ERROR_CODE)
722
852
  {
723
 
    maybe_die(EX_DRIZZLEERR, _("Got error: %s (%d) %s"),
724
 
              drizzle_result_error(res),
725
 
              drizzle_result_error_code(res),
726
 
              when);
 
853
    maybe_die(EX_DRIZZLEERR, _("Got error: %s %s"),
 
854
              drizzle_result_error_code(res), when);
727
855
    drizzle_result_free(res);
728
856
  }
729
857
  else
730
 
    maybe_die(EX_DRIZZLEERR, _("Got error: %d %s"), ret, when);
 
858
    maybe_die(EX_DRIZZLEERR, _("Got error: %s %s"), ret, when);
731
859
 
732
860
  return;
733
861
}
738
866
  Prints out an error message and kills the process.
739
867
 
740
868
  SYNOPSIS
741
 
  die()
742
 
  error_num   - process return value
743
 
  fmt_reason  - a format string for use by vsnprintf.
744
 
  ...         - variable arguments for above fmt_reason string
 
869
    die()
 
870
    error_num   - process return value
 
871
    fmt_reason  - a format string for use by vsnprintf.
 
872
    ...         - variable arguments for above fmt_reason string
745
873
 
746
874
  DESCRIPTION
747
 
  This call prints out the formatted error message to stderr and then
748
 
  terminates the process.
 
875
    This call prints out the formatted error message to stderr and then
 
876
    terminates the process.
749
877
*/
750
878
static void die(int error_num, const char* fmt_reason, ...)
751
879
{
755
883
  vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
756
884
  va_end(args);
757
885
 
758
 
  fprintf(stderr, "%s: %s\n", internal::my_progname, buffer);
 
886
  fprintf(stderr, "%s: %s\n", my_progname, buffer);
759
887
  fflush(stderr);
760
888
 
761
889
  ignore_errors= 0; /* force the exit */
767
895
  Prints out an error message and maybe kills the process.
768
896
 
769
897
  SYNOPSIS
770
 
  maybe_die()
771
 
  error_num   - process return value
772
 
  fmt_reason  - a format string for use by vsnprintf.
773
 
  ...         - variable arguments for above fmt_reason string
 
898
    maybe_die()
 
899
    error_num   - process return value
 
900
    fmt_reason  - a format string for use by vsnprintf.
 
901
    ...         - variable arguments for above fmt_reason string
774
902
 
775
903
  DESCRIPTION
776
 
  This call prints out the formatted error message to stderr and then
777
 
  terminates the process, unless the --force command line option is used.
 
904
    This call prints out the formatted error message to stderr and then
 
905
    terminates the process, unless the --force command line option is used.
778
906
 
779
 
  This call should be used for non-fatal errors (such as database
780
 
  errors) that the code may still be able to continue to the next unit
781
 
  of work.
 
907
    This call should be used for non-fatal errors (such as database
 
908
    errors) that the code may still be able to continue to the next unit
 
909
    of work.
782
910
 
783
911
*/
784
912
static void maybe_die(int error_num, const char* fmt_reason, ...)
789
917
  vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
790
918
  va_end(args);
791
919
 
792
 
  fprintf(stderr, "%s: %s\n", internal::my_progname, buffer);
 
920
  fprintf(stderr, "%s: %s\n", my_progname, buffer);
793
921
  fflush(stderr);
794
922
 
795
923
  maybe_exit(error_num);
802
930
  some.
803
931
 
804
932
  SYNOPSIS
805
 
  drizzleclient_query_with_error_report()
806
 
  drizzle_con       connection to use
807
 
  res             if non zero, result will be put there with
808
 
  drizzleclient_store_result()
809
 
  query           query to send to server
 
933
    drizzleclient_query_with_error_report()
 
934
    drizzle_con       connection to use
 
935
    res             if non zero, result will be put there with
 
936
                    drizzleclient_store_result()
 
937
    query           query to send to server
810
938
 
811
939
  RETURN VALUES
812
 
  0               query sending and (if res!=0) result reading went ok
813
 
  1               error
 
940
    0               query sending and (if res!=0) result reading went ok
 
941
    1               error
814
942
*/
815
943
 
816
944
static int drizzleclient_query_with_error_report(drizzle_con_st *con,
857
985
  Open a new .sql file to dump the table or view into
858
986
 
859
987
  SYNOPSIS
860
 
  open_sql_file_for_table
861
 
  name      name of the table or view
 
988
    open_sql_file_for_table
 
989
    name      name of the table or view
862
990
 
863
991
  RETURN VALUES
864
 
  0        Failed to open file
865
 
  > 0      Handle of the open file
 
992
    0        Failed to open file
 
993
    > 0      Handle of the open file
866
994
*/
867
995
static FILE* open_sql_file_for_table(const char* table)
868
996
{
869
997
  FILE* res;
870
998
  char filename[FN_REFLEN], tmp_path[FN_REFLEN];
871
 
  internal::convert_dirname(tmp_path,path,NULL);
872
 
  res= fopen(internal::fn_format(filename, table, tmp_path, ".sql", 4), "w");
 
999
  convert_dirname(tmp_path,path,NULL);
 
1000
  res= fopen(fn_format(filename, table, tmp_path, ".sql", 4), "w");
873
1001
 
874
1002
  return res;
875
1003
}
880
1008
  if (md_result_file && md_result_file != stdout)
881
1009
    fclose(md_result_file);
882
1010
  free(opt_password);
 
1011
  if (hash_inited(&ignore_table))
 
1012
    hash_free(&ignore_table);
883
1013
  if (defaults_argv)
884
 
    internal::free_defaults(defaults_argv);
885
 
  internal::my_end();
 
1014
    free_defaults(defaults_argv);
 
1015
  my_end(my_end_arg);
886
1016
}
887
1017
 
888
1018
 
912
1042
  drizzle_con_create(&drizzle, &dcon);
913
1043
  drizzle_con_set_tcp(&dcon, host, opt_drizzle_port);
914
1044
  drizzle_con_set_auth(&dcon, user, passwd);
915
 
  if (opt_mysql)
916
 
    drizzle_con_add_options(&dcon, DRIZZLE_CON_MYSQL);
917
1045
  ret= drizzle_con_connect(&dcon);
918
1046
  if (ret != DRIZZLE_RETURN_OK)
919
1047
  {
926
1054
 
927
1055
 
928
1056
/*
929
 
 ** dbDisconnect -- disconnects from the host.
 
1057
** dbDisconnect -- disconnects from the host.
930
1058
*/
931
1059
static void dbDisconnect(char *host)
932
1060
{
982
1110
static char *quote_name(const char *name, char *buff, bool force)
983
1111
{
984
1112
  char *to= buff;
985
 
  char qtype= '`';
 
1113
  char qtype= (opt_compatible_mode & MASK_ANSI_QUOTES) ? '\"' : '`';
986
1114
 
987
1115
  if (!force && !opt_quoted && !test_if_special_chars(name))
988
1116
    return (char*) name;
1003
1131
  Quote a table name so it can be used in "SHOW TABLES LIKE <tabname>"
1004
1132
 
1005
1133
  SYNOPSIS
1006
 
  quote_for_like()
1007
 
  name     name of the table
1008
 
  buff     quoted name of the table
 
1134
    quote_for_like()
 
1135
    name     name of the table
 
1136
    buff     quoted name of the table
1009
1137
 
1010
1138
  DESCRIPTION
1011
 
  Quote \, _, ' and % characters
1012
 
 
1013
 
Note: Because DRIZZLE uses the C escape syntax in strings
1014
 
(for example, '\n' to represent newline), you must double
1015
 
any '\' that you use in your LIKE  strings. For example, to
1016
 
search for '\n', specify it as '\\n'. To search for '\', specify
1017
 
it as '\\\\' (the backslashes are stripped once by the parser
1018
 
and another time when the pattern match is done, leaving a
1019
 
single backslash to be matched).
1020
 
 
1021
 
Example: "t\1" => "t\\\\1"
 
1139
    Quote \, _, ' and % characters
 
1140
 
 
1141
    Note: Because DRIZZLE uses the C escape syntax in strings
 
1142
    (for example, '\n' to represent newline), you must double
 
1143
    any '\' that you use in your LIKE  strings. For example, to
 
1144
    search for '\n', specify it as '\\n'. To search for '\', specify
 
1145
    it as '\\\\' (the backslashes are stripped once by the parser
 
1146
    and another time when the pattern match is done, leaving a
 
1147
    single backslash to be matched).
 
1148
 
 
1149
    Example: "t\1" => "t\\\\1"
1022
1150
 
1023
1151
*/
1024
1152
static char *quote_for_like(const char *name, char *buff)
1047
1175
  Quote and print a string.
1048
1176
 
1049
1177
  SYNOPSIS
1050
 
  print_quoted_xml()
1051
 
  xml_file    - output file
1052
 
  str         - string to print
1053
 
  len         - its length
 
1178
    print_quoted_xml()
 
1179
    xml_file    - output file
 
1180
    str         - string to print
 
1181
    len         - its length
1054
1182
 
1055
1183
  DESCRIPTION
1056
 
  Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
 
1184
    Quote '<' '>' '&' '\"' chars and print a string to the xml_file.
1057
1185
*/
1058
1186
 
1059
1187
static void print_quoted_xml(FILE *xml_file, const char *str, uint32_t len)
1072
1200
    case '&':
1073
1201
      fputs("&amp;", xml_file);
1074
1202
      break;
1075
 
      case '\"':
1076
 
        fputs("&quot;", xml_file);
 
1203
    case '\"':
 
1204
      fputs("&quot;", xml_file);
1077
1205
      break;
1078
1206
    default:
1079
1207
      fputc(*str, xml_file);
1088
1216
  Print xml tag. Optionally add attribute(s).
1089
1217
 
1090
1218
  SYNOPSIS
1091
 
  print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
1092
 
  ..., attribute_name_n, attribute_value_n, NULL)
1093
 
  xml_file              - output file
1094
 
  sbeg                  - line beginning
1095
 
  line_end              - line ending
1096
 
  tag_name              - XML tag name.
1097
 
  first_attribute_name  - tag and first attribute
1098
 
  first_attribute_value - (Implied) value of first attribute
1099
 
  attribute_name_n      - attribute n
1100
 
  attribute_value_n     - value of attribute n
 
1219
    print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
 
1220
                    ..., attribute_name_n, attribute_value_n, NULL)
 
1221
    xml_file              - output file
 
1222
    sbeg                  - line beginning
 
1223
    line_end              - line ending
 
1224
    tag_name              - XML tag name.
 
1225
    first_attribute_name  - tag and first attribute
 
1226
    first_attribute_value - (Implied) value of first attribute
 
1227
    attribute_name_n      - attribute n
 
1228
    attribute_value_n     - value of attribute n
1101
1229
 
1102
1230
  DESCRIPTION
1103
 
  Print XML tag with any number of attribute="value" pairs to the xml_file.
 
1231
    Print XML tag with any number of attribute="value" pairs to the xml_file.
1104
1232
 
1105
 
  Format is:
1106
 
  sbeg<tag_name first_attribute_name="first_attribute_value" ...
1107
 
  attribute_name_n="attribute_value_n">send
 
1233
    Format is:
 
1234
      sbeg<tag_name first_attribute_name="first_attribute_value" ...
 
1235
      attribute_name_n="attribute_value_n">send
1108
1236
  NOTE
1109
 
  Additional arguments must be present in attribute/value pairs.
1110
 
  The last argument should be the null character pointer.
1111
 
  All attribute_value arguments MUST be NULL terminated strings.
1112
 
  All attribute_value arguments will be quoted before output.
 
1237
    Additional arguments must be present in attribute/value pairs.
 
1238
    The last argument should be the null character pointer.
 
1239
    All attribute_value arguments MUST be NULL terminated strings.
 
1240
    All attribute_value arguments will be quoted before output.
1113
1241
*/
1114
1242
 
1115
1243
static void print_xml_tag(FILE * xml_file, const char* sbeg,
1152
1280
  Print xml tag with for a field that is null
1153
1281
 
1154
1282
  SYNOPSIS
1155
 
  print_xml_null_tag()
1156
 
  xml_file    - output file
1157
 
  sbeg        - line beginning
1158
 
  stag_atr    - tag and attribute
1159
 
  sval        - value of attribute
1160
 
  line_end        - line ending
 
1283
    print_xml_null_tag()
 
1284
    xml_file    - output file
 
1285
    sbeg        - line beginning
 
1286
    stag_atr    - tag and attribute
 
1287
    sval        - value of attribute
 
1288
    line_end        - line ending
1161
1289
 
1162
1290
  DESCRIPTION
1163
 
  Print tag with one attribute to the xml_file. Format is:
1164
 
  <stag_atr="sval" xsi:nil="true"/>
 
1291
    Print tag with one attribute to the xml_file. Format is:
 
1292
      <stag_atr="sval" xsi:nil="true"/>
1165
1293
  NOTE
1166
 
  sval MUST be a NULL terminated string.
1167
 
  sval string will be qouted before output.
 
1294
    sval MUST be a NULL terminated string.
 
1295
    sval string will be qouted before output.
1168
1296
*/
1169
1297
 
1170
1298
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
1186
1314
  Print xml tag with many attributes.
1187
1315
 
1188
1316
  SYNOPSIS
1189
 
  print_xml_row()
1190
 
  xml_file    - output file
1191
 
  row_name    - xml tag name
1192
 
  tableRes    - query result
1193
 
  row         - result row
 
1317
    print_xml_row()
 
1318
    xml_file    - output file
 
1319
    row_name    - xml tag name
 
1320
    tableRes    - query result
 
1321
    row         - result row
1194
1322
 
1195
1323
  DESCRIPTION
1196
 
  Print tag with many attribute to the xml_file. Format is:
1197
 
  \t\t<row_name Atr1="Val1" Atr2="Val2"... />
 
1324
    Print tag with many attribute to the xml_file. Format is:
 
1325
      \t\t<row_name Atr1="Val1" Atr2="Val2"... />
1198
1326
  NOTE
1199
 
  All atributes and values will be quoted before output.
 
1327
    All atributes and values will be quoted before output.
1200
1328
*/
1201
1329
 
1202
1330
static void print_xml_row(FILE *xml_file, const char *row_name,
1231
1359
  Print hex value for blob data.
1232
1360
 
1233
1361
  SYNOPSIS
1234
 
  print_blob_as_hex()
1235
 
  output_file         - output file
1236
 
  str                 - string to print
1237
 
  len                 - its length
 
1362
    print_blob_as_hex()
 
1363
    output_file         - output file
 
1364
    str                 - string to print
 
1365
    len                 - its length
1238
1366
 
1239
1367
  DESCRIPTION
1240
 
  Print hex value for blob data.
 
1368
    Print hex value for blob data.
1241
1369
*/
1242
1370
 
1243
1371
static void print_blob_as_hex(FILE *output_file, const char *str, uint32_t len)
1244
1372
{
1245
 
  /* sakaik got the idea to to provide blob's in hex notation. */
1246
 
  const char *ptr= str, *end= ptr + len;
1247
 
  for (; ptr < end ; ptr++)
1248
 
    fprintf(output_file, "%02X", *((unsigned char *)ptr));
1249
 
  check_io(output_file);
 
1373
    /* sakaik got the idea to to provide blob's in hex notation. */
 
1374
    const char *ptr= str, *end= ptr + len;
 
1375
    for (; ptr < end ; ptr++)
 
1376
      fprintf(output_file, "%02X", *((unsigned char *)ptr));
 
1377
    check_io(output_file);
1250
1378
}
1251
1379
 
1252
1380
/*
1255
1383
  be dumping.
1256
1384
 
1257
1385
  ARGS
1258
 
  table       - table name
1259
 
  db          - db name
1260
 
  table_type  - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
1261
 
  ignore_flag - what we must particularly ignore - see IGNORE_ defines above
1262
 
  num_fields  - number of fields in the table
 
1386
    table       - table name
 
1387
    db          - db name
 
1388
    table_type  - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
 
1389
    ignore_flag - what we must particularly ignore - see IGNORE_ defines above
 
1390
    num_fields  - number of fields in the table
1263
1391
 
1264
1392
  RETURN
1265
 
  true if success, false if error
 
1393
    true if success, false if error
1266
1394
*/
1267
1395
 
1268
1396
static bool get_table_structure(char *table, char *db, char *table_type,
1286
1414
  {
1287
1415
    delayed= 0;
1288
1416
    verbose_msg(_("-- Warning: Unable to use delayed inserts for table '%s' "
1289
 
                  "because it's of type %s\n"), table, table_type);
 
1417
                "because it's of type %s\n"), table, table_type);
1290
1418
  }
1291
1419
 
1292
1420
  complete_insert= 0;
1342
1470
      }
1343
1471
      if (opt_drop)
1344
1472
      {
1345
 
        /*
1346
 
          Even if the "table" is a view, we do a DROP TABLE here.
1347
 
        */
 
1473
      /*
 
1474
        Even if the "table" is a view, we do a DROP TABLE here.
 
1475
       */
1348
1476
        fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", opt_quoted_table);
1349
1477
        check_io(sql_file);
1350
1478
      }
1414
1542
  else
1415
1543
  {
1416
1544
    verbose_msg(_("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n"),
1417
 
                internal::my_progname, drizzle_con_error(&dcon));
 
1545
                my_progname, drizzle_con_error(&dcon));
1418
1546
 
1419
1547
    snprintf(query_buff, sizeof(query_buff), "show fields from %s",
1420
1548
             result_table);
1442
1570
        fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
1443
1571
      else
1444
1572
        print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
1445
 
                      NULL);
 
1573
                NULL);
1446
1574
      check_io(sql_file);
1447
1575
    }
1448
1576
 
1521
1649
      if (drizzleclient_query_with_error_report(&dcon, &result, buff, false))
1522
1650
      {
1523
1651
        fprintf(stderr, _("%s: Can't get keys for table %s\n"),
1524
 
                internal::my_progname, result_table);
 
1652
                my_progname, result_table);
1525
1653
        if (path)
1526
1654
          fclose(sql_file);
1527
1655
        return false;
1705
1833
 
1706
1834
/*
1707
1835
 
1708
 
  SYNOPSIS
 
1836
 SYNOPSIS
1709
1837
  dump_table()
1710
1838
 
1711
1839
  dump_table saves database contents as a series of INSERT statements.
1712
1840
 
1713
1841
  ARGS
1714
 
  table - table name
1715
 
  db    - db name
 
1842
   table - table name
 
1843
   db    - db name
1716
1844
 
1717
 
  RETURNS
1718
 
  void
 
1845
   RETURNS
 
1846
    void
1719
1847
*/
1720
1848
 
1721
1849
 
1755
1883
 
1756
1884
  /*
1757
1885
    If the table type is a merge table or any type that has to be
1758
 
    _completely_ ignored and no data dumped
 
1886
     _completely_ ignored and no data dumped
1759
1887
  */
1760
1888
  if (ignore_flag & IGNORE_DATA)
1761
1889
  {
1762
1890
    verbose_msg(_("-- Warning: Skipping data for table '%s' because " \
1763
 
                  "it's of type %s\n"), table, table_type);
 
1891
                "it's of type %s\n"), table, table_type);
1764
1892
    return;
1765
1893
  }
1766
1894
  /* Check that there are any fields in the table */
1787
1915
      Convert the path to native os format
1788
1916
      and resolve to the full filepath.
1789
1917
    */
1790
 
    internal::convert_dirname(tmp_path,path,NULL);
1791
 
    internal::my_load_path(tmp_path, tmp_path, NULL);
1792
 
    internal::fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
 
1918
    convert_dirname(tmp_path,path,NULL);
 
1919
    my_load_path(tmp_path, tmp_path, NULL);
 
1920
    fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
1793
1921
 
1794
1922
    /* Must delete the file that 'INTO OUTFILE' will write to */
1795
 
    internal::my_delete(filename, MYF(0));
 
1923
    my_delete(filename, MYF(0));
1796
1924
 
1797
1925
    /* now build the query string */
1798
1926
 
1883
2011
    if (drizzle_result_column_count(&result) != num_fields)
1884
2012
    {
1885
2013
      fprintf(stderr,_("%s: Error in field count for table: %s !  Aborting.\n"),
1886
 
              internal::my_progname, result_table);
 
2014
              my_progname, result_table);
1887
2015
      error= EX_CONSCHECK;
1888
2016
      drizzle_result_free(&result);
1889
2017
      goto err;
1890
2018
    }
1891
2019
 
 
2020
    if (opt_lock)
 
2021
    {
 
2022
      fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
 
2023
      check_io(md_result_file);
 
2024
    }
1892
2025
    /* Moved disable keys to after lock per bug 15977 */
1893
2026
    if (opt_disable_keys)
1894
2027
    {
1895
2028
      fprintf(md_result_file, "ALTER TABLE %s DISABLE KEYS;\n",
1896
 
              opt_quoted_table);
 
2029
              opt_quoted_table);
1897
2030
      check_io(md_result_file);
1898
2031
    }
1899
2032
 
1903
2036
    init_length=(uint32_t) insert_pat.length()+4;
1904
2037
    if (opt_xml)
1905
2038
      print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
1906
 
                    NULL);
 
2039
              NULL);
1907
2040
    if (opt_autocommit)
1908
2041
    {
1909
2042
      fprintf(md_result_file, "set autocommit=0;\n");
1926
2059
        if (ret != DRIZZLE_RETURN_OK)
1927
2060
        {
1928
2061
          fprintf(stderr,
1929
 
                  _("%s: Error reading rows for table: %s (%d:%s) ! Aborting.\n"),
1930
 
                  internal::my_progname, result_table, ret, drizzle_con_error(&dcon));
 
2062
                _("%s: Error reading rows for table: %s (%d:%s) ! Aborting.\n"),
 
2063
                  my_progname, result_table, ret, drizzle_con_error(&dcon));
1931
2064
          drizzle_result_free(&result);
1932
2065
          goto err;
1933
2066
        }
1965
2098
 
1966
2099
        if (!(column= drizzle_column_next(&result)))
1967
2100
          die(EX_CONSCHECK,
1968
 
              _("Not enough fields from table %s! Aborting.\n"),
1969
 
              result_table);
 
2101
                      _("Not enough fields from table %s! Aborting.\n"),
 
2102
                      result_table);
1970
2103
 
1971
2104
        /*
1972
 
          63 is my_charset_bin. If charsetnr is not 63,
1973
 
          we have not a BLOB but a TEXT column.
1974
 
          we'll dump in hex only BLOB columns.
 
2105
           63 is my_charset_bin. If charsetnr is not 63,
 
2106
           we have not a BLOB but a TEXT column.
 
2107
           we'll dump in hex only BLOB columns.
1975
2108
        */
1976
2109
        is_blob= (opt_hex_blob && drizzle_column_charset(column) == 63 &&
1977
2110
                  (drizzle_column_type(column) == DRIZZLE_COLUMN_TYPE_VARCHAR ||
2022
2155
                /* change any strings ("inf", "-inf", "nan") into NULL */
2023
2156
                char *ptr= row[i];
2024
2157
                if (my_isalpha(charset_info, *ptr) || (*ptr == '-' &&
2025
 
                                                       my_isalpha(charset_info, ptr[1])))
 
2158
                    my_isalpha(charset_info, ptr[1])))
2026
2159
                  extended_row.append( "NULL");
2027
2160
                else
2028
2161
                {
2079
2212
              if (opt_xml)
2080
2213
              {
2081
2214
                print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
2082
 
                              drizzle_column_name(column), NULL);
 
2215
                        drizzle_column_name(column), NULL);
2083
2216
                fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
2084
2217
                      md_result_file);
2085
2218
                fputs("</field>\n", md_result_file);
2142
2275
 
2143
2276
    /* XML - close table tag and supress regular output */
2144
2277
    if (opt_xml)
2145
 
      fputs("\t</table_data>\n", md_result_file);
 
2278
        fputs("\t</table_data>\n", md_result_file);
2146
2279
    else if (extended_insert && row_break)
2147
2280
      fputs(";\n", md_result_file);             /* If not empty table */
2148
2281
    fflush(md_result_file);
2155
2288
              opt_quoted_table);
2156
2289
      check_io(md_result_file);
2157
2290
    }
 
2291
    if (opt_lock)
 
2292
    {
 
2293
      fputs("UNLOCK TABLES;\n", md_result_file);
 
2294
      check_io(md_result_file);
 
2295
    }
2158
2296
    if (opt_autocommit)
2159
2297
    {
2160
2298
      fprintf(md_result_file, "commit;\n");
2232
2370
 
2233
2371
 
2234
2372
/*
2235
 
  Table Specific database initalization.
 
2373
Table Specific database initalization.
2236
2374
 
2237
 
  SYNOPSIS
 
2375
SYNOPSIS
2238
2376
  init_dumping_tables
2239
2377
  qdatabase      quoted name of the database
2240
2378
 
2241
 
  RETURN VALUES
 
2379
RETURN VALUES
2242
2380
  0        Success.
2243
2381
  1        Failure.
2244
2382
*/
2301
2439
    return 1;
2302
2440
 
2303
2441
  if (drizzle_select_db(&dcon, &result, database, &ret) == NULL ||
2304
 
      ret != DRIZZLE_RETURN_OK)
 
2442
        ret != DRIZZLE_RETURN_OK)
2305
2443
  {
2306
2444
    DB_error(&result, ret, _("when executing 'SELECT INTO OUTFILE'"));
2307
2445
    return 1;                   /* If --force */
2338
2476
 
2339
2477
/* Return 1 if we should copy the table */
2340
2478
 
2341
 
static bool include_table(const char *hash_key, size_t key_size)
 
2479
static bool include_table(const unsigned char *hash_key, size_t len)
2342
2480
{
2343
 
  string match(hash_key, key_size);
2344
 
  drizzled::hash_set<string>::iterator iter= ignore_table.find(match);
2345
 
  return (iter == ignore_table.end());
 
2481
  return !hash_search(&ignore_table, hash_key, len);
2346
2482
}
2347
2483
 
2348
2484
 
2349
2485
static int dump_all_tables_in_db(char *database)
2350
2486
{
2351
2487
  char *table;
 
2488
  uint32_t numrows;
 
2489
  char table_buff[DRIZZLE_MAX_TABLE_SIZE*2+3];
2352
2490
  char hash_key[DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2];  /* "db.tablename" */
2353
2491
  char *afterdot;
2354
2492
  drizzle_result_st result;
2355
2493
  drizzle_return_t ret;
2356
2494
 
2357
 
  memset(hash_key, 0, DRIZZLE_MAX_DB_SIZE+DRIZZLE_MAX_TABLE_SIZE+2);
2358
2495
  afterdot= strcpy(hash_key, database) + strlen(database);
2359
2496
  *afterdot++= '.';
2360
2497
 
2362
2499
    return(1);
2363
2500
  if (opt_xml)
2364
2501
    print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NULL);
 
2502
  if (lock_tables)
 
2503
  {
 
2504
    string query("LOCK TABLES ");
 
2505
    for (numrows= 0 ; (table= getTableName(1)) ; )
 
2506
    {
 
2507
      char *end= strcpy(afterdot, table) + strlen(table);
 
2508
      if (include_table((unsigned char*) hash_key,end - hash_key))
 
2509
      {
 
2510
        numrows++;
 
2511
        query.append( quote_name(table, table_buff, 1));
 
2512
        query.append( " READ LOCAL,");
 
2513
      }
 
2514
    }
 
2515
    if (numrows)
 
2516
    {
 
2517
      if (drizzle_query(&dcon, &result, query.c_str(),
 
2518
                        query.length()-1, &ret) == NULL ||
 
2519
          ret != DRIZZLE_RETURN_OK)
 
2520
      {
 
2521
        DB_error(&result, ret, _("when using LOCK TABLES"));
 
2522
        /* We shall continue here, if --force was given */
 
2523
      }
 
2524
      else
 
2525
        drizzle_result_free(&result);
 
2526
    }
 
2527
    query.clear();
 
2528
  }
2365
2529
  if (flush_logs)
2366
2530
  {
2367
2531
    if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
2376
2540
  while ((table= getTableName(0)))
2377
2541
  {
2378
2542
    char *end= strcpy(afterdot, table) + strlen(table);
2379
 
    if (include_table(hash_key, end - hash_key))
 
2543
    if (include_table((unsigned char*) hash_key, end - hash_key))
2380
2544
    {
2381
2545
      dump_table(table,database);
2382
2546
      free(order_by);
2388
2552
    fputs("</database>\n", md_result_file);
2389
2553
    check_io(md_result_file);
2390
2554
  }
 
2555
  if (lock_tables)
 
2556
  {
 
2557
    if (!drizzleclient_query_with_error_report(&dcon, &result, "UNLOCK TABLES", false))
 
2558
      drizzle_result_free(&result);
 
2559
  }
2391
2560
 
2392
 
  return 0;
 
2561
  return(0);
2393
2562
} /* dump_all_tables_in_db */
2394
2563
 
2395
2564
 
2400
2569
  different case (e.g.  T1 vs t1)
2401
2570
 
2402
2571
  RETURN
2403
 
  pointer to the table name
2404
 
  0 if error
 
2572
    pointer to the table name
 
2573
    0 if error
2405
2574
*/
2406
2575
 
2407
 
static char *get_actual_table_name(const char *old_table_name,
2408
 
                                   drizzled::memory::Root *root)
 
2576
static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
2409
2577
{
2410
2578
  char *name= 0;
2411
2579
  drizzle_result_st result;
2429
2597
    size_t *lengths;
2430
2598
    /*
2431
2599
      Return first row
2432
 
      TODO-> Return all matching rows
 
2600
      TODO: Return all matching rows
2433
2601
    */
2434
2602
    row= drizzle_row_next(&result);
2435
2603
    lengths= drizzle_row_field_sizes(&result);
2443
2611
 
2444
2612
static int dump_selected_tables(char *db, char **table_names, int tables)
2445
2613
{
2446
 
  drizzled::memory::Root root;
 
2614
  char table_buff[DRIZZLE_MAX_TABLE_SIZE*2+3];
 
2615
  string lock_tables_query("LOCK TABLES ");
 
2616
  MEM_ROOT root;
2447
2617
  char **dump_tables, **pos, **end;
2448
2618
  drizzle_result_st result;
2449
2619
  drizzle_return_t ret;
2452
2622
  if (init_dumping(db, init_dumping_tables))
2453
2623
    return(1);
2454
2624
 
2455
 
  init_alloc_root(&root, 8192);
 
2625
  init_alloc_root(&root, 8192, 0);
2456
2626
  if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *))))
2457
 
    die(EX_EOM, _("alloc_root failure."));
 
2627
     die(EX_EOM, _("alloc_root failure."));
2458
2628
 
2459
2629
  for (; tables > 0 ; tables-- , table_names++)
2460
2630
  {
2461
2631
    /* the table name passed on commandline may be wrong case */
2462
2632
    if ((*pos= get_actual_table_name(*table_names, &root)))
2463
2633
    {
 
2634
      /* Add found table name to lock_tables_query */
 
2635
      if (lock_tables)
 
2636
      {
 
2637
        lock_tables_query.append( quote_name(*pos, table_buff, 1));
 
2638
        lock_tables_query.append( " READ LOCAL,");
 
2639
      }
2464
2640
      pos++;
2465
2641
    }
2466
2642
    else
2475
2651
  }
2476
2652
  end= pos;
2477
2653
 
 
2654
  if (lock_tables)
 
2655
  {
 
2656
    if (drizzle_query(&dcon, &result, lock_tables_query.c_str(),
 
2657
                      lock_tables_query.length()-1, &ret) == NULL ||
 
2658
        ret != DRIZZLE_RETURN_OK)
 
2659
    {
 
2660
      if (!ignore_errors)
 
2661
      {
 
2662
        free_root(&root, MYF(0));
 
2663
      }
 
2664
      DB_error(&result, ret, _("when doing LOCK TABLES"));
 
2665
      /* We shall countinue here, if --force was given */
 
2666
    }
 
2667
    else
 
2668
      drizzle_result_free(&result);
 
2669
  }
2478
2670
  if (flush_logs)
2479
2671
  {
2480
2672
    if (drizzle_query_str(&dcon, &result, "FLUSH LOGS", &ret) == NULL ||
2503
2695
    fputs("</database>\n", md_result_file);
2504
2696
    check_io(md_result_file);
2505
2697
  }
2506
 
  return 0;
 
2698
  if (lock_tables)
 
2699
  {
 
2700
    if (!(drizzleclient_query_with_error_report(&dcon, &result, "UNLOCK TABLES", false)))
 
2701
      drizzle_result_free(&result);
 
2702
  }
 
2703
  return(0);
2507
2704
} /* dump_selected_tables */
2508
2705
 
 
2706
 
 
2707
static int do_show_master_status(drizzle_con_st *drizzle_con)
 
2708
{
 
2709
  drizzle_row_t row;
 
2710
  drizzle_result_st master;
 
2711
  const char *comment_prefix=
 
2712
    (opt_master_data == DRIZZLE_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
 
2713
  if (drizzleclient_query_with_error_report(drizzle_con, &master, "SHOW MASTER STATUS", false))
 
2714
  {
 
2715
    return 1;
 
2716
  }
 
2717
  else
 
2718
  {
 
2719
    row= drizzle_row_next(&master);
 
2720
    if (row && row[0] && row[1])
 
2721
    {
 
2722
      /* SHOW MASTER STATUS reports file and position */
 
2723
      if (opt_comments)
 
2724
        fprintf(md_result_file,
 
2725
                "\n--\n-- Position to start replication or point-in-time "
 
2726
                "recovery from\n--\n\n");
 
2727
      fprintf(md_result_file,
 
2728
              "%sCHANGE MASTER TO MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n",
 
2729
              comment_prefix, row[0], row[1]);
 
2730
      check_io(md_result_file);
 
2731
    }
 
2732
    else if (!ignore_errors)
 
2733
    {
 
2734
      /* SHOW MASTER STATUS reports nothing and --force is not enabled */
 
2735
      my_printf_error(0, _("Error: Binlogging on server not active"),
 
2736
                      MYF(0));
 
2737
      drizzle_result_free(&master);
 
2738
      maybe_exit(EX_DRIZZLEERR);
 
2739
      return 1;
 
2740
    }
 
2741
    drizzle_result_free(&master);
 
2742
  }
 
2743
  return 0;
 
2744
}
 
2745
 
 
2746
static int do_stop_slave_sql(drizzle_con_st *drizzle_con)
 
2747
{
 
2748
  drizzle_result_st slave;
 
2749
  /* We need to check if the slave sql is running in the first place */
 
2750
  if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS", false))
 
2751
    return(1);
 
2752
  else
 
2753
  {
 
2754
    drizzle_row_t row= drizzle_row_next(&slave);
 
2755
    if (row && row[11])
 
2756
    {
 
2757
      /* if SLAVE SQL is not running, we don't stop it */
 
2758
      if (!strcmp(row[11],"No"))
 
2759
      {
 
2760
        drizzle_result_free(&slave);
 
2761
        /* Silently assume that they don't have the slave running */
 
2762
        return(0);
 
2763
      }
 
2764
    }
 
2765
  }
 
2766
  drizzle_result_free(&slave);
 
2767
 
 
2768
  /* now, stop slave if running */
 
2769
  if (drizzleclient_query_with_error_report(drizzle_con, &slave, "STOP SLAVE SQL_THREAD", false))
 
2770
    return(1);
 
2771
  drizzle_result_free(&slave);
 
2772
 
 
2773
  return(0);
 
2774
}
 
2775
 
 
2776
static int add_stop_slave(void)
 
2777
{
 
2778
  if (opt_comments)
 
2779
    fprintf(md_result_file,
 
2780
            "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
 
2781
  fprintf(md_result_file, "STOP SLAVE;\n");
 
2782
  return(0);
 
2783
}
 
2784
 
 
2785
static int add_slave_statements(void)
 
2786
{
 
2787
  if (opt_comments)
 
2788
    fprintf(md_result_file,
 
2789
            "\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
 
2790
  fprintf(md_result_file, "START SLAVE;\n");
 
2791
  return(0);
 
2792
}
 
2793
 
 
2794
static int do_show_slave_status(drizzle_con_st *drizzle_con)
 
2795
{
 
2796
  drizzle_result_st slave;
 
2797
  const char *comment_prefix=
 
2798
    (opt_slave_data == DRIZZLE_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
 
2799
  if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS", false))
 
2800
  {
 
2801
    if (!ignore_errors)
 
2802
    {
 
2803
      /* SHOW SLAVE STATUS reports nothing and --force is not enabled */
 
2804
      my_printf_error(0, _("Error: Slave not set up"), MYF(0));
 
2805
    }
 
2806
    return 1;
 
2807
  }
 
2808
  else
 
2809
  {
 
2810
    drizzle_row_t row= drizzle_row_next(&slave);
 
2811
    if (row && row[9] && row[21])
 
2812
    {
 
2813
      /* SHOW MASTER STATUS reports file and position */
 
2814
      if (opt_comments)
 
2815
        fprintf(md_result_file,
 
2816
                "\n--\n-- Position to start replication or point-in-time "
 
2817
                "recovery from (the master of this slave)\n--\n\n");
 
2818
 
 
2819
      fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
 
2820
 
 
2821
      if (opt_include_master_host_port)
 
2822
      {
 
2823
        if (row[1])
 
2824
          fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
 
2825
        if (row[3])
 
2826
          fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
 
2827
      }
 
2828
      fprintf(md_result_file,
 
2829
              "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
 
2830
 
 
2831
      check_io(md_result_file);
 
2832
    }
 
2833
    drizzle_result_free(&slave);
 
2834
  }
 
2835
  return 0;
 
2836
}
 
2837
 
 
2838
static int do_start_slave_sql(drizzle_con_st *drizzle_con)
 
2839
{
 
2840
  drizzle_result_st slave;
 
2841
  /* We need to check if the slave sql is stopped in the first place */
 
2842
  if (drizzleclient_query_with_error_report(drizzle_con, &slave, "SHOW SLAVE STATUS", false))
 
2843
    return(1);
 
2844
  else
 
2845
  {
 
2846
    drizzle_row_t row= drizzle_row_next(&slave);
 
2847
    if (row && row[11])
 
2848
    {
 
2849
      /* if SLAVE SQL is not running, we don't start it */
 
2850
      if (!strcmp(row[11],"Yes"))
 
2851
      {
 
2852
        drizzle_result_free(&slave);
 
2853
        /* Silently assume that they don't have the slave running */
 
2854
        return(0);
 
2855
      }
 
2856
    }
 
2857
    drizzle_result_free(&slave);
 
2858
  }
 
2859
 
 
2860
  /* now, start slave if stopped */
 
2861
  if (drizzleclient_query_with_error_report(drizzle_con, &slave, "START SLAVE", false))
 
2862
  {
 
2863
    my_printf_error(0, _("Error: Unable to start slave"), MYF(0));
 
2864
    return 1;
 
2865
  }
 
2866
  drizzle_result_free(&slave);
 
2867
  return(0);
 
2868
}
 
2869
 
 
2870
 
 
2871
 
2509
2872
static int do_flush_tables_read_lock(drizzle_con_st *drizzle_con)
2510
2873
{
2511
2874
  /*
2512
2875
    We do first a FLUSH TABLES. If a long update is running, the FLUSH TABLES
2513
2876
    will wait but will not stall the whole mysqld, and when the long update is
2514
2877
    done the FLUSH TABLES WITH READ LOCK will start and succeed quickly. So,
2515
 
    FLUSH TABLES is to lower the probability of a stage where both drizzled
 
2878
    FLUSH TABLES is to lower the probability of a stage where both mysqldump
2516
2879
    and most client connections are stalled. Of course, if a second long
2517
2880
    update starts between the two FLUSHes, we have that bad stall.
2518
2881
  */
2519
2882
  return
2520
2883
    ( drizzleclient_query_with_error_report(drizzle_con, 0, "FLUSH TABLES", false) ||
2521
2884
      drizzleclient_query_with_error_report(drizzle_con, 0,
2522
 
                                            "FLUSH TABLES WITH READ LOCK", false) );
 
2885
                                    "FLUSH TABLES WITH READ LOCK", false) );
2523
2886
}
2524
2887
 
 
2888
 
2525
2889
static int do_unlock_tables(drizzle_con_st *drizzle_con)
2526
2890
{
2527
2891
  return drizzleclient_query_with_error_report(drizzle_con, 0, "UNLOCK TABLES", false);
2528
2892
}
2529
2893
 
 
2894
static int get_bin_log_name(drizzle_con_st *drizzle_con,
 
2895
                            char* buff_log_name, uint32_t buff_len)
 
2896
{
 
2897
  drizzle_result_st res;
 
2898
  drizzle_row_t row;
 
2899
 
 
2900
  if (drizzleclient_query_with_error_report(drizzle_con, &res, "SHOW MASTER STATUS", false))
 
2901
    return 1;
 
2902
 
 
2903
  if (!(row= drizzle_row_next(&res)))
 
2904
  {
 
2905
    drizzle_result_free(&res);
 
2906
    return 1;
 
2907
  }
 
2908
  /*
 
2909
    Only one row is returned, and the first column is the name of the
 
2910
    active log.
 
2911
  */
 
2912
  strncpy(buff_log_name, row[0], buff_len - 1);
 
2913
 
 
2914
  drizzle_result_free(&res);
 
2915
  return 0;
 
2916
}
 
2917
 
 
2918
static int purge_bin_logs_to(drizzle_con_st *drizzle_con, char* log_name)
 
2919
{
 
2920
  int err;
 
2921
  string str= "PURGE BINARY LOGS TO '";
 
2922
  str.append(log_name);
 
2923
  str.append("'");
 
2924
  drizzle_result_st res;
 
2925
  err= drizzleclient_query_with_error_report(drizzle_con, &res, str.c_str(),
 
2926
                                             false);
 
2927
  if (err)
 
2928
    return err;
 
2929
  drizzle_result_free(&res);
 
2930
  return 0;
 
2931
}
 
2932
 
 
2933
 
2530
2934
static int start_transaction(drizzle_con_st *drizzle_con)
2531
2935
{
2532
2936
  return (drizzleclient_query_with_error_report(drizzle_con, 0,
2533
 
                                                "SET SESSION TRANSACTION ISOLATION "
2534
 
                                                "LEVEL REPEATABLE READ", false) ||
 
2937
                                        "SET SESSION TRANSACTION ISOLATION "
 
2938
                                        "LEVEL REPEATABLE READ", false) ||
2535
2939
          drizzleclient_query_with_error_report(drizzle_con, 0,
2536
 
                                                "START TRANSACTION "
2537
 
                                                "WITH CONSISTENT SNAPSHOT", false));
 
2940
                                        "START TRANSACTION "
 
2941
                                        "WITH CONSISTENT SNAPSHOT", false));
2538
2942
}
2539
2943
 
2540
2944
 
2541
2945
static uint32_t find_set(TYPELIB *lib, const char *x, uint32_t length,
2542
 
                         char **err_pos, uint32_t *err_len)
 
2946
                      char **err_pos, uint32_t *err_len)
2543
2947
{
2544
2948
  const char *end= x + length;
2545
2949
  uint32_t found= 0;
2561
2965
 
2562
2966
      for (; pos != end && *pos != ','; pos++) ;
2563
2967
      var_len= (uint32_t) (pos - start);
2564
 
      strncpy(buff, start, min((uint32_t)sizeof(buff), var_len+1));
 
2968
      strncpy(buff, start, min((uint32_t)sizeof(buff), var_len));
2565
2969
      find= find_type(buff, lib, var_len);
2566
2970
      if (!find)
2567
2971
      {
2645
3049
 
2646
3050
  ARGS
2647
3051
 
2648
 
  check_if_ignore_table()
2649
 
  table_name                  Table name to check
2650
 
  table_type                  Type of table
 
3052
    check_if_ignore_table()
 
3053
    table_name                  Table name to check
 
3054
    table_type                  Type of table
2651
3055
 
2652
3056
  GLOBAL VARIABLES
2653
 
  drizzle                       Drizzle connection
2654
 
  verbose                     Write warning messages
 
3057
    drizzle                       Drizzle connection
 
3058
    verbose                     Write warning messages
2655
3059
 
2656
3060
  RETURN
2657
 
  char (bit value)            See IGNORE_ values at top
 
3061
    char (bit value)            See IGNORE_ values at top
2658
3062
*/
2659
3063
 
2660
3064
char check_if_ignore_table(const char *table_name, char *table_type)
2690
3094
  }
2691
3095
  /*
2692
3096
    If the table type matches any of these, we do support delayed inserts.
2693
 
    Note-> we do not want to skip dumping this table if if is not one of
 
3097
    Note: we do not want to skip dumping this table if if is not one of
2694
3098
    these types, but we do want to use delayed inserts in the dump if
2695
3099
    the table type is _NOT_ one of these types
2696
 
  */
 
3100
    */
2697
3101
  {
2698
3102
    strncpy(table_type, row[1], DRIZZLE_MAX_TABLE_SIZE-1);
2699
3103
    if (opt_delayed)
2714
3118
  Get string of comma-separated primary key field names
2715
3119
 
2716
3120
  SYNOPSIS
2717
 
  char *primary_key_fields(const char *table_name)
2718
 
  RETURNS     pointer to allocated buffer (must be freed by caller)
2719
 
  table_name  quoted table name
 
3121
    char *primary_key_fields(const char *table_name)
 
3122
    RETURNS     pointer to allocated buffer (must be freed by caller)
 
3123
    table_name  quoted table name
2720
3124
 
2721
3125
  DESCRIPTION
2722
 
  Use SHOW KEYS FROM table_name, allocate a buffer to hold the
2723
 
  field names, and then build that string and return the pointer
2724
 
  to that buffer.
 
3126
    Use SHOW KEYS FROM table_name, allocate a buffer to hold the
 
3127
    field names, and then build that string and return the pointer
 
3128
    to that buffer.
2725
3129
 
2726
 
  Returns NULL if there is no PRIMARY or UNIQUE key on the table,
2727
 
  or if there is some failure.  It is better to continue to dump
2728
 
  the table unsorted, rather than exit without dumping the data.
 
3130
    Returns NULL if there is no PRIMARY or UNIQUE key on the table,
 
3131
    or if there is some failure.  It is better to continue to dump
 
3132
    the table unsorted, rather than exit without dumping the data.
2729
3133
*/
2730
3134
 
2731
3135
static char *primary_key_fields(const char *table_name)
2748
3152
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
2749
3153
    {
2750
3154
      fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2751
 
                        " records are NOT sorted (%s)\n"),
 
3155
              " records are NOT sorted (%s)\n"),
2752
3156
              table_name, drizzle_result_error(&res));
2753
3157
      drizzle_result_free(&res);
2754
3158
    }
2755
3159
    else
2756
3160
    {
2757
3161
      fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2758
 
                        " records are NOT sorted (%s)\n"),
 
3162
              " records are NOT sorted (%s)\n"),
2759
3163
              table_name, drizzle_con_error(&dcon));
2760
3164
    }
2761
3165
 
2765
3169
  if (drizzle_result_buffer(&res) != DRIZZLE_RETURN_OK)
2766
3170
  {
2767
3171
    fprintf(stderr, _("Warning: Couldn't read keys from table %s;"
2768
 
                      " records are NOT sorted (%s)\n"),
 
3172
            " records are NOT sorted (%s)\n"),
2769
3173
            table_name, drizzle_con_error(&dcon));
2770
3174
    return result;
2771
3175
  }
2775
3179
   * Note that SHOW KEYS is ordered:  a PRIMARY key is always the first
2776
3180
   * row, and UNIQUE keys come before others.  So we only need to check
2777
3181
   * the first key, not all keys.
2778
 
 */
 
3182
   */
2779
3183
  if ((row= drizzle_row_next(&res)) && atoi(row[1]) == 0)
2780
3184
  {
2781
3185
    /* Key is unique */
2791
3195
  {
2792
3196
    char *end;
2793
3197
    /* result (terminating \0 is already in result_length) */
2794
 
 
2795
 
    size_t result_length_alloc= result_length + 10;
2796
 
    result= (char *)malloc(result_length_alloc);
 
3198
    result= (char *)malloc(result_length + 10);
2797
3199
    if (!result)
2798
3200
    {
2799
3201
      fprintf(stderr, _("Error: Not enough memory to store ORDER BY clause\n"));
2804
3206
    row= drizzle_row_next(&res);
2805
3207
    quoted_field= quote_name(row[4], buff, 0);
2806
3208
    end= strcpy(result, quoted_field) + strlen(quoted_field);
2807
 
    result_length_alloc -= strlen(quoted_field);
2808
3209
    while ((row= drizzle_row_next(&res)) && atoi(row[3]) > 1)
2809
3210
    {
2810
3211
      quoted_field= quote_name(row[4], buff, 0);
2811
 
      end+= snprintf(end, result_length_alloc, ",%s",quoted_field);
2812
 
      result_length_alloc -= strlen(quoted_field);
 
3212
      end+= sprintf(end,",%s",quoted_field);
2813
3213
    }
2814
3214
  }
2815
3215
 
2820
3220
 
2821
3221
int main(int argc, char **argv)
2822
3222
{
 
3223
  char bin_log_name[FN_REFLEN];
2823
3224
  int exit_code;
2824
3225
  MY_INIT("drizzledump");
2825
3226
  drizzle_result_st result;
2826
3227
 
2827
3228
  compatible_mode_normal_str[0]= 0;
 
3229
  default_charset= (char *)drizzle_universal_client_charset;
 
3230
  memset(&ignore_table, 0, sizeof(ignore_table));
2828
3231
 
2829
3232
  exit_code= get_options(&argc, &argv);
2830
3233
  if (exit_code)
2841
3244
  if (!path)
2842
3245
    write_header(md_result_file, *argv);
2843
3246
 
2844
 
  if ((opt_lock_all_tables) && do_flush_tables_read_lock(&dcon))
 
3247
  if (opt_slave_data && do_stop_slave_sql(&dcon))
 
3248
    goto err;
 
3249
 
 
3250
  if ((opt_lock_all_tables || opt_master_data) &&
 
3251
      do_flush_tables_read_lock(&dcon))
2845
3252
    goto err;
2846
3253
  if (opt_single_transaction && start_transaction(&dcon))
2847
 
    goto err;
2848
 
  if (opt_lock_all_tables)
 
3254
      goto err;
 
3255
  if (opt_delete_master_logs)
 
3256
  {
 
3257
    if (drizzleclient_query_with_error_report(&dcon, &result, "FLUSH LOGS", false))
 
3258
      goto err;
 
3259
    drizzle_result_free(&result);
 
3260
    if (get_bin_log_name(&dcon, bin_log_name, sizeof(bin_log_name)))
 
3261
      goto err;
 
3262
    flush_logs= 0;
 
3263
  }
 
3264
  if (opt_lock_all_tables || opt_master_data)
2849
3265
  {
2850
3266
    if (drizzleclient_query_with_error_report(&dcon, &result, "FLUSH LOGS", false))
2851
3267
      goto err;
2852
3268
    drizzle_result_free(&result);
2853
3269
    flush_logs= 0; /* not anymore; that would not be sensible */
2854
3270
  }
 
3271
  /* Add 'STOP SLAVE to beginning of dump */
 
3272
  if (opt_slave_apply && add_stop_slave())
 
3273
    goto err;
 
3274
  if (opt_master_data && do_show_master_status(&dcon))
 
3275
    goto err;
 
3276
  if (opt_slave_data && do_show_slave_status(&dcon))
 
3277
    goto err;
2855
3278
  if (opt_single_transaction && do_unlock_tables(&dcon)) /* unlock but no commit! */
2856
3279
    goto err;
2857
3280
 
2869
3292
    dump_databases(argv);
2870
3293
  }
2871
3294
 
 
3295
  /* if --dump-slave , start the slave sql thread */
 
3296
  if (opt_slave_data && do_start_slave_sql(&dcon))
 
3297
    goto err;
 
3298
 
 
3299
  /* add 'START SLAVE' to end of dump */
 
3300
  if (opt_slave_apply && add_slave_statements())
 
3301
    goto err;
 
3302
 
2872
3303
  /* ensure dumped data flushed */
2873
3304
  if (md_result_file && fflush(md_result_file))
2874
3305
  {
2876
3307
      first_error= EX_DRIZZLEERR;
2877
3308
    goto err;
2878
3309
  }
 
3310
  /* everything successful, purge the old logs files */
 
3311
  if (opt_delete_master_logs && purge_bin_logs_to(&dcon, bin_log_name))
 
3312
    goto err;
2879
3313
 
2880
3314
  /*
2881
3315
    No reason to explicitely COMMIT the transaction, neither to explicitely