12 #include <Ice/ConsoleUtil.h>
16 #include <IceUtil/DisableWarnings.h>
17 #include <IceUtil/FileUtil.h>
18 #include <IceUtil/Options.h>
26 class Client :
public Ice::Application
30 virtual int run(
int,
char*[]);
36 wmain(
int argc,
wchar_t* argv[])
41 main(
int argc,
char* argv[])
46 return app.main(argc, argv);
52 consoleErr <<
"Usage: " << appName() <<
" <options>\n";
53 consoleErr <<
"Options:\n"
54 "-h, --help Show this message.\n"
55 "-v, --version Display version.\n"
56 "--import FILE Import database from FILE.\n"
57 "--export FILE Export database to FILE.\n"
58 "--dbhome DIR Source or target database environment.\n"
59 "--dbpath DIR Source or target database environment.\n"
60 "--mapsize VALUE Set LMDB map size in MB (optional, import only).\n"
61 "-d, --debug Print debug messages.\n";
67 IceUtilInternal::Options opts;
68 opts.addOpt(
"h",
"help");
69 opts.addOpt(
"v",
"version");
70 opts.addOpt(
"d",
"debug");
71 opts.addOpt(
"",
"import", IceUtilInternal::Options::NeedArg);
72 opts.addOpt(
"",
"export", IceUtilInternal::Options::NeedArg);
73 opts.addOpt(
"",
"dbhome", IceUtilInternal::Options::NeedArg);
74 opts.addOpt(
"",
"dbpath", IceUtilInternal::Options::NeedArg);
75 opts.addOpt(
"",
"mapsize", IceUtilInternal::Options::NeedArg);
80 args = opts.parse(argc,
const_cast<const char**
>(argv));
82 catch (
const IceUtilInternal::BadOptException& e)
84 consoleErr << argv[0] <<
": " << e.reason << endl;
90 consoleErr << argv[0] <<
": too many arguments" << endl;
95 if (opts.isSet(
"help"))
101 if (opts.isSet(
"version"))
103 consoleOut << ICE_STRING_VERSION << endl;
107 if (!(opts.isSet(
"import") ^ opts.isSet(
"export")))
109 consoleErr << argv[0] <<
": either --import or --export must be set" << endl;
114 if (!(opts.isSet(
"dbhome") ^ opts.isSet(
"dbpath")))
116 consoleErr << argv[0]
117 <<
": set the database environment directory with either --dbhome or --dbpath"
123 bool debug = opts.isSet(
"debug");
124 bool import = opts.isSet(
"import");
125 string dbFile = opts.optArg(
import ?
"import" :
"export");
127 if (opts.isSet(
"dbhome"))
129 dbPath = opts.optArg(
"dbhome");
133 dbPath = opts.optArg(
"dbpath");
136 string mapSizeStr = opts.optArg(
"mapsize");
150 consoleOut <<
"Importing database to directory " << dbPath <<
" from file " << dbFile
155 consoleErr << argv[0] <<
": output directory does not exist: " << dbPath << endl;
159 if (!IceUtilInternal::isEmptyDirectory(dbPath))
161 consoleErr << argv[0] <<
": output directory is not empty: " << dbPath << endl;
165 ifstream fs(IceUtilInternal::streamFilename(dbFile).c_str(), ios::binary);
168 consoleErr << argv[0] <<
": could not open input file: " << strerror(errno) << endl;
171 fs.unsetf(ios::skipws);
173 fs.seekg(0, ios::end);
174 streampos fileSize = fs.tellg();
179 consoleErr << argv[0] <<
": empty input file" << endl;
183 fs.seekg(0, ios::beg);
185 vector<Ice::Byte> buf;
186 buf.reserve(
static_cast<size_t>(fileSize));
187 buf.insert(buf.begin(), istream_iterator<Ice::Byte>(fs), istream_iterator<Ice::Byte>());
196 if (type !=
"IceStorm")
198 consoleErr << argv[0] <<
": incorrect input file type: " << type << endl;
201 stream.read(version);
210 consoleOut <<
"Writing LLU Map:" << endl;
216 for (StringLogUpdateDict::const_iterator p =
data.llus.begin();
217 p !=
data.llus.end();
222 consoleOut <<
" KEY = " << p->first << endl;
224 lluMap.put(txn, p->first, p->second);
229 consoleOut <<
"Writing Subscriber Map:" << endl;
233 Dbi<SubscriberRecordKey, SubscriberRecord, IceDB::IceContext, Ice::OutputStream>
234 subscriberMap(txn,
"subscribers",
dbContext, MDB_CREATE);
236 for (SubscriberRecordDict::const_iterator
q =
data.subscribers.begin();
237 q !=
data.subscribers.end();
242 consoleOut <<
" KEY = TOPIC("
243 << communicator()->identityToString(
q->first.topic) <<
") ID("
244 << communicator()->identityToString(
q->first.id) <<
")" << endl;
246 subscriberMap.put(txn,
q->first,
q->second);
255 consoleOut <<
"Exporting database from directory " << dbPath <<
" to file " << dbFile
264 consoleOut <<
"Reading LLU Map:" << endl;
273 lluCursor(lluMap, txn);
274 while (lluCursor.get(
s, llu, MDB_NEXT))
278 consoleOut <<
" KEY = " <<
s << endl;
280 data.llus.insert(std::make_pair(
s, llu));
286 consoleOut <<
"Reading Subscriber Map:" << endl;
290 Dbi<SubscriberRecordKey, SubscriberRecord, IceDB::IceContext, Ice::OutputStream>
291 subscriberMap(txn,
"subscribers",
dbContext, 0);
299 subCursor(subscriberMap, txn);
300 while (subCursor.get(key, record, MDB_NEXT))
304 consoleOut <<
" KEY = TOPIC("
305 << communicator()->identityToString(key.
topic) <<
") ID("
306 << communicator()->identityToString(key.
id) <<
")" << endl;
308 data.subscribers.insert(std::make_pair(key, record));
317 stream.write(
"IceStorm");
318 stream.write(ICE_INT_VERSION);
321 ofstream fs(IceUtilInternal::streamFilename(dbFile).c_str(), ios::binary);
324 consoleErr << argv[0] <<
": could not open output file: " << strerror(errno)
328 fs.write(
reinterpret_cast<const char*
>(stream.b.begin()), stream.b.size());
332 catch (
const IceUtil::Exception& ex)
334 consoleErr << argv[0] <<
": " << (
import ?
"import" :
"export") <<
" failed:\n"