1
// **********************************************************************
3
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
5
// This copy of Ice is licensed to you under the terms described in the
6
// ICE_LICENSE file included in this distribution.
8
// **********************************************************************
10
#include <IceUtil/DisableWarnings.h>
11
#include <Freeze/Freeze.h>
13
#include <IceStorm/IceStormInternal.h>
15
#include <IceStorm/FreezeDB/SubscriberMap.h>
16
#include <IceStorm/FreezeDB/LLUMap.h>
17
#include <IceStorm/FreezeDB/V32FormatDB.h>
18
#include <IceStorm/FreezeDB/V31FormatDB.h>
22
using namespace IceStorm;
24
class Client : public Application
29
virtual int run(int, char*[]);
33
void v32migrate(const Freeze::ConnectionPtr&, SubscriberMap&);
34
void v31migrate(const Freeze::ConnectionPtr&, SubscriberMap&);
37
//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications.
38
#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__)
41
wmain(int argc, wchar_t* argv[])
46
main(int argc, char* argv[])
51
int rc = app.main(argc, argv);
58
cerr << "Usage: " << appName() << " old-env new-env\n";
60
cerr << "This utility upgrades a 3.1 or 3.2 IceStorm database environment\n";
61
cerr << "to a 3.3 or superior IceStorm database environment.\n";
65
identityToTopicName(const Ice::Identity& id)
68
// Work out the topic name. If the category is empty then we're in
69
// backwards compatibility mode and the name is just
70
// identity.name. Otherwise identity.name is topic.<topicname>.
72
if(id.category.empty())
77
assert(id.name.length() > 6 && id.name.compare(0, 6, "topic.") == 0);
78
return id.name.substr(6);
82
Client::v32migrate(const Freeze::ConnectionPtr& oldCon, SubscriberMap& subscriberMap)
84
// We should not create the old database.
85
V32Format topicMap(oldCon, "topics", false);
86
Freeze::TransactionHolder oldTxn(oldCon);
88
for(V32Format::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p)
90
// First the placeholder record for the topic.
91
SubscriberRecordKey key;
96
subscriberMap.put(SubscriberMap::value_type(key, rec));
98
string topicName = identityToTopicName(key.topic);
101
for(LinkRecordSeq::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
103
Ice::Identity id = q->theTopic->ice_getIdentity();
108
rec.theTopic = q->theTopic;
109
rec.topicName = topicName;
113
subscriberMap.put(SubscriberMap::value_type(key, rec));
121
Client::v31migrate(const Freeze::ConnectionPtr& oldCon, SubscriberMap& subscriberMap)
124
// We should not create the old database.
125
V31Format topicMap(oldCon, "topics", false);
126
Freeze::TransactionHolder oldTxn(oldCon);
128
for(V31Format::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p)
130
// First the placeholder record for the topic.
131
SubscriberRecordKey key;
132
key.topic.name = p->first;
133
SubscriberRecord rec;
136
subscriberMap.put(SubscriberMap::value_type(key, rec));
138
string topicName = identityToTopicName(key.topic);
141
for(LinkRecordDict::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
143
Ice::Identity id = q->second.theTopic->ice_getIdentity();
147
rec.obj = q->second.obj;
148
rec.theTopic = q->second.theTopic;
149
rec.topicName = topicName;
151
rec.cost = q->second.cost;
153
subscriberMap.put(SubscriberMap::value_type(key, rec));
161
Client::run(int argc, char* argv[])
169
string oldEnvName = argv[1];
170
string newEnvName = argv[2];
172
if(oldEnvName == newEnvName)
174
cerr << argv[0] << ": The database environment names must be different" << endl;
178
bool migrate31 = false;
180
Freeze::ConnectionPtr oldCon = Freeze::createConnection(communicator(), oldEnvName);
181
Freeze::Catalog catalog(oldCon, Freeze::catalogName());
182
if(catalog.size() != 1 || catalog.begin()->first != "topics")
184
cerr << argv[0] << ": The old database environment does not contain an IceStorm database." << endl;
187
Freeze::CatalogData data = catalog.begin()->second;
188
if(!data.evictor && data.key == "string" && data.value == "::IceStorm::LinkRecordDict")
192
else if(!data.evictor && data.key == "::Ice::Identity" && data.value == "::IceStorm::LinkRecordSeq")
198
cerr << argv[0] << ": The old environment contains an unrecognized IceStorm database version." << endl;
202
// Creating the new database is fine.
203
Freeze::ConnectionPtr newCon = Freeze::createConnection(communicator(), newEnvName);
204
SubscriberMap subscriberMap(newCon, "subscribers");
205
LLUMap lluMap(newCon, "llu");
206
Freeze::TransactionHolder newTxn(newCon);
210
v31migrate(oldCon, subscriberMap);
214
v32migrate(oldCon, subscriberMap);
217
// We need to write a record in the LLU map so that if this
218
// database is used for a migration this database will be picked
219
// as the latest. We use generation 1 since the default is 0.
220
IceStormElection::LogUpdate llu;
223
lluMap.put(LLUMap::value_type("_manager", llu));