sql-oo: An persistent layer for particularly constructed objects

_sql-oo: An persistent layer for particularly constructed objects_

By Jay McCarthy (jay at kenyamountain dot com)

Keywords: _io_, _db_


After developing an SQLite interface, I found it convenient to abstract the details of loading objects to and from the SQL database. Due to this development order, the library currently only works with SQLite, pending an abstraction of SchemQL and a general SQL interface.


This file defines the main objects and methods. Require it like this:

> (require (planet "" ("jaymccarthy" "sql-oo.plt" 1)))

It provides the follow procedures:

> (db-class@ table-name (field ...)) syntax -> unit

This syntax will return a unit, with the signature db-addon^, that contains the following symbols:
     <%> : The interface that provides "field" and "field!" for each field given. And is a subinterface of db-object<%>
     % : The object that is a subclass of db-object% that implements the above methods in such a way as to abstract that the object is stored in a database. This object must be instantiated with a 'db' initarg that is an SQLite handle and a '_path' initarg that is a string identifying the object. (However, you should not need to instantiate these objects on your own.)
     mixin-maker : A function that given a class that implements <%>, will provide a mixin that expands objects that implement sql-oo<%> to allow % objects to be stored in the table 'table-name'

> sql-oo<%>

This interface specifies the operations:
     get-db : -> db-handle
	    This should return a db handle.
     init-sql : -> (listof string?)
	    This should return a list of SQL expressions that initialize an empty database to store the objects that the class supports
     init-db : -> integer
	    This runs the init-sql on the database. (You must pass it the symbol 'really for it to actually run it, due to the unsafe-ness of deleting the database.)
     object : path [table-name] -> object
	    This returns an object corresponding to the given path, if it resides in the database. If not, #f is returned.
	    If the optional table-name argument is passed, then the object must implement be in this table (and thus be of a particular type.) However, in this case, if the object does not yet exist, it will be created.
     type->class : table-name -> class
	    This returns the class that implements objects residing in the 'table-name' table.

> sql-oo%
An implementation of sql-oo<%>

> (apply-units base% . unit@-list) -> object

This method requires that base% implements sql-oo<%> and returns an object that also implements sql-oo<%>. If all the units in the unit@-list have the signature db-addon^, then they will be used (in order) to extend the base% class to support the object types they specify.


(require (lib "")
(prefix sql-oo: "../"))

(define wiki@ (sql-oo:db-class@ "object_wiki"
		     (author body last_changed)))
(define the-sql-oo%

See the code in the tests/ directory, for how to use such objects.

See the yppdb package for an extended example.

Notes and Limitations

As mentioned above, it really only works with SQLite. And it doesn't generate much management code for defining searches and relations.


v1.1 :: June 14th, 2005
	* Added caching via hash-tables for objects and the database as a whole.

v1.0 :: April 7th, 2005
        * Initial revision