Elephant: A Persistent Metaobject Protocol and Object Oriented Database for Common Lisp Persistent object protocol –persistent-metaclass specializes slot accesses –Enables persistent links between objects –Enables automatic indexing of class instances by slot value –Efficient instance mapping by class, slot values, etc. Simple persistent collection APIs –Persistent sets (add, remove, find) –Btrees (insert, delete, pred, succ)
Transactional architecture –Support for concurrent transactions –Provides the full ACID compliance of underlying data store –Elephant is thread-safe; can share data store handles Modular Data Store design –The interface to disk storage is abstracted –Currently supports Berkeley DB (direct/fast) and CL-SQL (general/slower) for flexible speed, license issues –Full support for migration between database instances –Migration also provides compaction and garbage collection Runtime database configuration –Class schema redefinition –Add/remove slot indexes –Add/drop objects from the database
PSET Class Indexing Persistent Slots BTree SerializerMemutils/UFFI MOP User API Data Store Interface and Utilities db-bdbdb-postmoderndb-clsqldb-lisp BerkeleyDBPostgreSQLSQLite DCM User API Internal Ready to integrate TBD 3rd party
(defpclass friend () ((name :accessor name :initarg :name) (birthday :initarg :birthday :index t)) => # (make-instance 'friend :name "Carlos" :birthday (encode-birthday '( ))) (make-instance 'friend :name "Adriana" :birthday (encode-birthday '( ))) (make-instance 'friend :name "Zaid" :birthday (encode-birthday '( ))) NOW SOMEONE TRIPS OVER THE POWER CORD... Restart your LISP and do: (get-instances-by-class 'friends) => (# # # ) (map-class-index #'(format t " name: ~A birthdate: ~A~%" (name friend) (birthday friend)) 'friend ‘birthday) name: Carlos birthdate: ( ) name: Zaid birthdate: ( ) name: Adriana birthdate: ( ) => nil Persistent Classes
Persistent References
Transactions
Persistent Sets
BTrees
Fast Binary Object Serializer All numeric types Strings, symbols and pathnames –Full Unicode support Persistent objects Standard objects and structs Arrays, hash-tables and lists
Flexible Indexing Scheme Don't optimize prematurely...index a slot when you need to Functional indexes provide lots of power; you can index objects by the values returned from arbitrary lisp functions Indexes can be ordered by –Any numeric quantity –Lexical ordering of strings, symbols and paths
Broad Platform Support Multiple Lisp environments: –SBCL, ACL, LispWorks, OpenMCL Multiple Platforms: –Linux, Mac, Windows –32 and 64 bit Multiple data store implementations –Berkeley DB and CL-SQL (PostgreSQL and SQLite) –Native PostgreSQL and Lisp data store planned
Multiple Data Stores Berkeley DB: fast, not free for a website unless website is open-source Postgres via CLSQL: slower, liberal license, very solid and well-supported SQLite3 via CLSQL: simple, slowest, good for prototyping Easy to migrate your application between them and more data stores are on the way
The Future A robust, long-term supported 1.0 release planned by end of summer ‘07 –Referential integrity and full support for schema evolution (changing persistent class slots) –Better support for class hierarchies when indexing –Better postgres usage with postmodern –Object query language (and compiler?) Post 1.0 features under consideration –Native LISP data store –Object prevalence or Object management (DCM)
Elephant Pointers – –Available via CVS and tar archive (not asdf-installable today) –Add feature requests and log bug reports to the TRAC project database at Authors –Original Elephant Implementation by Andrew Blumberg and Ben Lee –New Elephant Versions ‘05-’07 by Ian Eslick and Robert Read –Numerous patches, features, examples and significant testing support from a growing user base!