00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "client_priv.h"
00035 #include <string>
00036 #include <iostream>
00037 #include <stdarg.h>
00038 #include <boost/unordered_set.hpp>
00039 #include <algorithm>
00040 #include <fstream>
00041 #include <drizzled/gettext.h>
00042 #include <drizzled/configmake.h>
00043 #include <drizzled/error.h>
00044 #include <boost/program_options.hpp>
00045 #include <boost/regex.hpp>
00046 #include <boost/date_time/posix_time/posix_time.hpp>
00047
00048 #include "client/drizzledump_data.h"
00049 #include "client/drizzledump_mysql.h"
00050 #include "client/drizzledump_drizzle.h"
00051
00052 #include "user_detect.h"
00053
00054 using namespace std;
00055 using namespace drizzled;
00056 namespace po= boost::program_options;
00057
00058
00059
00060 #define EX_USAGE 1
00061 #define EX_DRIZZLEERR 2
00062 #define EX_EOF 5
00063
00064 bool verbose= false;
00065 static bool use_drizzle_protocol= false;
00066 bool ignore_errors= false;
00067 static bool flush_logs= false;
00068 static bool create_options= true;
00069 static bool opt_quoted= false;
00070 bool opt_databases= false;
00071 bool opt_alldbs= false;
00072 static bool opt_lock_all_tables= false;
00073 static bool opt_dump_date= true;
00074 bool opt_autocommit= false;
00075 static bool opt_single_transaction= false;
00076 static bool opt_comments;
00077 static bool opt_compact;
00078 bool opt_ignore= false;
00079 bool opt_drop_database;
00080 bool opt_no_create_info;
00081 bool opt_no_data= false;
00082 bool opt_create_db= false;
00083 bool opt_disable_keys= true;
00084 bool extended_insert= true;
00085 bool opt_replace_into= false;
00086 bool opt_drop= true;
00087 bool opt_data_is_mangled= false;
00088 uint32_t show_progress_size= 0;
00089 static string insert_pat;
00090 static uint32_t opt_drizzle_port= 0;
00091 static int first_error= 0;
00092 static string extended_row;
00093 FILE *md_result_file= 0;
00094 FILE *stderror_file= 0;
00095 std::vector<DrizzleDumpDatabase*> database_store;
00096 DrizzleDumpConnection* db_connection;
00097 DrizzleDumpConnection* destination_connection;
00098
00099 enum destinations {
00100 DESTINATION_DB,
00101 DESTINATION_FILES,
00102 DESTINATION_STDOUT
00103 };
00104
00105 int opt_destination= DESTINATION_STDOUT;
00106 std::string opt_destination_host;
00107 uint16_t opt_destination_port;
00108 std::string opt_destination_user;
00109 std::string opt_destination_password;
00110 std::string opt_destination_database;
00111
00112 const string progname= "drizzledump";
00113
00114 string password,
00115 enclosed,
00116 escaped,
00117 current_host,
00118 path,
00119 current_user,
00120 opt_password,
00121 opt_protocol,
00122 where;
00123
00124 boost::unordered_set<string> ignore_table;
00125
00126 void maybe_exit(int error);
00127 static void die(int error, const char* reason, ...);
00128 static void write_header(char *db_name);
00129 static int dump_selected_tables(const string &db, const vector<string> &table_names);
00130 static int dump_databases(const vector<string> &db_names);
00131 static int dump_all_databases(void);
00132 int get_server_type();
00133 void dump_all_tables(void);
00134 void generate_dump(void);
00135 void generate_dump_db(void);
00136
00137 void dump_all_tables(void)
00138 {
00139 std::vector<DrizzleDumpDatabase*>::iterator i;
00140 for (i= database_store.begin(); i != database_store.end(); ++i)
00141 {
00142 if ((not (*i)->populateTables()) && (not ignore_errors))
00143 maybe_exit(EX_DRIZZLEERR);
00144 }
00145 }
00146
00147 void generate_dump(void)
00148 {
00149 std::vector<DrizzleDumpDatabase*>::iterator i;
00150
00151 if (path.empty())
00152 {
00153 cout << endl << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;"
00154 << endl << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
00155 }
00156
00157 if (opt_autocommit)
00158 cout << "SET AUTOCOMMIT=0;" << endl;
00159
00160 for (i= database_store.begin(); i != database_store.end(); ++i)
00161 {
00162 DrizzleDumpDatabase *database= *i;
00163 cout << *database;
00164 }
00165
00166 if (path.empty())
00167 {
00168 cout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;"
00169 << endl << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
00170 }
00171 }
00172
00173 void generate_dump_db(void)
00174 {
00175 std::vector<DrizzleDumpDatabase*>::iterator i;
00176 DrizzleStringBuf sbuf(1024);
00177 try
00178 {
00179 destination_connection= new DrizzleDumpConnection(opt_destination_host,
00180 opt_destination_port, opt_destination_user, opt_destination_password,
00181 false);
00182 }
00183 catch (std::exception&)
00184 {
00185 cerr << "Could not connect to destination database server" << endl;
00186 maybe_exit(EX_DRIZZLEERR);
00187 }
00188 sbuf.setConnection(destination_connection);
00189 std::ostream sout(&sbuf);
00190 sout.exceptions(ios_base::badbit);
00191
00192 if (path.empty())
00193 {
00194 sout << "SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;" << endl;
00195 sout << "SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;" << endl;
00196 }
00197
00198 if (opt_autocommit)
00199 cout << "SET AUTOCOMMIT=0;" << endl;
00200
00201 for (i= database_store.begin(); i != database_store.end(); ++i)
00202 {
00203 try
00204 {
00205 DrizzleDumpDatabase *database= *i;
00206 sout << *database;
00207 }
00208 catch (std::exception&)
00209 {
00210 std::cout << _("Error inserting into destination database") << std::endl;
00211 if (not ignore_errors)
00212 maybe_exit(EX_DRIZZLEERR);
00213 }
00214 }
00215
00216 if (path.empty())
00217 {
00218 sout << "SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;" << endl;
00219 sout << "SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;" << endl;
00220 }
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 static void check_io(FILE *file)
00232 {
00233 if (ferror(file))
00234 die(EX_EOF, _("Got errno %d on write"), errno);
00235 }
00236
00237 static void write_header(char *db_name)
00238 {
00239 if ((not opt_compact) and (opt_comments))
00240 {
00241 cout << "-- drizzledump " << VERSION << " libdrizzle "
00242 << drizzle_version() << ", for " << HOST_VENDOR << "-" << HOST_OS
00243 << " (" << HOST_CPU << ")" << endl << "--" << endl;
00244 cout << "-- Host: " << current_host << " Database: " << db_name << endl;
00245 cout << "-- ------------------------------------------------------" << endl;
00246 cout << "-- Server version\t" << db_connection->getServerVersion();
00247 if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
00248 cout << " (MySQL server)";
00249 else if (db_connection->getServerType() == ServerDetect::SERVER_DRIZZLE_FOUND)
00250 cout << " (Drizzle server)";
00251 cout << endl << endl;
00252 }
00253
00254 }
00255
00256
00257 static void write_footer(FILE *sql_file)
00258 {
00259 if (! opt_compact)
00260 {
00261 if (opt_comments)
00262 {
00263 if (opt_dump_date)
00264 {
00265 boost::posix_time::ptime time(boost::posix_time::second_clock::local_time());
00266 fprintf(sql_file, "-- Dump completed on %s\n",
00267 boost::posix_time::to_simple_string(time).c_str());
00268 }
00269 else
00270 fprintf(sql_file, "-- Dump completed\n");
00271 }
00272 check_io(sql_file);
00273 }
00274 }
00275
00276 static int get_options(void)
00277 {
00278 if (opt_single_transaction && opt_lock_all_tables)
00279 {
00280 fprintf(stderr, _("%s: You can't use --single-transaction and "
00281 "--lock-all-tables at the same time.\n"), progname.c_str());
00282 return(EX_USAGE);
00283 }
00284 if ((opt_databases || opt_alldbs) && ! path.empty())
00285 {
00286 fprintf(stderr,
00287 _("%s: --databases or --all-databases can't be used with --tab.\n"),
00288 progname.c_str());
00289 return(EX_USAGE);
00290 }
00291
00292 if (tty_password)
00293 opt_password=client_get_tty_password(NULL);
00294 return(0);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 static void die(int error_num, const char* fmt_reason, ...)
00312 {
00313 char buffer[1000];
00314 va_list args;
00315 va_start(args,fmt_reason);
00316 vsnprintf(buffer, sizeof(buffer), fmt_reason, args);
00317 va_end(args);
00318
00319 fprintf(stderr, "%s: %s\n", progname.c_str(), buffer);
00320 fflush(stderr);
00321
00322 ignore_errors= 0;
00323 maybe_exit(error_num);
00324 }
00325
00326 static void free_resources(void)
00327 {
00328 if (md_result_file && md_result_file != stdout)
00329 fclose(md_result_file);
00330 opt_password.erase();
00331 }
00332
00333
00334 void maybe_exit(int error)
00335 {
00336 if (!first_error)
00337 first_error= error;
00338 if (ignore_errors)
00339 return;
00340 delete db_connection;
00341 delete destination_connection;
00342 free_resources();
00343 exit(error);
00344 }
00345
00346 static int dump_all_databases()
00347 {
00348 drizzle_row_t row;
00349 drizzle_result_st *tableres;
00350 int result=0;
00351 std::string query;
00352 DrizzleDumpDatabase *database;
00353
00354 if (verbose)
00355 std::cerr << _("-- Retrieving database structures...") << std::endl;
00356
00357
00358 if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
00359 query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME NOT IN ('information_schema', 'performance_schema', 'mysql')";
00360 else
00361 query= "SELECT SCHEMA_NAME, DEFAULT_COLLATION_NAME FROM DATA_DICTIONARY.SCHEMAS WHERE SCHEMA_NAME NOT IN ('information_schema','data_dictionary')";
00362
00363 tableres= db_connection->query(query);
00364 while ((row= drizzle_row_next(tableres)))
00365 {
00366 std::string database_name(row[0]);
00367 if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
00368 database= new DrizzleDumpDatabaseMySQL(database_name, db_connection);
00369 else
00370 database= new DrizzleDumpDatabaseDrizzle(database_name, db_connection);
00371
00372 database->setCollate(row[1]);
00373 database_store.push_back(database);
00374 }
00375 db_connection->freeResult(tableres);
00376 return result;
00377 }
00378
00379
00380
00381 static int dump_databases(const vector<string> &db_names)
00382 {
00383 int result=0;
00384 string temp;
00385 DrizzleDumpDatabase *database;
00386
00387 for (vector<string>::const_iterator it= db_names.begin(); it != db_names.end(); ++it)
00388 {
00389 temp= *it;
00390 if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
00391 database= new DrizzleDumpDatabaseMySQL(temp, db_connection);
00392 else
00393 database= new DrizzleDumpDatabaseDrizzle(temp, db_connection);
00394 database_store.push_back(database);
00395 }
00396 return(result);
00397 }
00398
00399 static int dump_selected_tables(const string &db, const vector<string> &table_names)
00400 {
00401 DrizzleDumpDatabase *database;
00402
00403 if (db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND)
00404 database= new DrizzleDumpDatabaseMySQL(db, db_connection);
00405 else
00406 database= new DrizzleDumpDatabaseDrizzle(db, db_connection);
00407
00408 if (not database->populateTables(table_names))
00409 {
00410 delete database;
00411 if (not ignore_errors)
00412 maybe_exit(EX_DRIZZLEERR);
00413 }
00414
00415 database_store.push_back(database);
00416
00417 return 0;
00418 }
00419
00420 static int do_flush_tables_read_lock()
00421 {
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 db_connection->queryNoResult("FLUSH TABLES");
00432 db_connection->queryNoResult("FLUSH TABLES WITH READ LOCK");
00433
00434 return 0;
00435 }
00436
00437 static int start_transaction()
00438 {
00439 db_connection->queryNoResult("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ");
00440 db_connection->queryNoResult("START TRANSACTION WITH CONSISTENT SNAPSHOT");
00441
00442 if (db_connection->getServerType() == ServerDetect::SERVER_DRIZZLE_FOUND)
00443 {
00444 drizzle_result_st *result;
00445 drizzle_row_t row;
00446 std::string query("SELECT COMMIT_ID, ID FROM DATA_DICTIONARY.SYS_REPLICATION_LOG WHERE COMMIT_ID=(SELECT MAX(COMMIT_ID) FROM DATA_DICTIONARY.SYS_REPLICATION_LOG)");
00447 result= db_connection->query(query);
00448 if ((row= drizzle_row_next(result)))
00449 {
00450 cout << "-- SYS_REPLICATION_LOG: COMMIT_ID = " << row[0] << ", ID = " << row[1] << endl << endl;
00451 }
00452 db_connection->freeResult(result);
00453 }
00454
00455 return 0;
00456 }
00457
00458 int main(int argc, char **argv)
00459 {
00460 try
00461 {
00462 int exit_code;
00463
00464 #if defined(ENABLE_NLS)
00465 # if defined(HAVE_LOCALE_H)
00466 setlocale(LC_ALL, "");
00467 # endif
00468 bindtextdomain("drizzle7", LOCALEDIR);
00469 textdomain("drizzle7");
00470 #endif
00471
00472 po::options_description commandline_options(_("Options used only in command line"));
00473 commandline_options.add_options()
00474 ("all-databases,A", po::value<bool>(&opt_alldbs)->default_value(false)->zero_tokens(),
00475 _("Dump all the databases. This will be same as --databases with all databases selected."))
00476 ("flush-logs,F", po::value<bool>(&flush_logs)->default_value(false)->zero_tokens(),
00477 _("Flush logs file in server before starting dump. Note that if you dump many databases at once (using the option --databases= or --all-databases), the logs will be flushed for each database dumped. The exception is when using --lock-all-tables in this case the logs will be flushed only once, corresponding to the moment all tables are locked. So if you want your dump and the log flush to happen at the same exact moment you should use --lock-all-tables or --flush-logs"))
00478 ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
00479 _("Continue even if we get an sql-error."))
00480 ("help,?", _("Display this help message and exit."))
00481 ("lock-all-tables,x", po::value<bool>(&opt_lock_all_tables)->default_value(false)->zero_tokens(),
00482 _("Locks all tables across all databases. This is achieved by taking a global read lock for the duration of the whole dump. Automatically turns --single-transaction off."))
00483 ("single-transaction", po::value<bool>(&opt_single_transaction)->default_value(false)->zero_tokens(),
00484 _("Creates a consistent snapshot by dumping all tables in a single transaction. Works ONLY for tables stored in storage engines which support multiversioning (currently only InnoDB does); the dump is NOT guaranteed to be consistent for other storage engines. While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents), no other connection should use the following statements: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them."))
00485 ("skip-opt",
00486 _("Disable --opt. Disables --add-drop-table, --add-locks, --create-options, ---extended-insert and --disable-keys."))
00487 ("tables", _("Overrides option --databases (-B)."))
00488 ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(10000),
00489 _("Number of rows before each output progress report (requires --verbose)."))
00490 ("verbose,v", po::value<bool>(&verbose)->default_value(false)->zero_tokens(),
00491 _("Print info about the various stages."))
00492 ("version,V", _("Output version information and exit."))
00493 ("skip-comments", _("Turn off Comments"))
00494 ("skip-create", _("Turn off create-options"))
00495 ("skip-extended-insert", _("Turn off extended-insert"))
00496 ("skip-dump-date", _( "Turn off dump date at the end of the output"))
00497 ("no-defaults", _("Do not read from the configuration files"))
00498 ;
00499
00500 po::options_description dump_options(_("Options specific to the drizzle client"));
00501 dump_options.add_options()
00502 ("add-drop-database", po::value<bool>(&opt_drop_database)->default_value(false)->zero_tokens(),
00503 _("Add a 'DROP DATABASE' before each create."))
00504 ("skip-drop-table", _("Do not add a 'drop table' before each create."))
00505 ("compact", po::value<bool>(&opt_compact)->default_value(false)->zero_tokens(),
00506 _("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"))
00507 ("databases,B", po::value<bool>(&opt_databases)->default_value(false)->zero_tokens(),
00508 _("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."))
00509 ("skip-disable-keys,K",
00510 _("'ALTER TABLE tb_name DISABLE KEYS;' and 'ALTER TABLE tb_name ENABLE KEYS;' will not be put in the output."))
00511 ("ignore-table", po::value<string>(),
00512 _("Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names, e.g. --ignore-table=database.table"))
00513 ("insert-ignore", po::value<bool>(&opt_ignore)->default_value(false)->zero_tokens(),
00514 _("Insert rows with INSERT IGNORE."))
00515 ("no-autocommit", po::value<bool>(&opt_autocommit)->default_value(false)->zero_tokens(),
00516 _("Wrap a table's data in START TRANSACTION/COMMIT statements."))
00517 ("no-create-db,n", po::value<bool>(&opt_create_db)->default_value(false)->zero_tokens(),
00518 _("'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."))
00519 ("no-data,d", po::value<bool>(&opt_no_data)->default_value(false)->zero_tokens(),
00520 _("No row information."))
00521 ("replace", po::value<bool>(&opt_replace_into)->default_value(false)->zero_tokens(),
00522 _("Use REPLACE INTO instead of INSERT INTO."))
00523 ("destination-type", po::value<string>()->default_value("stdout"),
00524 _("Where to send output to (stdout|database"))
00525 ("destination-host", po::value<string>(&opt_destination_host)->default_value("localhost"),
00526 _("Hostname for destination db server (requires --destination-type=database)"))
00527 ("destination-port", po::value<uint16_t>(&opt_destination_port)->default_value(4427),
00528 _("Port number for destination db server (requires --destination-type=database)"))
00529 ("destination-user", po::value<string>(&opt_destination_user),
00530 _("User name for destination db server (resquires --destination-type=database)"))
00531 ("destination-password", po::value<string>(&opt_destination_password),
00532 _("Password for destination db server (requires --destination-type=database)"))
00533 ("destination-database", po::value<string>(&opt_destination_database),
00534 _("The database in the destination db server (requires --destination-type=database, not for use with --all-databases)"))
00535 ("my-data-is-mangled", po::value<bool>(&opt_data_is_mangled)->default_value(false)->zero_tokens(),
00536 _("Do not make a UTF8 connection to MySQL, use if you have UTF8 data in a non-UTF8 table"))
00537 ;
00538
00539 po::options_description client_options(_("Options specific to the client"));
00540 client_options.add_options()
00541 ("host,h", po::value<string>(¤t_host)->default_value("localhost"),
00542 _("Connect to host."))
00543 ("password,P", po::value<string>(&password)->default_value(PASSWORD_SENTINEL),
00544 _("Password to use when connecting to server. If password is not given it's solicited on the tty."))
00545 ("port,p", po::value<uint32_t>(&opt_drizzle_port)->default_value(0),
00546 _("Port number to use for connection."))
00547 ("user,u", po::value<string>(¤t_user)->default_value(UserDetect().getUser()),
00548 _("User for login if not current user."))
00549 ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
00550 _("The protocol of connection (mysql or drizzle)."))
00551 ;
00552
00553 po::options_description hidden_options(_("Hidden Options"));
00554 hidden_options.add_options()
00555 ("database-used", po::value<vector<string> >(), _("Used to select the database"))
00556 ("Table-used", po::value<vector<string> >(), _("Used to select the tables"))
00557 ;
00558
00559 po::options_description all_options(_("Allowed Options + Hidden Options"));
00560 all_options.add(commandline_options).add(dump_options).add(client_options).add(hidden_options);
00561
00562 po::options_description long_options(_("Allowed Options"));
00563 long_options.add(commandline_options).add(dump_options).add(client_options);
00564
00565 std::string system_config_dir_dump(SYSCONFDIR);
00566 system_config_dir_dump.append("/drizzle/drizzledump.cnf");
00567
00568 std::string system_config_dir_client(SYSCONFDIR);
00569 system_config_dir_client.append("/drizzle/client.cnf");
00570
00571 std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
00572
00573 if (user_config_dir.compare(0, 2, "~/") == 0)
00574 {
00575 char *homedir;
00576 homedir= getenv("HOME");
00577 if (homedir != NULL)
00578 user_config_dir.replace(0, 1, homedir);
00579 }
00580
00581 po::positional_options_description p;
00582 p.add("database-used", 1);
00583 p.add("Table-used",-1);
00584
00585 md_result_file= stdout;
00586
00587 po::variables_map vm;
00588
00589
00590 int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
00591
00592 po::store(po::command_line_parser(argc, argv).style(style).
00593 options(all_options).positional(p).
00594 extra_parser(parse_password_arg).run(), vm);
00595
00596 if (! vm.count("no-defaults"))
00597 {
00598 std::string user_config_dir_dump(user_config_dir);
00599 user_config_dir_dump.append("/drizzle/drizzledump.cnf");
00600
00601 std::string user_config_dir_client(user_config_dir);
00602 user_config_dir_client.append("/drizzle/client.cnf");
00603
00604 ifstream user_dump_ifs(user_config_dir_dump.c_str());
00605 po::store(parse_config_file(user_dump_ifs, dump_options), vm);
00606
00607 ifstream user_client_ifs(user_config_dir_client.c_str());
00608 po::store(parse_config_file(user_client_ifs, client_options), vm);
00609
00610 ifstream system_dump_ifs(system_config_dir_dump.c_str());
00611 po::store(parse_config_file(system_dump_ifs, dump_options), vm);
00612
00613 ifstream system_client_ifs(system_config_dir_client.c_str());
00614 po::store(parse_config_file(system_client_ifs, client_options), vm);
00615 }
00616
00617 po::notify(vm);
00618
00619 if ((not vm.count("database-used") && not vm.count("Table-used")
00620 && not opt_alldbs && path.empty())
00621 || (vm.count("help")) || vm.count("version"))
00622 {
00623 printf(_("Drizzledump %s build %s, for %s-%s (%s)\n"),
00624 drizzle_version(), VERSION, HOST_VENDOR, HOST_OS, HOST_CPU);
00625 if (vm.count("version"))
00626 exit(0);
00627 puts("");
00628 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"));
00629 puts(_("Dumps definitions and data from a Drizzle database server"));
00630 printf(_("Usage: %s [OPTIONS] database [tables]\n"), progname.c_str());
00631 printf(_("OR %s [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\n"),
00632 progname.c_str());
00633 printf(_("OR %s [OPTIONS] --all-databases [OPTIONS]\n"), progname.c_str());
00634 cout << long_options;
00635 if (vm.count("help"))
00636 exit(0);
00637 else
00638 exit(1);
00639 }
00640
00641
00642
00643 opt_drop= not vm.count("skip-drop-table");
00644 opt_comments= not vm.count("skip-comments");
00645 extended_insert= not vm.count("skip-extended-insert");
00646 opt_dump_date= not vm.count("skip-dump-date");
00647 opt_disable_keys= not vm.count("skip-disable-keys");
00648 opt_quoted= not vm.count("skip-quote-names");
00649
00650 if (vm.count("protocol"))
00651 {
00652 boost::to_lower(opt_protocol);
00653 if (not opt_protocol.compare("mysql"))
00654 use_drizzle_protocol=false;
00655 else if (not opt_protocol.compare("drizzle"))
00656 use_drizzle_protocol=true;
00657 else
00658 {
00659 cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
00660 exit(-1);
00661 }
00662 }
00663
00664 if (vm.count("port"))
00665 {
00666
00667
00668
00669
00670 if (opt_drizzle_port > 65535)
00671 {
00672 fprintf(stderr, _("Value supplied for port is not valid.\n"));
00673 exit(-1);
00674 }
00675 }
00676
00677 if (vm.count("password"))
00678 {
00679 if (!opt_password.empty())
00680 opt_password.erase();
00681 if (password == PASSWORD_SENTINEL)
00682 {
00683 opt_password= "";
00684 }
00685 else
00686 {
00687 opt_password= password;
00688 tty_password= false;
00689 }
00690 }
00691 else
00692 {
00693 tty_password= true;
00694 }
00695
00696 if (! path.empty())
00697 {
00698 opt_disable_keys= 0;
00699 }
00700
00701 if (vm.count("skip-opt"))
00702 {
00703 extended_insert= opt_drop= create_options= 0;
00704 opt_disable_keys= 0;
00705 }
00706
00707 if (opt_compact)
00708 {
00709 opt_comments= opt_drop= opt_disable_keys= 0;
00710 }
00711
00712 if (vm.count("opt"))
00713 {
00714 extended_insert= opt_drop= create_options= 1;
00715 opt_disable_keys= 1;
00716 }
00717
00718 if (vm.count("tables"))
00719 {
00720 opt_databases= false;
00721 }
00722
00723 if (vm.count("ignore-table"))
00724 {
00725 if (!strchr(vm["ignore-table"].as<string>().c_str(), '.'))
00726 {
00727 fprintf(stderr, _("Illegal use of option --ignore-table=<database>.<table>\n"));
00728 exit(EXIT_ARGUMENT_INVALID);
00729 }
00730 string tmpptr(vm["ignore-table"].as<string>());
00731 ignore_table.insert(tmpptr);
00732 }
00733
00734 if (vm.count("skip-create"))
00735 {
00736 opt_create_db= opt_no_create_info= create_options= false;
00737 }
00738
00739 exit_code= get_options();
00740 if (exit_code)
00741 {
00742 free_resources();
00743 exit(exit_code);
00744 }
00745 try
00746 {
00747 db_connection = new DrizzleDumpConnection(current_host, opt_drizzle_port,
00748 current_user, opt_password, use_drizzle_protocol);
00749 }
00750 catch (std::exception&)
00751 {
00752 maybe_exit(EX_DRIZZLEERR);
00753 }
00754
00755 if ((db_connection->getServerType() == ServerDetect::SERVER_MYSQL_FOUND) and (not opt_data_is_mangled))
00756 db_connection->queryNoResult("SET NAMES 'utf8'");
00757
00758 if (vm.count("destination-type"))
00759 {
00760 string tmp_destination(vm["destination-type"].as<string>());
00761 if (tmp_destination.compare("database") == 0)
00762 opt_destination= DESTINATION_DB;
00763 else if (tmp_destination.compare("stdout") == 0)
00764 opt_destination= DESTINATION_STDOUT;
00765 else
00766 exit(EXIT_ARGUMENT_INVALID);
00767 }
00768
00769
00770 if (path.empty() && vm.count("database-used"))
00771 {
00772 string database_used= *vm["database-used"].as< vector<string> >().begin();
00773 write_header((char *)database_used.c_str());
00774 }
00775
00776 if ((opt_lock_all_tables) && do_flush_tables_read_lock())
00777 goto err;
00778 if (opt_single_transaction && start_transaction())
00779 goto err;
00780 if (opt_lock_all_tables)
00781 db_connection->queryNoResult("FLUSH LOGS");
00782
00783 if (opt_alldbs)
00784 {
00785 dump_all_databases();
00786 dump_all_tables();
00787 }
00788 if (vm.count("database-used") && vm.count("Table-used") && not opt_databases)
00789 {
00790 string database_used= *vm["database-used"].as< vector<string> >().begin();
00791
00792 dump_selected_tables(database_used, vm["Table-used"].as< vector<string> >());
00793 }
00794
00795 if (vm.count("Table-used") && opt_databases)
00796 {
00797 vector<string> database_used= vm["database-used"].as< vector<string> >();
00798 vector<string> table_used= vm["Table-used"].as< vector<string> >();
00799
00800 for (vector<string>::iterator it= table_used.begin();
00801 it != table_used.end();
00802 ++it)
00803 {
00804 database_used.insert(database_used.end(), *it);
00805 }
00806
00807 dump_databases(database_used);
00808 dump_all_tables();
00809 }
00810
00811 if (vm.count("database-used") && not vm.count("Table-used"))
00812 {
00813 dump_databases(vm["database-used"].as< vector<string> >());
00814 dump_all_tables();
00815 }
00816
00817 if (opt_destination == DESTINATION_STDOUT)
00818 generate_dump();
00819 else
00820 generate_dump_db();
00821
00822
00823 if (md_result_file && fflush(md_result_file))
00824 {
00825 if (!first_error)
00826 first_error= EX_DRIZZLEERR;
00827 goto err;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836 err:
00837 delete db_connection;
00838 delete destination_connection;
00839 if (path.empty())
00840 write_footer(md_result_file);
00841 free_resources();
00842
00843 if (stderror_file)
00844 fclose(stderror_file);
00845 }
00846
00847 catch(exception &err)
00848 {
00849 cerr << err.what() << endl;
00850 }
00851
00852 return(first_error);
00853 }