This project presents an abstraction layer on top of a database. It lets a project have persistent classes with a moderate amount of overhead. Every class will have a factory class which will help saving and loading persistent classes from the database. The abstraction from the database is very complete, with both sql and xml backends.
An AbstractFactory design pattern is used to instantiate persistent classes and an Adapter around the database interface. The real innovation is in the search parameters implemented to make a complete abstraction over any given query. It is possible to create complex, nested queries without ever knowing the underlying database interface.
This is currently being implemented in C++, Java and Ruby. A Perl implementation is on the way. Other implementations may follow.
The intent is that this will work across many platforms, but currently it has only been tested on Windows (cygwin) and GNU/Linux.
MySQL, CTLib, and PostgreSQL libraries are used for SQL database connectivity and Expat is used for XML persistence. Expat may be replaced by SXP in the very near future.
Compared to other database wrappers, this library completely hides the underlying database. For instance, some SQL wrappers have update and insert functions, whereas this wrapper simply have a load and a save function.
Internally there is an SQL Abstraction layer, which will be used by all implementations of the DatabaseInterface that connect to an SQL database. As of now only a Java implementation of this SQL Abstration layer exists but a Ruby port is on its way. The C++ port may be a while yet.
Currently, only the Ruby port has been released (in version ) for the general public. It is still in it's very early alpha version. A C++ version and a Java version is also in the CVS repository. Sourceforge kindly makes a nightly snapsnot of the entire DBI++ CVS repository, which you may also download. If you do so, it is at your own risc. Mostly what is checked in will as least compile, but there are no garantees given. And of cause it's sheer luck if any given snapshot is even slightly stable.
This project's SourceForge CVS repository can be checked out through anonymous (pserver) CVS with the following instruction set. The module you wish to check out must be specified as the modulename. When prompted for a password for anonymous, simply press the Enter key.
cvs -d:pserver:anonymous@cvs.dbixx.sourceforge.net:/cvsroot/dbixx login cvs -d:pserver:anonymous@cvs.dbixx.sourceforge.net:/cvsroot/dbixx co dbixx
Updates from within the module's directory do not need the -d parameter.
Each class extends a Persistent class and has an accompanying factory class, which extends a PersistentFactory. To instantiate a new Persistent-derived class, the relevant PersistentFactory-derived class factory is called to load the class. The factory knows how to instantiate the class and builds the correct Search parameters. It then calls the DatabaseInterface to do the actual loading of the class. The DatabaseInterface will then fetch the class attributes from the database and get a new instance of the class from a default Persistent.


Several steps need to be taken in order to use the DBI++ API. To make a new class, that is to be serializable must extend the Persistent class. It needs to have a constructor that takes an assosiative array with all attributes that the class, a default constructor and a method called newInstance, which also takes an assosiative array as parameter and instanatiates a new persistent with the given attributes.
For instance, a User class is shown below. UML, EER and code is provided in the hopes that this will be verbose enough to convey the intend.
class User extends dbixx.Persistent { private String[] notes ; private String username ; private String password ; public User () {} /** * Initialize a User * * PARAMETERS map an associative array of attributes and their values * * SIDEEFFECTS none * * BUGS none implemented * * RETURN nothing * * STATE being tested * * AUTHOR Anders Borch */ public User (HashMap attributes) { username = attributes.find("login") ; password = attributes.find("password") ; uid = attributes.find("id") ; } public newInstance (HashMap attributes) { return new User (attributes) ; } package addUserNotes (String note) { this.notes.arrayCopy (notes) ; } } class UserFactory extends dbixx.PersistentFactory { DatabaseInterface databaseInterface ; /** * Initialize a UserFactory * * PARAMETERS dbi interface to the database used to create User instances * * SIDEEFFECTS none * * BUGS none implemented * * RETURN nothing * * STATE being tested * * AUTHOR Anders Borch */ UserFactory (DatabaseInterface dbi) { databaseInterface = dbi ; } /** * Create a user instance * * PARAMETERS login/id the unique identity of the user instance * * SIDEEFFECTS none * * BUGS need to create InternalUser or Distributor in stead of User * * RETURN pointer to a user instance * * STATE being tested * * AUTHOR Anders Borch */ Persistent createPersistent (int id) { User templateUser ; // fetch user information Search s1 ; s1.addAttributeCriteria (null, "id", Search.EQUAL, "1") ; User newUser = (User)databaseInterface.load ("users", s1, templateUser) ; // fetch user notes Search s2 ; s2.addAttributeCriteria (null, "userid", Search.EQUAL, "1") ; HashMap[] rows = databaseInterface.load ("user_notes", s2) ; for (int c = 0 ; c < rows.length() ; c++) newUser.addUserNotes (rows[c]) ; return newUser ; } }
| Suggested Class Name | Short Description |
|---|---|
| Select | Represents a 'SELECT' SQL statement. |
| Delete | Represents a 'DELETE' SQL statement. |
| Update | Represents an 'UPDATE' SQL statement. |
| Search | Represents the 'WHERE'-clause of an SQL statement. |
| Create | Represents a 'CREATE' SQL statement. |
| Drop | Represents a 'DROP' SQL statement. |
| Alter | Represents an 'ALTER' SQL statement. |
| Procedure | Creates or runs an existing stored procedure. |
| Sequence | Represents an auto-incrementing counter for generating unique integer values. |
| SQLDatabaseInterface | Used for loading database drivers transparently, obtaining connections to the database and constructing instances of the other classes. Might also implement a connection-reuse strategy. |
Other features might include:
Should you be interested in helping out with the development of this great and revolutionary library, any help or input is very much appreciated. All bug tracking, current documentation, feature resuests and updated status of this project is available on the sourceforge page.
Should you be in any doubt, please let me assure you, this is a sourceforge hosted site and therefore features the sourceforge logo: