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