[Schevo-devel] transactions returning transactions

Patrick K. O'Brien pobrien at orbtech.com
Fri Nov 18 11:12:34 EST 2005


Matthew Scott wrote:
> 
> Here's how I ultimately implemented the auto-incrementing global sequence:
> 
> First, a Sequence extent:
> 
> class Sequence(E.Entity):
>     """Sequentially increasing numbers for assigning to items."""
> 
>     next = f.integer()
> 
>     _hide('t_create', 't_delete', 't_update', 't_increment')
> 
>     _initial = [
>         (10000, ),
>         ]
> 
>     def t_increment(self):
>         return E.Sequence._Increment(self)
> 
>     class _Increment(T.Transaction):
>         """Increment the sequence and return the previous value."""
> 
>         def __init__(self, sequence):
>             T.Transaction.__init__(self)
>             self.x.sequence = sequence
> 
>         def _execute(self, db):
>             seq = self.x.sequence
>             current = seq.next
>             tx = seq.t.update(next=current+1)
>             db.execute(tx)
>             return current
> 
>     @classmethod
>     def x_get(cls):
>         """Returns the singleton entity."""
>         return db.Sequence[1]
> 
>     @classmethod
>     def x_next(cls):
>         """Returns the next sequence number."""
>         return db.execute(db.Sequence.x.get().t.increment())
> 
> The Invoice extent remains simple since it can use a callable default:
> 
> class Invoice(E.Entity):
>     """Invoice."""
> 
>     from_party = f.entity('Party')
>     to_party = f.entity('Party')
>     invoice_number = f.unicode(default=lambda : db.Sequence.x.next)
>     opened = f.date(default=datetime.date.today)
>     submitted = f.date(required=False)
> 
> Note that using 'default=db.Sequence.x.next' won't work because during
> execution of the schema module, db won't yet be the actual database. 
> By using a lambda function, the name db is resolved later when it is
> the actual database instance.

Very nice.  I wonder if you could have done 'default=E.Sequence.x.next'
if x_next() was not a classmethod.  Avoids the dreaded lambda, but also
takes away the ability to do db.Sequence.x.next() elsewhere.  Perhaps
even more reason that we should implement an @extentmethod decorator
instead of relying on @classmethod trickery to move methods from the
Entity class definition to the corresponding Extent class.  In any
event, a very nice example.

-- 
Patrick K. O'Brien
Orbtech       http://www.orbtech.com
Schevo        http://www.schevo.org




More information about the Schevo-devel mailing list