~ubuntu-branches/ubuntu/quantal/zeroc-ice/quantal

« back to all changes in this revision

Viewing changes to cpp/src/IceStorm/FreezeDB/Migrate.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cleto Martin Angelina
  • Date: 2011-04-25 18:44:24 UTC
  • mfrom: (6.1.14 sid)
  • Revision ID: james.westby@ubuntu.com-20110425184424-sep9i9euu434vq4c
Tags: 3.4.1-7
* Bug fix: "libdb5.1-java.jar was renamed to db.jar", thanks to Ondřej
  Surý (Closes: #623555).
* Bug fix: "causes noise in php5", thanks to Jayen Ashar (Closes:
  #623533).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// **********************************************************************
 
2
//
 
3
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
 
4
//
 
5
// This copy of Ice is licensed to you under the terms described in the
 
6
// ICE_LICENSE file included in this distribution.
 
7
//
 
8
// **********************************************************************
 
9
 
 
10
#include <IceUtil/DisableWarnings.h>
 
11
#include <Freeze/Freeze.h>
 
12
 
 
13
#include <IceStorm/IceStormInternal.h>
 
14
 
 
15
#include <IceStorm/FreezeDB/SubscriberMap.h>
 
16
#include <IceStorm/FreezeDB/LLUMap.h>
 
17
#include <IceStorm/FreezeDB/V32FormatDB.h>
 
18
#include <IceStorm/FreezeDB/V31FormatDB.h>
 
19
 
 
20
using namespace std;
 
21
using namespace Ice;
 
22
using namespace IceStorm;
 
23
 
 
24
class Client : public Application
 
25
{
 
26
public:
 
27
 
 
28
    void usage();
 
29
    virtual int run(int, char*[]);
 
30
 
 
31
private:
 
32
 
 
33
    void v32migrate(const Freeze::ConnectionPtr&, SubscriberMap&);
 
34
    void v31migrate(const Freeze::ConnectionPtr&, SubscriberMap&);
 
35
};
 
36
 
 
37
//COMPILERFIX: Borland C++ 2010 doesn't support wmain for console applications.
 
38
#if defined(_WIN32 ) && !defined(__BCPLUSPLUS__)
 
39
 
 
40
int
 
41
wmain(int argc, wchar_t* argv[])
 
42
 
 
43
#else
 
44
 
 
45
int
 
46
main(int argc, char* argv[])
 
47
 
 
48
#endif
 
49
{
 
50
    Client app;
 
51
    int rc = app.main(argc, argv);
 
52
    return rc;
 
53
}
 
54
 
 
55
void
 
56
Client::usage()
 
57
{
 
58
    cerr << "Usage: " << appName() << " old-env new-env\n";
 
59
    cerr << "\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";
 
62
}
 
63
 
 
64
string
 
65
identityToTopicName(const Ice::Identity& id)
 
66
{
 
67
    //
 
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>.
 
71
    //
 
72
    if(id.category.empty())
 
73
    {
 
74
        return id.name;
 
75
    }
 
76
 
 
77
    assert(id.name.length() > 6 && id.name.compare(0, 6, "topic.") == 0);
 
78
    return id.name.substr(6);
 
79
}
 
80
 
 
81
void
 
82
Client::v32migrate(const Freeze::ConnectionPtr& oldCon, SubscriberMap& subscriberMap)
 
83
{
 
84
    // We should not create the old database.
 
85
    V32Format topicMap(oldCon, "topics", false);
 
86
    Freeze::TransactionHolder oldTxn(oldCon);
 
87
 
 
88
    for(V32Format::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p)
 
89
    {
 
90
        // First the placeholder record for the topic.
 
91
        SubscriberRecordKey key;
 
92
        key.topic = p->first;
 
93
        SubscriberRecord rec;
 
94
        rec.link = false;
 
95
        rec.cost = 0;
 
96
        subscriberMap.put(SubscriberMap::value_type(key, rec));
 
97
 
 
98
        string topicName = identityToTopicName(key.topic);
 
99
        
 
100
        // Next each link.
 
101
        for(LinkRecordSeq::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
 
102
        {
 
103
            Ice::Identity id = q->theTopic->ice_getIdentity();
 
104
            key.id = id;
 
105
 
 
106
            rec.id = id;
 
107
            rec.obj = q->obj;
 
108
            rec.theTopic = q->theTopic;
 
109
            rec.topicName = topicName;
 
110
            rec.link = true;
 
111
            rec.cost = q->cost;
 
112
 
 
113
            subscriberMap.put(SubscriberMap::value_type(key, rec));
 
114
        }
 
115
    }
 
116
 
 
117
    oldTxn.rollback();
 
118
}
 
119
 
 
120
void
 
121
Client::v31migrate(const Freeze::ConnectionPtr& oldCon, SubscriberMap& subscriberMap)
 
122
{
 
123
 
 
124
    // We should not create the old database.
 
125
    V31Format topicMap(oldCon, "topics", false);
 
126
    Freeze::TransactionHolder oldTxn(oldCon);
 
127
 
 
128
    for(V31Format::const_iterator p = topicMap.begin(); p != topicMap.end(); ++p)
 
129
    {
 
130
        // First the placeholder record for the topic.
 
131
        SubscriberRecordKey key;
 
132
        key.topic.name = p->first;
 
133
        SubscriberRecord rec;
 
134
        rec.link = false;
 
135
        rec.cost = 0;
 
136
        subscriberMap.put(SubscriberMap::value_type(key, rec));
 
137
 
 
138
        string topicName = identityToTopicName(key.topic);
 
139
        
 
140
        // Next each link.
 
141
        for(LinkRecordDict::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
 
142
        {
 
143
            Ice::Identity id = q->second.theTopic->ice_getIdentity();
 
144
            key.id = id;
 
145
 
 
146
            rec.id = id;
 
147
            rec.obj = q->second.obj;
 
148
            rec.theTopic = q->second.theTopic;
 
149
            rec.topicName = topicName;
 
150
            rec.link = true;
 
151
            rec.cost = q->second.cost;
 
152
 
 
153
            subscriberMap.put(SubscriberMap::value_type(key, rec));
 
154
        }
 
155
    }
 
156
 
 
157
    oldTxn.rollback();
 
158
}
 
159
 
 
160
int
 
161
Client::run(int argc, char* argv[])
 
162
{
 
163
    if(argc != 3)
 
164
    {
 
165
        usage();
 
166
        return EXIT_FAILURE;
 
167
    }
 
168
    
 
169
    string oldEnvName = argv[1];
 
170
    string newEnvName = argv[2];
 
171
 
 
172
    if(oldEnvName == newEnvName)
 
173
    {
 
174
        cerr << argv[0] << ": The database environment names must be different" << endl;
 
175
        return EXIT_FAILURE;
 
176
    }
 
177
 
 
178
    bool migrate31 = false;
 
179
 
 
180
    Freeze::ConnectionPtr oldCon = Freeze::createConnection(communicator(), oldEnvName);
 
181
    Freeze::Catalog catalog(oldCon, Freeze::catalogName());
 
182
    if(catalog.size() != 1 || catalog.begin()->first != "topics")
 
183
    {
 
184
        cerr << argv[0] << ": The old database environment does not contain an IceStorm database." << endl;
 
185
        return EXIT_FAILURE;
 
186
    }
 
187
    Freeze::CatalogData data = catalog.begin()->second;
 
188
    if(!data.evictor && data.key == "string" && data.value == "::IceStorm::LinkRecordDict")
 
189
    {
 
190
        migrate31 = true;
 
191
    }
 
192
    else if(!data.evictor && data.key == "::Ice::Identity" && data.value == "::IceStorm::LinkRecordSeq")
 
193
    {
 
194
        migrate31 = false;
 
195
    }
 
196
    else
 
197
    {
 
198
        cerr << argv[0] << ": The old environment contains an unrecognized IceStorm database version." << endl;
 
199
        return EXIT_FAILURE;
 
200
    }
 
201
 
 
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);
 
207
 
 
208
    if(migrate31)
 
209
    {
 
210
        v31migrate(oldCon, subscriberMap);
 
211
    }
 
212
    else
 
213
    {
 
214
        v32migrate(oldCon, subscriberMap);
 
215
    }
 
216
 
 
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;
 
221
    llu.generation = 1;
 
222
    llu.iteration = 0;
 
223
    lluMap.put(LLUMap::value_type("_manager", llu));
 
224
 
 
225
    newTxn.commit();
 
226
 
 
227
    return 0;
 
228
}