RD> For example, when a new slot is introduced it is unbound in existing RD> instances. I will often set the slot value to nil in the migration RD> function. Other times I will need to query the web for the correct RD> value for existing objects' new slots.
Here's how I do it (my-persistent-object is root class for all my persistent objects): (defmethod slot-unbound (class (instance my-persistent-object) name) ;; when we've got unbound slot ;; try reinitializing it with initform via shared initialize (shared-initialize instance (list name)) (if (slot-boundp instance name) ;; if it becomes bound, call slot-value once again. ;; (I hope it does not get into loop.) (slot-value instance name) ;; otherwise call next method which signals error (call-next-method))) Then it boils down to having correct shared-initialize which can fix partially-initialized classes. For most cases initform is enough, I think. Initform is a function and it can do pretty much anything. If you want to refer to instance in initform, you can do that through special variables and shared-initialize :around (defvar *current-instance* nil) (defmethod shared-initialize :around ((instance my-persistent-object) slot-names &key) (let ((*current-instance* instance)) (call-next-method))) Then initform you can refer to it: (defpclass foobar () ((foo :accessor foo-of :initarg :foo) (bar :initform (+ 10 (foo-of *current-instance*)) :initarg :bar) Or you can explicitly implement this stuff in shared-initialize methods, if it doesn't fit into initform somehow. Of course, this method implies that unbound slots are not possible in healthy instances. I haven't yet seen the case where I want slot to be unbound... RD> The desire is to define a migration framework that satisfies the RD> following criteria: RD> * the database should keep track of the version of its schema. Elephant 1.0 does this and it implements scheme evolution in some way. But, honestly, I didn't look into it in details. Check schema.lisp and schema-evolution.lisp. RD> Perhaps the most straightforward implementation would be to introduce RD> a new means of defining persistent classes and their indices more RD> explicitly, instead of letting defclass do all the work. Hmm, I think the whole point of Elephant is that it is a CLOS persistence and classes are defined via defclass. It is actually good that you don't see how class definition was changing over time -- you see only current class definition. And code which translates old instances to new ones -- that can be a separate _temporary_ layer. RD> Instead of adding ":index t" to a slot definition, you would instead RD> define a migration and call (add-index-for-slot (find-class 'user) RD> 'telephone-number). This is too close to SQL :) Which is not necessarily a bad thing, but if you want to do it in SQL style, won't it be easier to use SQL directly? _______________________________________________ elephant-devel site list elephant-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/elephant-devel