WebÞing

AnyDBM
A general-purpose DBM library

Tie

Tie is named after the Perl module which binds an associative array to a DBM. Tie is essentially similar to its Perl cousin, but offers several additional advantages:

  1. Tie is templateized to store arbitrary objects.
  2. Tie works over a network (including the Internet) using RDBM.
  3. Tie provides the traditional functional interface, in addition to the associative array binding.

Example

Suppose we want persistent objects of MY_TYPE indexed by name, using a database on any.dbm.org:

/* Most of the dbm accessess in the following could throw a dbmexception,
   but we're going to ignore it
*/

#include <AnyDBM/RDBM.h>
#include <AnyDBM/Tie.h>

typedef RDBM<MY_TYPE> MY_TYPE_dbm ;
typedef TiedArray<MY_TYPE_dbm, MY_TYPE> MY_TYPE_array ;
typedef TiedObject<MY_TYPE_dbm, MY_TYPE> MY_TYPE_iterator ;

func() {
  MY_TYPE_dbm dbm("any.dbm.org") ;	// makes a connection

  MY_TYPE_array data(dbm) ;		// gives assoc-array notation

/* Insert an object */
  MY_TYPE my_obj ;
  data["some key"] = my_obj ;		// or data.put("some key", my_obj)

/* retrieve an object */
  my_obj = data["other key"] ;		// or data.get("other key")

/* List all the objects */
  int n = 0 ;
  for ( MY_TYPE_iterator obj = *data ; !data.eof() ; ++obj )
	cout << ++n << ": " << obj.key() << " -> " << *obj << endl ;

}			// when func returns, data and dbm go out of scope
			// and the destructors perform housekeeping

Uniform Interface

If we compile the above with -lrdbm, we have a DBM Client program that works with any RDBM Server, locally or remotely. But equally, we could have written:


#include <AnyDBM/NDBM.h>
#include <AnyDBM/Tie.h>

typedef NDBM<MY_TYPE> MY_TYPE_dbm ;

... etc
and generated a program to use NDBM. Likewise, we could have used GDBM, or any of the Berkeley DB options, DB_HASH, DB_BTREE or DB_RECNO[1].

The sample program example.cc included in the distribution in fact compiles from the identical source file to an RDBM Client program and to four different standalone DBM programs, merely by using different options in the Makefile.

Description

Tie comprises two main classes:

  1. TiedArray - an object DBM
  2. TiedObject - an accessor and iterator for TiedArray

Both classes are templates of:

  1. DBM - the underlying DBM implementation (NDBM, GDBM, Berkeley DB with Hash, BTree or Recno, or RDBM Client to any of these).
  2. T - the object type stored (e.g. const char*, my_db_item, or CGI).

TiedArray provides the full BASE_DBM interface, with additional operators for Associative Array notation:


  TiedObject<DBM,T> operator[](const char* key) throw(dbmexception) ;
  TiedObject<DBM,T> operator*() throw(dbmexception) ;

TiedObject is formally an Output Iterator for TiedArray, with transparent conversion to/from the underlying object type.

Other classes in Tie

Tie also defines an exception class dbmexception, thrown when a DBM operation fails. dbmexception has a public data member errnum, which is the error code returned by the operation.

Finally, TiedObjectType is a virtual base class which you can inherit from to ensure your class supports the interface necessary for AnyDBM (i.e. conversion to/from const char* and operator!() ). Without touching your object type, you might use:


class myobject { ... }
class mydbmobect : public myobject, public TiedObjectType {
public:
  // Instantiate the TiedObjectType interface
} ;

Footnotes

[1]
The recno option of the Berkeley DB should be supported in theory, but I can't actually get it to work.