summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2002-03-08 13:47:12 +0000
committerMatthew Newhook <matthew@zeroc.com>2002-03-08 13:47:12 +0000
commit2ee86c01bdce8ff4fb14120f9603e2d4382a32af (patch)
tree9ef026ad20f848bf3f4217eebd478804e3740f9f /cpp
parentadding constructors to holder classes (diff)
downloadice-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.cpp21
-rw-r--r--cpp/demo/Freeze/phonebook/Parser.cpp21
-rw-r--r--cpp/demo/Freeze/phonebook/PhoneBook.ice28
-rw-r--r--cpp/demo/Freeze/phonebook/PhoneBookI.cpp313
-rw-r--r--cpp/demo/Freeze/phonebook/PhoneBookI.h6
-rw-r--r--cpp/slice/Freeze/DB.ice34
-rw-r--r--cpp/slice/Freeze/DBException.ice6
-rw-r--r--cpp/slice/Freeze/Evictor.ice2
-rw-r--r--cpp/src/Freeze/Application.cpp1
-rw-r--r--cpp/src/Freeze/DBI.cpp109
-rw-r--r--cpp/src/Freeze/DBI.h1
-rw-r--r--cpp/src/Freeze/EvictorI.cpp19
-rw-r--r--cpp/test/Freeze/complex/Client.cpp2
-rw-r--r--cpp/test/Freeze/complex/Complex.ice18
-rw-r--r--cpp/test/Freeze/cursor/Client.cpp17
-rw-r--r--cpp/test/Freeze/dbmap/Client.cpp24
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);