[PEAK] EntityDM._thunk method

Phillip J. Eby pje at telecommunity.com
Thu Jul 21 00:34:26 EDT 2005

At 01:46 AM 7/21/2005 +0000, Tiago Cogumbreiro wrote:
>Here's a simplified version of the code, in order for it to work:
>storage.beginTransaction (self)
>foo = self.FooDM.newItem ()
>bar = self.BarDM.newItem ()

Note that 'newItem()' is deprecated; create objects and 'add()' them instead.

>bar.foo = foo
>self.BarDM.flush () #[1]
>self.FooDM.remove (foo)
>self.FooDM.flush () #[2]
>self.assertEqual (len (self.BarDM), 0)
>self.assertEqual (len (self.FooDM), 0)
>storage.commitTransaction (self)
>[1] must be called otherwise the self.FooDM._thunk will be called

When does it get called?

>[2] must be called otherwise len() will get the wrong value because
>the objects - FooDM triggers BarDM into remove 'bar' - will only be
>removed on the end of the transaction.

flush() is an instruction to make the underlying database state match the 
in-memory state, so if you are using the _delete_oids mechanism to 
implement cascading deletion, it will only take effect at flush() or 
commit.  If you want to implement a cascading delete that takes effect as 
soon as you remove(), you need to override remove() to first call the base 
definition of remove, and then do any cascading removes.  _delete_oids is 
for deleting the identified objects from underlying storage.

In general, if you are implementing a *storage* function, you should be 
overriding a method beginning with '_', but if you are implementing a 
*behavioral* function (like cascading delete) then you probably should be 
overriding a public method.

>My first question is, why do I need to call [1]?

Since I don't know what your DM's do, I can't say.  I can only speculate, 
as I have above.

>Since my len() is basically returns the value from `self.db ("SELECT
>COUNT(*) FROM Table")`, is there anyway to enforce that flush be
>called and thus it gets a real value?

Well, you could certainly call flush() from len(), and in general if you're 
doing queries against an underlying database and not taking into account 
the possibly-different in-memory state, you need to flush().  That's what 
it's for.  The value in flush() being delayed is that it allows 
shorter-duration locks in many high-contention database scenarios, and that 
it avoids issuing updates on a per-field basis.

More information about the PEAK mailing list