[TransWarp] SkinScript-to-Jars phrasebook, deleting objects, and terminology

Phillip J. Eby pje at telecommunity.com
Sun Jun 30 16:10:46 EDT 2002

Most SkinScript declarations can be rewritten as Python code inside one of 
the methods of AbstractJar.  The main difference in execution model between 
ZPatterns and PEAK for attribute storage is that ZPatterns allows 
attributes to be computed on-demand, while PEAK (actually ZODB) requires 
that all an object's attributes be computed at once.  It's just that 
attributes which are other persistent objects can be "ghosts", whose class 
is known but whose state/contents may not be.

So translating from SkinScript to PEAK persistence using Jars will be done 
by combining all SkinScript declarations into Python code in jar methods 
according to the following chart:

Abstract method     ZPatterns/SkinScript Equivalent
---------------     ---------------------------------------------------
load()              WITH ... COMPUTE ...
defaultState()      INITIALIZE OBJECT WITH ...
new()               WHEN OBJECT ADDED ...
save()              WHEN OBJECT CHANGED STORE attrs USING ...
ghost()             no real equivalent
thunk()             rarely used mix of attribute exprs and trigger code

You'll notice there's also no direct equivalent to WHEN OBJECT 
DELETED.  There are two kinds of situations where an object would be deleted:

* An object "belongs" to another object, i.e., it is at the child end of a 
composite association, and the link to/from the parent is broken, implying 
deletion.  This should be handled in the "save()" method of the jar on the 
child side of the association.  If it sees the child object no longer has a 
parent pointer, it should respond by deleting its associated data record 
(not to mention any of its owned children in outgoing composition 
links).  This is easiest if the database supports ON DELETE CASCADE 
constraints, but it can also be done manually.

* The other possibility is that a top-level (i.e. not a child of anything) 
object is to be deleted.  This can be handled by a Specialist method which 
delegates to something in the data layer, or by mapping a domain-level 
attribute such as "active" or "deleted" to the necessary action in save().

As you can see, neither of these situations can be clearly expressed as a 
standard method to override in the jar, because the triggering conditions 
vary so widely.  In the absence of a uniform way to express "delete this" 
at the application level, adding logic in 'save()' will have to do.  Of 
course, once we get to having jars that are driven by metadata, the 
composition situation should be handled automatically, and we'll probably 
have some way to configure to configure a signal to indicate the top-level 

Hm.  It may be that we should add something to peak.model.Element to be 
able to tell it to delete itself, walking all its reference/collection 
features and clearing them...

Anyway, object deletion is rather messy.  One particularly messy bit is 
that unlike object creation, you can't guarantee operations will be issued 
to the DB in an order that's compatible with (undeferred) referential 
integrity checks, unless you have cascade deletion support or hardcode the 
cascading yourself.

In any event, I've written up a preliminary version of a 
'peak.storage.jars' module with an AbstractJar class, and in the process I 
found a few minor issues that weren't covered in the design so far.  For 
example, I needed a 'commitInProgress' flag in order to ensure certain 
invariants held true even when a save() operation during a top-level commit 
ends up modifying a persistent object that has already been committed.

Nonetheless, the implementation looks pretty good at about 247 lines of 
heavily commented code.  I haven't checked it in yet, mainly because 
there's still some ambiguity as to where it should live in the PEAK package 

'peak.storage' as a top-level package doesn't sound bad, and a lot of the 
DB-related stuff I wanted to cram under 'peak.deployment' would probably go 
better there.  I'm just not sure if Jars should actually be Racks or PDM's 
or some other such thing, in PEAK nomenclature.

Suggestions, anyone?

More information about the PEAK mailing list