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_
Introduction
============
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.
_sql-oo.ss_
---------------
This file defines the main objects and methods. Require it like this:
> (require (planet "sql-oo.ss" ("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.
Examples
========
(require (lib "class.ss")
(prefix sql-oo: "../sql-oo.ss"))
(define wiki@ (sql-oo:db-class@ "object_wiki"
(author body last_changed)))
(define the-sql-oo%
(sql-oo:apply-units
sql-oo:sql-oo%
wiki@))
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.
History
=======
v2.0 :: October 4th, 2005
* Updating to next version of sqlite.plt
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
References
==========