// ********************************************************************** // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #include #include #include #include #include #include #include #include using namespace std; using namespace Ice; using namespace IceStorm; using namespace IceStormElection; class Client : public Application { public: void usage(); virtual int run(int, char*[]); }; #ifdef _WIN32 int wmain(int argc, wchar_t* argv[]) #else int main(int argc, char* argv[]) #endif { Client app; return app.main(argc, argv); } void Client::usage() { cerr << "Usage: " << appName() << " \n"; cerr << "Options:\n" "-h, --help Show this message.\n" "-v, --version Display version.\n" "--import FILE Import database from FILE.\n" "--export FILE Export database to FILE.\n" "--dbhome DIR The database directory.\n" "-d, --debug Print debug messages.\n" ; } int Client::run(int argc, char* argv[]) { IceUtilInternal::Options opts; opts.addOpt("h", "help"); opts.addOpt("v", "version"); opts.addOpt("d", "debug"); opts.addOpt("", "import", IceUtilInternal::Options::NeedArg); opts.addOpt("", "export", IceUtilInternal::Options::NeedArg); opts.addOpt("", "dbhome", IceUtilInternal::Options::NeedArg); vector args; try { args = opts.parse(argc, const_cast(argv)); } catch(const IceUtilInternal::BadOptException& e) { cerr << argv[0] << ": " << e.reason << endl; usage(); return EXIT_FAILURE; } if(!args.empty()) { cerr << argv[0] << ": too many arguments" << endl; usage(); return EXIT_FAILURE; } if(opts.isSet("help")) { usage(); return EXIT_SUCCESS; } if(opts.isSet("version")) { cout << ICE_STRING_VERSION << endl; return EXIT_SUCCESS; } if((!opts.isSet("import") && !opts.isSet("export")) || (opts.isSet("import") && opts.isSet("export"))) { cerr << argv[0] << ": either --import or --export must be set" << endl; usage(); return EXIT_FAILURE; } if(!opts.isSet("dbhome")) { cerr << argv[0] << ": database path must be specified" << endl; usage(); return EXIT_FAILURE; } bool debug = opts.isSet("debug"); bool import = opts.isSet("import"); string dbFile = opts.optArg(import ? "import" : "export"); string dbPath = opts.optArg("dbhome"); try { IceStorm::AllData data; EncodingVersion encoding; encoding.major = 1; encoding.minor = 1; communicator()->getProperties()->setProperty("Freeze.DbEnv.IceStorm.DbHome", dbPath); if(import) { cout << "Importing database to directory " << dbPath << " from file " << dbFile << endl; if(!IceUtilInternal::directoryExists(dbPath)) { cerr << argv[0] << ": output directory does not exist: " << dbPath << endl; return EXIT_FAILURE; } if(!IceUtilInternal::isEmptyDirectory(dbPath)) { cerr << argv[0] << ": output directory is not empty: " << dbPath << endl; return EXIT_FAILURE; } ifstream fs(dbFile.c_str(), ios::binary); if(fs.fail()) { cerr << argv[0] << ": could not open input file: " << strerror(errno) << endl; return EXIT_FAILURE; } fs.unsetf(ios::skipws); fs.seekg(0, ios::end); streampos fileSize = fs.tellg(); fs.seekg(0, ios::beg); vector buf; buf.reserve(static_cast(fileSize)); buf.insert(buf.begin(), istream_iterator(fs), istream_iterator()); fs.close(); string type; int version; Ice::InputStreamPtr stream = Ice::wrapInputStream(communicator(), buf, encoding); stream->read(type); if(type != "IceStorm") { cerr << argv[0] << ": incorrect input file type: " << type << endl; return EXIT_FAILURE; } stream->read(version); stream->read(data); { Freeze::ConnectionPtr connection = Freeze::createConnection(communicator(), "IceStorm"); Freeze::TransactionHolder txn(connection); if(debug) { cout << "Writing LLU Map:" << endl; } IceStorm::LLUMap llumap(connection, "llu"); for(StringLogUpdateDict::const_iterator p = data.llus.begin(); p != data.llus.end(); ++p) { if(debug) { cout << " KEY = " << p->first << endl; } llumap.put(*p); } if(debug) { cout << "Writing Subscriber Map:" << endl; } IceStorm::SubscriberMap subscribers(connection, "subscribers"); for(SubscriberRecordDict::const_iterator q = data.subscribers.begin(); q != data.subscribers.end(); ++q) { if(debug) { cout << " KEY = TOPIC(" << communicator()->identityToString(q->first.topic) << ") ID(" << communicator()->identityToString(q->first.id) << ")" <identityToString(q->first.topic) << ") ID(" << communicator()->identityToString(q->first.id) << ")" <write("IceStorm"); stream->write(ICE_INT_VERSION); stream->write(data); pair buf = stream->finished(); ofstream fs(IceUtilInternal::streamFilename(dbFile).c_str(), ios::binary); if(fs.fail()) { cerr << argv[0] << ": could not open output file: " << strerror(errno) << endl; return EXIT_FAILURE; } fs.write(reinterpret_cast(buf.first), buf.second - buf.first); fs.close(); } } catch(const IceUtil::Exception& ex) { cerr << argv[0] << ": " << (import ? "import" : "export") << " failed:\n" << ex << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }