diff options
author | Matthew Newhook <matthew@zeroc.com> | 2008-03-12 12:34:03 +0800 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2008-03-12 12:34:03 +0800 |
commit | 471790b096f5d2ec24e0108ecedf801fc5df4a87 (patch) | |
tree | ae9c36953f9fe462dc0dd8075f020a10bd7bc4c7 /cpp/src/IceStorm/Migrate.cpp | |
parent | Bug 2745. (diff) | |
download | ice-471790b096f5d2ec24e0108ecedf801fc5df4a87.tar.bz2 ice-471790b096f5d2ec24e0108ecedf801fc5df4a87.tar.xz ice-471790b096f5d2ec24e0108ecedf801fc5df4a87.zip |
merge of bug2737.
Diffstat (limited to 'cpp/src/IceStorm/Migrate.cpp')
-rw-r--r-- | cpp/src/IceStorm/Migrate.cpp | 145 |
1 files changed, 116 insertions, 29 deletions
diff --git a/cpp/src/IceStorm/Migrate.cpp b/cpp/src/IceStorm/Migrate.cpp index f4f3132f6a8..4ffa27a82e5 100644 --- a/cpp/src/IceStorm/Migrate.cpp +++ b/cpp/src/IceStorm/Migrate.cpp @@ -8,11 +8,15 @@ // ********************************************************************** #include <IceUtil/DisableWarnings.h> -#include <IceStorm/PersistentTopicMap.h> +#include <Freeze/Freeze.h> +#include <Freeze/Catalog.h> // XXX: + #include <IceStorm/SubscriberMap.h> #include <IceStorm/IceStormInternal.h> #include <IceStorm/LLUMap.h> -#include <Freeze/Freeze.h> + +#include <IceStorm/V32FormatDB.h> +#include <IceStorm/V31FormatDB.h> using namespace std; using namespace Ice; @@ -24,6 +28,11 @@ public: void usage(); virtual int run(int, char*[]); + +private: + + void v32migrate(const Freeze::ConnectionPtr&, SubscriberMap&); + void v31migrate(const Freeze::ConnectionPtr&, SubscriberMap&); }; int @@ -57,35 +66,14 @@ identityToTopicName(const Ice::Identity& id) return id.name.substr(6); } -int -Client::run(int argc, char* argv[]) +void +Client::v32migrate(const Freeze::ConnectionPtr& oldCon, SubscriberMap& subscriberMap) { - if(argc != 3) - { - usage(); - return EXIT_FAILURE; - } - string oldEnvName = argv[1]; - string newEnvName = argv[2]; - - if(oldEnvName == newEnvName) - { - cerr << argv[0] << ": database environment names must be different" << endl; - return EXIT_FAILURE; - } - - Freeze::ConnectionPtr oldCon = Freeze::createConnection(communicator(), oldEnvName); - Freeze::ConnectionPtr newCon = Freeze::createConnection(communicator(), newEnvName); - // We should not create the old database. - PersistentTopicMap topicMap(oldCon, "topics", false); - // Creating the new database is fine. - SubscriberMap subscriberMap(newCon, "subscribers"); - LLUMap lluMap(newCon, "llu"); - + V32Format topicMap(oldCon, "topics", false); Freeze::TransactionHolder oldTxn(oldCon); - Freeze::TransactionHolder newTxn(newCon); - for(PersistentTopicMap::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p) + + for(V32Format::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p) { // First the placeholder record for the topic. SubscriberRecordKey key; @@ -114,6 +102,106 @@ Client::run(int argc, char* argv[]) } } + oldTxn.rollback(); +} + +void +Client::v31migrate(const Freeze::ConnectionPtr& oldCon, SubscriberMap& subscriberMap) +{ + + // We should not create the old database. + V31Format topicMap(oldCon, "topics", false); + Freeze::TransactionHolder oldTxn(oldCon); + + for(V31Format::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p) + { + // First the placeholder record for the topic. + SubscriberRecordKey key; + key.topic.name = p->first; + SubscriberRecord rec; + rec.link = false; + rec.cost = 0; + subscriberMap.put(SubscriberMap::value_type(key, rec)); + + string topicName = identityToTopicName(key.topic); + + // Next each link. + for(LinkRecordDict::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + Ice::Identity id = q->second.theTopic->ice_getIdentity(); + key.id = id; + + rec.id = id; + rec.obj = q->second.obj; + rec.theTopic = q->second.theTopic; + rec.topicName = topicName; + rec.link = true; + rec.cost = q->second.cost; + + subscriberMap.put(SubscriberMap::value_type(key, rec)); + } + } + + oldTxn.rollback(); +} + +int +Client::run(int argc, char* argv[]) +{ + if(argc != 3) + { + usage(); + return EXIT_FAILURE; + } + + string oldEnvName = argv[1]; + string newEnvName = argv[2]; + + if(oldEnvName == newEnvName) + { + cerr << argv[0] << ": The database environment names must be different" << endl; + return EXIT_FAILURE; + } + + bool migrate31 = false; + + Freeze::ConnectionPtr oldCon = Freeze::createConnection(communicator(), oldEnvName); + Freeze::Catalog catalog(oldCon, Freeze::catalogName()); + if(catalog.size() != 1 || catalog.begin()->first != "topics") + { + cerr << argv[0] << ": The old database environment does not contain an IceStorm database." << endl; + return EXIT_FAILURE; + } + Freeze::CatalogData data = catalog.begin()->second; + if(!data.evictor && data.key == "string" && data.value == "::IceStorm::LinkRecordDict") + { + migrate31 = true; + } + else if(!data.evictor && data.key == "::Ice::Identity" && data.value == "::IceStorm::LinkRecordSeq") + { + migrate31 = false; + } + else + { + cerr << argv[0] << ": The old environment contains an unrecognized IceStorm database version." << endl; + return EXIT_FAILURE; + } + + // Creating the new database is fine. + Freeze::ConnectionPtr newCon = Freeze::createConnection(communicator(), newEnvName); + SubscriberMap subscriberMap(newCon, "subscribers"); + LLUMap lluMap(newCon, "llu"); + Freeze::TransactionHolder newTxn(newCon); + + if(migrate31) + { + v31migrate(oldCon, subscriberMap); + } + else + { + v32migrate(oldCon, subscriberMap); + } + // We need to write a record in the LLU map so that if this // database is used for a migration this database will be picked // as the latest. We use generation 1 since the default is 0. @@ -122,7 +210,6 @@ Client::run(int argc, char* argv[]) llu.iteration = 0; lluMap.put(LLUMap::value_type("_manager", llu)); - oldTxn.rollback(); newTxn.commit(); return 0; |