diff options
author | Matthew Newhook <matthew@zeroc.com> | 2002-03-08 13:47:12 +0000 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2002-03-08 13:47:12 +0000 |
commit | 2ee86c01bdce8ff4fb14120f9603e2d4382a32af (patch) | |
tree | 9ef026ad20f848bf3f4217eebd478804e3740f9f /cpp | |
parent | adding constructors to holder classes (diff) | |
download | ice-2ee86c01bdce8ff4fb14120f9603e2d4382a32af.tar.bz2 ice-2ee86c01bdce8ff4fb14120f9603e2d4382a32af.tar.xz ice-2ee86c01bdce8ff4fb14120f9603e2d4382a32af.zip |
updates for Freeze.
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/demo/Freeze/phonebook/Collocated.cpp | 21 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/Parser.cpp | 21 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBook.ice | 28 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBookI.cpp | 313 | ||||
-rw-r--r-- | cpp/demo/Freeze/phonebook/PhoneBookI.h | 6 | ||||
-rw-r--r-- | cpp/slice/Freeze/DB.ice | 34 | ||||
-rw-r--r-- | cpp/slice/Freeze/DBException.ice | 6 | ||||
-rw-r--r-- | cpp/slice/Freeze/Evictor.ice | 2 | ||||
-rw-r--r-- | cpp/src/Freeze/Application.cpp | 1 | ||||
-rw-r--r-- | cpp/src/Freeze/DBI.cpp | 109 | ||||
-rw-r--r-- | cpp/src/Freeze/DBI.h | 1 | ||||
-rw-r--r-- | cpp/src/Freeze/EvictorI.cpp | 19 | ||||
-rw-r--r-- | cpp/test/Freeze/complex/Client.cpp | 2 | ||||
-rw-r--r-- | cpp/test/Freeze/complex/Complex.ice | 18 | ||||
-rw-r--r-- | cpp/test/Freeze/cursor/Client.cpp | 17 | ||||
-rw-r--r-- | cpp/test/Freeze/dbmap/Client.cpp | 24 |
16 files changed, 411 insertions, 211 deletions
diff --git a/cpp/demo/Freeze/phonebook/Collocated.cpp b/cpp/demo/Freeze/phonebook/Collocated.cpp index ca23cc5bcc1..72f36506f57 100644 --- a/cpp/demo/Freeze/phonebook/Collocated.cpp +++ b/cpp/demo/Freeze/phonebook/Collocated.cpp @@ -14,11 +14,6 @@ using namespace std; using namespace Ice; -using namespace Freeze; - -using namespace std; -using namespace Ice; -using namespace Freeze; class PhoneBookCollocated : public Freeze::Application { @@ -29,7 +24,7 @@ public: { } - virtual int runFreeze(int argc, char* argv[], const DBEnvironmentPtr&); + virtual int runFreeze(int argc, char* argv[], const Freeze::DBEnvironmentPtr&); }; int @@ -40,26 +35,26 @@ main(int argc, char* argv[]) } int -PhoneBookCollocated::runFreeze(int argc, char* argv[], const DBEnvironmentPtr& dbEnv) +PhoneBookCollocated::runFreeze(int argc, char* argv[], const Freeze::DBEnvironmentPtr& dbEnv) { PropertiesPtr properties = communicator()->getProperties(); string value; - DBPtr dbPhoneBook = dbEnv->openDB("phonebook", true); - DBPtr dbContacts = dbEnv->openDB("contacts", true); + Freeze::DBPtr dbPhoneBook = dbEnv->openDB("phonebook", true); + Freeze::DBPtr dbContacts = dbEnv->openDB("contacts", true); // // Create an Evictor for contacts. // - EvictorPtr evictor; + Freeze::EvictorPtr evictor; value = properties->getProperty("PhoneBook.SaveAfterMutatingOperation"); if(!value.empty() && atoi(value.c_str()) > 0) { - evictor = dbContacts->createEvictor(SaveAfterMutatingOperation); + evictor = dbContacts->createEvictor(Freeze::SaveAfterMutatingOperation); } else { - evictor = dbContacts->createEvictor(SaveUponEviction); + evictor = dbContacts->createEvictor(Freeze::SaveUponEviction); } value = properties->getProperty("PhoneBook.EvictorSize"); if(!value.empty()) @@ -83,7 +78,7 @@ PhoneBookCollocated::runFreeze(int argc, char* argv[], const DBEnvironmentPtr& d // Create and install a factory and initializer for contacts. // ObjectFactoryPtr contactFactory = new ContactFactory(phoneBook, evictor); - ServantInitializerPtr contactInitializer = ServantInitializerPtr::dynamicCast(contactFactory); + Freeze::ServantInitializerPtr contactInitializer = Freeze::ServantInitializerPtr::dynamicCast(contactFactory); communicator()->addObjectFactory(contactFactory, "::Contact"); evictor->installServantInitializer(contactInitializer); diff --git a/cpp/demo/Freeze/phonebook/Parser.cpp b/cpp/demo/Freeze/phonebook/Parser.cpp index 86da2f6ad6c..ef22b5b665c 100644 --- a/cpp/demo/Freeze/phonebook/Parser.cpp +++ b/cpp/demo/Freeze/phonebook/Parser.cpp @@ -18,7 +18,6 @@ using namespace std; using namespace Ice; -using namespace Freeze; extern FILE* yyin; @@ -67,7 +66,7 @@ Parser::addContacts(const list<string>& args) cout << "added new contact for `" << *p << "'" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -95,7 +94,7 @@ Parser::findContacts(const list<string>& args) cout << "number of contacts found: " << _foundContacts.size() << endl; printCurrent(); } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -134,7 +133,7 @@ Parser::printCurrent() cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -167,7 +166,7 @@ Parser::setCurrentName(const list<string>& args) cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -200,7 +199,7 @@ Parser::setCurrentAddress(const list<string>& args) cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -233,7 +232,7 @@ Parser::setCurrentPhone(const list<string>& args) cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -260,7 +259,7 @@ Parser::removeCurrent() cout << "no current contact" << endl; } } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -285,7 +284,7 @@ Parser::setEvictorSize(const list<string>& args) { _phoneBook->setEvictorSize(atoi(args.front().c_str())); } - catch(const DBException& ex) + catch(const DatabaseException& ex) { error(ex.message); } @@ -304,10 +303,6 @@ Parser::shutdown() { _phoneBook->shutdown(); } - catch(const DBException& ex) - { - error(ex.message); - } catch(const Exception& ex) { ostringstream s; diff --git a/cpp/demo/Freeze/phonebook/PhoneBook.ice b/cpp/demo/Freeze/phonebook/PhoneBook.ice index 68709b12f5e..9b21a47cee5 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBook.ice +++ b/cpp/demo/Freeze/phonebook/PhoneBook.ice @@ -12,25 +12,29 @@ #define PHONE_BOOK_ICE #include <Ice/Identity.ice> -#include <Freeze/DBException.ice> + +exception DatabaseException +{ + string message; +}; class Contact { - ["nonmutating"] string getName() throws Freeze::DBException; - void setName(string name) throws Freeze::DBException; + ["nonmutating"] string getName(); + void setName(string name) throws DatabaseException; - ["nonmutating"] string getAddress() throws Freeze::DBException; - void setAddress(string address) throws Freeze::DBException; + ["nonmutating"] string getAddress(); + void setAddress(string address); - ["nonmutating"] string getPhone() throws Freeze::DBException; - void setPhone(string phone) throws Freeze::DBException; + ["nonmutating"] string getPhone(); + void setPhone(string phone); // // Yes, destroy() is nonmutating. It doesn't change the state of // the Contact. It removes the Contact completely, but doesn't // touch state. // - ["nonmutating"] void destroy(); + ["nonmutating"] void destroy() throws DatabaseException; string _name; string _address; @@ -42,10 +46,10 @@ sequence<Ice::Identity> Identities; // Needed for slice2freeze interface PhoneBook { - Contact* createContact() throws Freeze::DBException; - ["nonmutating"] Contacts findContacts(string name) throws Freeze::DBException; - void setEvictorSize(int size) throws Freeze::DBException; - ["nonmutating"] void shutdown() throws Freeze::DBException; + Contact* createContact() throws DatabaseException; + ["nonmutating"] Contacts findContacts(string name) throws DatabaseException; + void setEvictorSize(int size) throws DatabaseException; + ["nonmutating"] void shutdown(); }; #endif diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp index 67bb4dfe3ad..23c67d3f509 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.cpp +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.cpp @@ -29,14 +29,15 @@ ContactI::setIdentity(const Identity& ident) string ContactI::getName(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); return _name; } void ContactI::setName(const string& name, const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); + assert(!_identity.name.empty()); _phoneBook->move(_identity, _name, name); _name = name; @@ -45,38 +46,59 @@ ContactI::setName(const string& name, const Ice::Current&) string ContactI::getAddress(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); return _address; } void ContactI::setAddress(const string& address, const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); _address = address; } string ContactI::getPhone(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); return _phone; } void ContactI::setPhone(const string& phone, const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); _phone = phone; } void ContactI::destroy(const Ice::Current&) { - IceUtil::Mutex::Lock sync(*this); // TODO: Reader/Writer lock - assert(!_identity.name.empty()); - _phoneBook->remove(_identity, _name); - _evictor->destroyObject(_identity); + IceUtil::RWRecMutex::RLock sync(*this); + + try + { + assert(!_identity.name.empty()); + _phoneBook->remove(_identity, _name); + + // + // This can throw EvictorDeactivatedException (which indicates + // an internal error). The exception is currently ignored. + // + _evictor->destroyObject(_identity); + } + catch(const Freeze::DBNotFoundException& ex) + { + // + // Raised by remove. Ignore. + // + } + catch(const Freeze::DBException& ex) + { + DatabaseException e; + e.message = ex.message; + throw e; + } } PhoneBookI::PhoneBookI(const ObjectAdapterPtr& adapter, const DBPtr& db, const EvictorPtr& evictor) : @@ -109,7 +131,7 @@ private: ContactPrx PhoneBookI::createContact(const Ice::Current&) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); // // Get a new unique identity. @@ -126,6 +148,9 @@ PhoneBookI::createContact(const Ice::Current&) // Create a new Ice Object in the evictor, using the new identity // and the new Servant. // + // This can throw EvictorDeactivatedException (which indicates + // an internal error). The exception is currently ignored. + // _evictor->createObject(ident, contact); // @@ -133,44 +158,63 @@ PhoneBookI::createContact(const Ice::Current&) // is the empty string. See the comment in getNewIdentity why the // prefix "N" is needed. // - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N"); - Identities identities; - if (p != _nameIdentitiesDict.end()) + try { - identities = p->second; + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N"); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + + identities.push_back(ident); + _nameIdentitiesDict.insert(make_pair(string("N"), identities)); + + // + // Turn the identity into a Proxy and return the Proxy to the + // caller. + // + return IdentityToContact(_adapter)(ident); + } + catch(const Freeze::DBException& ex) + { + DatabaseException e; + e.message = ex.message; + throw e; } - - identities.push_back(ident); - _nameIdentitiesDict.insert(make_pair(string("N"), identities)); - - // - // Turn the identity into a Proxy and return the Proxy to the - // caller. - // - return IdentityToContact(_adapter)(ident); } Contacts PhoneBookI::findContacts(const string& name, const Ice::Current&) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::RLock sync(*this); - // - // Lookup all phone book contacts that match a name, and return - // them to the caller. See the comment in getNewIdentity why the - // prefix "N" is needed. - // - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); - Identities identities; - if (p != _nameIdentitiesDict.end()) + try + { + // + // Lookup all phone book contacts that match a name, and + // return them to the caller. See the comment in + // getNewIdentity why the prefix "N" is needed. + // + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + + Contacts contacts; + contacts.reserve(identities.size()); + transform(identities.begin(), identities.end(), back_inserter(contacts), IdentityToContact(_adapter)); + + return contacts; + } + catch(const Freeze::DBException& ex) { - identities = p->second; + DatabaseException e; + e.message = ex.message; + throw e; } - - Contacts contacts; - contacts.reserve(identities.size()); - transform(identities.begin(), identities.end(), back_inserter(contacts), IdentityToContact(_adapter)); - return contacts; } void @@ -179,7 +223,6 @@ PhoneBookI::setEvictorSize(Int size, const Ice::Current&) // // No synchronization necessary, _evictor is immutable. // - _evictor->setSize(size); } @@ -189,112 +232,158 @@ PhoneBookI::shutdown(const Ice::Current&) // // No synchronization necessary, _adapter is immutable. // - _adapter->getCommunicator()->shutdown(); } void PhoneBookI::remove(const Identity& ident, const string& name) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock - - // - // See the comment in getNewIdentity why the prefix "N" is needed. - // - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); - - // - // If the name isn't found then this is an application - // error. Throw a DBNotFoundException. - // - if (p == _nameIdentitiesDict.end()) - { - throw DBNotFoundException(); - } + IceUtil::RWRecMutex::WLock sync(*this); - Identities identities = p->second; - identities.erase(remove_if(identities.begin(), identities.end(), bind2nd(equal_to<Ice::Identity>(), ident)), - identities.end()); - - if (identities.empty()) + try { - _nameIdentitiesDict.erase(p); + removeI(ident, name); } - else + catch(const Freeze::DBException& ex) { - // - // See the comment in getNewIdentity why the prefix "N" is - // needed. - // - _nameIdentitiesDict.insert(make_pair("N" + name, identities)); + DatabaseException e; + e.message = ex.message; + throw e; } } void PhoneBookI::move(const Identity& ident, const string& oldName, const string& newName) { - IceUtil::RecMutex::Lock sync(*this); // TODO: Reader/Writer lock + IceUtil::RWRecMutex::WLock sync(*this); - // - // Called by ContactI in case the name has been changed. See the - // comment in getNewIdentity why the prefix "N" is needed. - // - remove(ident, oldName); - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + newName); - Identities identities; - if (p != _nameIdentitiesDict.end()) + try + { + // + // Called by ContactI in case the name has been changed. See + // the comment in getNewIdentity why the prefix "N" is needed. + // + removeI(ident, oldName); + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + newName); + Identities identities; + if (p != _nameIdentitiesDict.end()) + { + identities = p->second; + } + identities.push_back(ident); + _nameIdentitiesDict.insert(make_pair("N" + newName, identities)); + } + catch(const Freeze::DBNotFoundException& ex) + { + // + // Raised by remove. This should only happen under very rare + // circumstances if destroy() had gotten to the object prior + // to the setName() operation being dispatched. Ignore the + // exception. + // + } + catch(const Freeze::DBException& ex) { - identities = p->second; + DatabaseException e; + e.message = ex.message; + throw e; } - identities.push_back(ident); - _nameIdentitiesDict.insert(make_pair("N" + newName, identities)); } Identity PhoneBookI::getNewIdentity() { - // - // This code is a bit of a hack. It stores the last identity that - // has been used (or the name component thereof, to be more - // precise) in the _nameIdentitiesDict, with the special prefix - // "ID". Because of this, all "real" names need to be prefixed - // with "N", so that there is no potential for a name clash. - // - - Ice::Long n; - Identities ids; - NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("ID"); - if (p == _nameIdentitiesDict.end()) + try { - n = 0; - } - else - { - ids = p->second; - assert(ids.size() == 1); + // + // This code is a bit of a hack. It stores the last identity + // that has been used (or the name component thereof, to be + // more precise) in the _nameIdentitiesDict, with the special + // prefix "ID". Because of this, all "real" names need to be + // prefixed with "N", so that there is no potential for a name + // clash. + // + + Ice::Long n; + Identities ids; + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("ID"); + if (p == _nameIdentitiesDict.end()) + { + n = 0; + } + else + { + ids = p->second; + assert(ids.size() == 1); #ifdef WIN32 - n = _atoi64(ids.front().name.c_str()) + 1; + n = _atoi64(ids.front().name.c_str()) + 1; #else - n = atoll(ids.front().name.c_str()) + 1; + n = atoll(ids.front().name.c_str()) + 1; #endif - } + } - char s[20]; + char s[20]; #ifdef WIN32 - sprintf(s, "%I64d", n); + sprintf(s, "%I64d", n); #else - sprintf(s, "%lld", n); + sprintf(s, "%lld", n); #endif - Identity id; + Identity id; + + id.name = s; + ids.clear(); + ids.push_back(id); + + _nameIdentitiesDict.insert(make_pair(string("ID"), ids)); + + id.name = s; + id.category = "contact"; + return id; + } + catch(const Freeze::DBException& ex) + { + DatabaseException e; + e.message = ex.message; + throw e; + } +} - id.name = s; - ids.clear(); - ids.push_back(id); +// +// Called with the RWRecMutex already acquired. +// +void +PhoneBookI::removeI(const Identity& ident, const string& name) +{ + // + // See the comment in getNewIdentity why the prefix "N" is + // needed. + // + NameIdentitiesDict::iterator p = _nameIdentitiesDict.find("N" + name); - _nameIdentitiesDict.insert(make_pair(string("ID"), ids)); + // + // If the name isn't found then raise a record not found + // exception. + // + if (p == _nameIdentitiesDict.end()) + { + throw Freeze::DBNotFoundException(__FILE__, __LINE__); + } + + Identities identities = p->second; + identities.erase(remove_if(identities.begin(), identities.end(), bind2nd(equal_to<Ice::Identity>(), ident)), + identities.end()); - id.name = s; - id.category = "contact"; - return id; + if (identities.empty()) + { + _nameIdentitiesDict.erase(p); + } + else + { + // + // See the comment in getNewIdentity why the prefix "N" is + // needed. + // + _nameIdentitiesDict.insert(make_pair("N" + name, identities)); + } } diff --git a/cpp/demo/Freeze/phonebook/PhoneBookI.h b/cpp/demo/Freeze/phonebook/PhoneBookI.h index 09e5c84d8c4..bb341a7b94a 100644 --- a/cpp/demo/Freeze/phonebook/PhoneBookI.h +++ b/cpp/demo/Freeze/phonebook/PhoneBookI.h @@ -23,7 +23,7 @@ typedef IceUtil::Handle<PhoneBookI> PhoneBookIPtr; class ContactI; typedef IceUtil::Handle<ContactI> ContactIPtr; -class ContactI : public Contact, public IceUtil::Mutex +class ContactI : public Contact, public IceUtil::RWRecMutex { public: @@ -49,7 +49,7 @@ private: Ice::Identity _identity; }; -class PhoneBookI : public PhoneBook, public IceUtil::RecMutex +class PhoneBookI : public PhoneBook, public IceUtil::RWRecMutex { public: @@ -66,6 +66,8 @@ public: private: + void removeI(const Ice::Identity&, const std::string&); + Ice::ObjectAdapterPtr _adapter; Freeze::DBPtr _db; Freeze::EvictorPtr _evictor; diff --git a/cpp/slice/Freeze/DB.ice b/cpp/slice/Freeze/DB.ice index ab4d590d9cc..1beffec5a8f 100644 --- a/cpp/slice/Freeze/DB.ice +++ b/cpp/slice/Freeze/DB.ice @@ -284,17 +284,19 @@ local interface DBCursor * * @return The cloned cursor. * - * @throws DBException Raised if the cursor has been closed. + * @throws DBException Raised if a database failure occurred. * **/ - DBCursor clone(); + DBCursor clone() throws DBException; /** * * Close the cursor. Subsequent calls to [close] have no effect. * + * @throws DBException Raised if a database failure occurred. + * **/ - void close(); + void close() throws DBException; }; /** @@ -414,6 +416,28 @@ local interface DB /** * + * Determine if a key is contained in the database. + * + * @param key The key to check. + * + * @return True if the key is contained in the database, false otherwise. + * + * @throws DBNotFoundException Raised if the key was not found in + * the database. + * + * @throws DBDeadlockException Raised if a deadlock occurred. + * + * @throws DBException Raised if any other database failure + * occurred. + * + * @see put + * @see del + * + **/ + bool contains(Key key) throws DBException; + + /** + * * Get a value from a database by it's key. * * @param key The key under which the value is stored in the database @@ -510,11 +534,13 @@ local interface DB * * @return The new Evictor. * + * @throws DBException Raised if the database has been closed. + * * @see Evictor * @see EvictorPersistenceMode * **/ - Evictor createEvictor(EvictorPersistenceMode mode); + Evictor createEvictor(EvictorPersistenceMode mode) throws DBException; }; }; diff --git a/cpp/slice/Freeze/DBException.ice b/cpp/slice/Freeze/DBException.ice index ee06d22cdf2..2abf6d26a95 100644 --- a/cpp/slice/Freeze/DBException.ice +++ b/cpp/slice/Freeze/DBException.ice @@ -24,7 +24,7 @@ module Freeze * @see Evictor * **/ -exception DBException +local exception DBException { /** * @@ -40,7 +40,7 @@ exception DBException * could not be found. * **/ -exception DBNotFoundException extends DBException +local exception DBNotFoundException extends DBException { }; @@ -50,7 +50,7 @@ exception DBNotFoundException extends DBException * this exception by aborting and trying the transaction again. * **/ -exception DBDeadlockException extends DBException +local exception DBDeadlockException extends DBException { }; diff --git a/cpp/slice/Freeze/Evictor.ice b/cpp/slice/Freeze/Evictor.ice index d7813370634..9c1105594a4 100644 --- a/cpp/slice/Freeze/Evictor.ice +++ b/cpp/slice/Freeze/Evictor.ice @@ -55,7 +55,7 @@ local interface ServantInitializer * This exception is raised if the evictor has been deactivated. * **/ -exception EvictorDeactivatedException +local exception EvictorDeactivatedException { }; diff --git a/cpp/src/Freeze/Application.cpp b/cpp/src/Freeze/Application.cpp index 06ca83de335..c3088794a2b 100644 --- a/cpp/src/Freeze/Application.cpp +++ b/cpp/src/Freeze/Application.cpp @@ -41,6 +41,7 @@ Freeze::Application::run(int argc, char* argv[]) cerr << appName() << ": " << ex << ": " << ex.message << endl; status = EXIT_FAILURE; } + // TODO: How does this compile? catch(const Exception& ex) { cerr << appName() << ": " << ex << endl; diff --git a/cpp/src/Freeze/DBI.cpp b/cpp/src/Freeze/DBI.cpp index 254291b451d..952195a6b59 100644 --- a/cpp/src/Freeze/DBI.cpp +++ b/cpp/src/Freeze/DBI.cpp @@ -40,7 +40,7 @@ Freeze::checkBerkeleyDBReturn(int ret, const string& prefix, const string& op) { case DB_LOCK_DEADLOCK: { - DBDeadlockException ex; + DBDeadlockException ex(__FILE__, __LINE__);; ex.message = s.str(); throw ex; } @@ -48,14 +48,14 @@ Freeze::checkBerkeleyDBReturn(int ret, const string& prefix, const string& op) case ENOENT: // The case that db->open was called with a non-existent database case DB_NOTFOUND: { - DBNotFoundException ex; + DBNotFoundException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } default: { - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -71,14 +71,14 @@ Freeze::DBEnvironmentI::DBEnvironmentI(const CommunicatorPtr& communicator, cons _errorPrefix = "Freeze::DBEnvironment(\"" + _name + "\"): "; _trace = atoi(_communicator->getProperties()->getProperty("Freeze.Trace.DB").c_str()); - checkBerkeleyDBReturn(db_env_create(&_dbEnv, 0), _errorPrefix, "db_env_create"); - if (_trace >= 1) { Trace out(_communicator->getLogger(), "DB"); out << "opening database environment \"" << _name << "\""; } + checkBerkeleyDBReturn(db_env_create(&_dbEnv, 0), _errorPrefix, "db_env_create"); + checkBerkeleyDBReturn(_dbEnv->open(_dbEnv, _name.c_str(), DB_CREATE | DB_INIT_LOCK | @@ -121,7 +121,7 @@ Freeze::DBEnvironmentI::openDB(const string& name, bool create) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -268,7 +268,7 @@ Freeze::DBTransactionI::commit() { ostringstream s; s << _errorPrefix << "transaction has already been committed or aborted"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -293,7 +293,7 @@ Freeze::DBTransactionI::abort() { ostringstream s; s << _errorPrefix << "transaction has already been committed or aborted"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -350,7 +350,7 @@ DBCursorI::curr(Key& key, Value& value) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -383,7 +383,7 @@ DBCursorI::set(const Value& value) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -397,7 +397,7 @@ DBCursorI::set(const Value& value) if (_trace >= 1) { Trace out(_communicator->getLogger(), "DB"); - out << "reading current value from database \"" << _name << "\""; + out << "setting current value in database \"" << _name << "\""; } // @@ -415,7 +415,7 @@ DBCursorI::next() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -456,7 +456,7 @@ DBCursorI::prev() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -497,7 +497,7 @@ DBCursorI::del() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -520,7 +520,7 @@ DBCursorI::clone() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -606,7 +606,7 @@ Freeze::DBI::getNumberOfRecords() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -630,7 +630,7 @@ Freeze::DBI::getCursor() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -675,7 +675,7 @@ Freeze::DBI::getCursorAtKey(const Key& key) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -726,7 +726,7 @@ Freeze::DBI::put(const Key& key, const Value& value) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -748,6 +748,45 @@ Freeze::DBI::put(const Key& key, const Value& value) checkBerkeleyDBReturn(_db->put(_db, 0, &dbKey, &dbData, 0), _errorPrefix, "DB->put"); } +bool +Freeze::DBI::contains(const Key& key) +{ + IceUtil::Mutex::Lock sync(*this); + + if (!_db) + { + ostringstream s; + s << _errorPrefix << "\"" << _name << "\" has been closed"; + DBException ex(__FILE__, __LINE__); + ex.message = s.str(); + throw ex; + } + + DBT dbKey; + memset(&dbKey, 0, sizeof(dbKey)); + dbKey.data = const_cast<void*>(static_cast<const void*>(key.begin())); + dbKey.size = key.size(); + + DBT dbData; + memset(&dbData, 0, sizeof(dbData)); + dbData.flags = DB_DBT_PARTIAL; + + if (_trace >= 1) + { + Trace out(_communicator->getLogger(), "DB"); + out << "checking key in database \"" << _name << "\""; + } + + int rc = _db->get(_db, 0, &dbKey, &dbData, 0); + if (rc == DB_NOTFOUND) + { + return false; + } + + checkBerkeleyDBReturn(rc, _errorPrefix, "DB->get"); + return true; +} + Value Freeze::DBI::get(const Key& key) { @@ -757,7 +796,7 @@ Freeze::DBI::get(const Key& key) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -788,7 +827,7 @@ Freeze::DBI::del(const Key& key) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -816,7 +855,7 @@ Freeze::DBI::clear() { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } @@ -894,10 +933,34 @@ Freeze::DBI::createEvictor(EvictorPersistenceMode persistenceMode) { ostringstream s; s << _errorPrefix << "\"" << _name << "\" has been closed"; - DBException ex; + DBException ex(__FILE__, __LINE__); ex.message = s.str(); throw ex; } return new EvictorI(this, persistenceMode); } + +// +// Print for the various exception types. +// +void +Freeze::DBDeadlockException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown local exception"; +} + +void +Freeze::DBNotFoundException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown local exception"; +} + +void +Freeze::DBException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown local exception"; +} diff --git a/cpp/src/Freeze/DBI.h b/cpp/src/Freeze/DBI.h index 15ef795b618..448a7dfa680 100644 --- a/cpp/src/Freeze/DBI.h +++ b/cpp/src/Freeze/DBI.h @@ -129,6 +129,7 @@ public: virtual DBCursorPtr getCursorAtKey(const Key&); virtual void put(const Key&, const Value&); + virtual bool contains(const Key&); virtual Value get(const Key&); virtual void del(const Key&); diff --git a/cpp/src/Freeze/EvictorI.cpp b/cpp/src/Freeze/EvictorI.cpp index e278dd630cc..d5381c2539d 100644 --- a/cpp/src/Freeze/EvictorI.cpp +++ b/cpp/src/Freeze/EvictorI.cpp @@ -42,7 +42,7 @@ Freeze::EvictorI::getDB() if (_deactivated) { - throw EvictorDeactivatedException(); + throw EvictorDeactivatedException(__FILE__, __LINE__); } return _db; @@ -55,7 +55,7 @@ Freeze::EvictorI::setSize(Int evictorSize) if (_deactivated) { - throw EvictorDeactivatedException(); + throw EvictorDeactivatedException(__FILE__, __LINE__); } // @@ -84,7 +84,7 @@ Freeze::EvictorI::getSize() if (_deactivated) { - throw EvictorDeactivatedException(); + throw EvictorDeactivatedException(__FILE__, __LINE__); } return static_cast<Int>(_evictorSize); @@ -97,7 +97,7 @@ Freeze::EvictorI::createObject(const Identity& ident, const ObjectPtr& servant) if (_deactivated) { - throw EvictorDeactivatedException(); + throw EvictorDeactivatedException(__FILE__, __LINE__); } // @@ -125,7 +125,7 @@ Freeze::EvictorI::destroyObject(const Identity& ident) if (_deactivated) { - throw EvictorDeactivatedException(); + throw EvictorDeactivatedException(__FILE__, __LINE__); } // @@ -148,7 +148,7 @@ Freeze::EvictorI::installServantInitializer(const ServantInitializerPtr& initial if (_deactivated) { - throw EvictorDeactivatedException(); + throw EvictorDeactivatedException(__FILE__, __LINE__); } _initializer = initializer; @@ -416,3 +416,10 @@ Freeze::EvictorI::remove(const Identity& ident) _evictorMap.erase(p); } } + +void +Freeze::EvictorDeactivatedException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + out << ":\nunknown local exception"; +} diff --git a/cpp/test/Freeze/complex/Client.cpp b/cpp/test/Freeze/complex/Client.cpp index e120644497a..faafbca2966 100644 --- a/cpp/test/Freeze/complex/Client.cpp +++ b/cpp/test/Freeze/complex/Client.cpp @@ -36,7 +36,7 @@ validate(const DBPtr& db) for (p = m.begin(); p != m.end(); ++p) { // - // Verified the stored record is correct. + // Verify the stored record is correct. // test(p->first.result == p->second->calc()); diff --git a/cpp/test/Freeze/complex/Complex.ice b/cpp/test/Freeze/complex/Complex.ice index 44bb0e500c3..4a69236d237 100644 --- a/cpp/test/Freeze/complex/Complex.ice +++ b/cpp/test/Freeze/complex/Complex.ice @@ -15,7 +15,7 @@ module Complex // The database key (the expression and the result). Naturally, this // is a stupid key - but this is only a test :) // -/*local*/ struct Key +struct Key { string expression; int result; @@ -24,33 +24,27 @@ module Complex // // A set of classes that represents a numeric parse tree. // -/*local*/ class Node { +class Node { int calc(); }; -/*local*/ class NumberNode extends Node +class NumberNode extends Node { - int calc(); - int _number; }; -/*local*/ class BinaryNode extends Node +class BinaryNode extends Node { - int calc(); - Node _left; Node _right; }; -/*local*/ class AddNode extends BinaryNode +class AddNode extends BinaryNode { - int calc(); }; -/*local*/ class MultiplyNode extends BinaryNode +class MultiplyNode extends BinaryNode { - int calc(); }; }; diff --git a/cpp/test/Freeze/cursor/Client.cpp b/cpp/test/Freeze/cursor/Client.cpp index 79ecd512782..1bd50da5e54 100644 --- a/cpp/test/Freeze/cursor/Client.cpp +++ b/cpp/test/Freeze/cursor/Client.cpp @@ -142,6 +142,23 @@ run(int argc, char* argv[], const DBEnvironmentPtr& dbEnv) cursor->close(); cout << "ok" << endl; + cout << "testing contains... "; + try + { + for (j = alphabet.begin(); j != alphabet.end(); ++j) + { + k = KeyCodec::write(*j, instance); + test(db->contains(k)); + } + } + catch(const DBException&) + { + test(false); + } + k = KeyCodec::write('0', instance); + test(!db->contains(k)); + cout << "ok" << endl; + cout << "testing DB::getCursorAtKey... "; k = KeyCodec::write('n', instance); j = find(alphabet.begin(), alphabet.end(), 'n'); diff --git a/cpp/test/Freeze/dbmap/Client.cpp b/cpp/test/Freeze/dbmap/Client.cpp index f249c6cc237..7f4f9b0eb0e 100644 --- a/cpp/test/Freeze/dbmap/Client.cpp +++ b/cpp/test/Freeze/dbmap/Client.cpp @@ -126,6 +126,9 @@ run(int argc, char* argv[], const DBPtr& db) test(cp != m.end()); test(cp->first == *j && cp->second == j - alphabet.begin()); } + + test(!m.empty()); + test(m.size() == alphabet.size()); cout << "ok" << endl; cout << "testing map::find... "; @@ -182,10 +185,11 @@ run(int argc, char* argv[], const DBPtr& db) CharIntMap::iterator p2 = p; // - // Verify both iterators point at 'd' + // Verify both iterators point at the same element, and that + // element is in the map. // - test(p->first == 'd' && p->second == 3); - test(p2->first == 'd' && p2->second == 3); + test(p->first == p2->first && p->second == p2->second); + test(find(alphabet.begin(), alphabet.end(), p->first) != alphabet.end()); // // Create iterator that points at 'n' @@ -222,22 +226,24 @@ run(int argc, char* argv[], const DBPtr& db) cout << "ok" << endl; - cout << "testing operator[]... "; + // + // Test writing into an iterator. + // + cout << "testing iterator.set... "; + p = m.find('d'); test(p != m.end() && p->second == 3); + test(m.find('a') == m.end()); m.insert(CharIntMap::value_type('a', 1)); + p = m.find('a'); test(p != m.end() && p->second == 1); + m.insert(CharIntMap::value_type('a', 0)); p = m.find('a'); test(p != m.end() && p->second == 0); - cout << "ok" << endl; - // - // Test writing into an iterator. - // - cout << "testing iterator.set... "; p = m.find('a'); test(p != m.end() && p->second == 0); p.set(1); |