Schevo Transaction Hook Methods — libschevo 3.2.4 documentation

### Navigation

- index
- next |
- previous |
- libschevo 3.2.4 documentation »
- Schevo References »

# Schevo Transaction Hook Methods

## Overview

Transaction hooks make it easy to change specific behavior of default transaction classes. You can customize the following behaviors:

- Setup of a transaction instance.
- What happens just before standard transaction execution.
- What happens just after standard transaction execution.

## Doctest Setup

This document also functions as a doctest:

    >>> from schevo.test import DocTest

## Subclassing in general

Define each subclass as an inner class of the entity class that you are overriding. Begin the class name with an underscore, then the name of the transaction you are overriding. Inherit from the name of the transaction in the `T` namespace. For example:

    class Foo(E.Entity):

        bar = f.string()
        count = f.integer()

        class _Create(T.Create):
            ...

        class _Delete(T.Delete):
            ...

        class _Update(T.Update):
            ...

You can also create custom transactions that have names that differ from the standard ones shown above. Remember to set up a t method so you can create instances of your new transaction:

    class Foo(E.Entity):

        bar = f.string()
        count = f.integer()

        def t_custom_update(self, **kw):
            return E.Foo._CustomUpdate(self, **kw)

        class _CustomUpdate(T.Update):
            ...

### Overriding __init__ and _execute not allowed

Overriding __init__ or _execute in most Transaction subclasses is not allowed. If you attempt to do so, Schevo will raise a schevo.error.TransactionExecuteRedefinitionRestricted exception:

    >>> t = DocTest("""
    ...     class Foo(E.Entity):
    ...
    ...         bar = f.string()
    ...
    ...         class _Create(T.Create):
    ...
    ...             def _execute(self, db):
    ...                 pass
    ... """)
    Traceback (most recent call last):
        ...
    TransactionExecuteRedefinitionRestricted: ...

Classes that have a _restrict_subclasses attribute set to True enforce the above restriction. They include the following:

- Combination
- Create
- Delete
- Update
- Inverse
- Initialize
- Populate
- CallableWrapper

### Overriding hook methods

When implementing the hooks listed below, remember that you can raise an exception at any point to veto an operation. Any changes to the database made by the transaction will be reversed, and control will return to the parent transaction execution, if one exists.

### Adding and overriding fields

Subclasses of Create, Delete, and Update transactions that are defined as inner classes of an entity class inherit the field definitions from the entity class.

When a field with a new name is defined in a transaction subclass, it is added to the end of the existing field definitions. For example, the Update class here has three fields, `bar`, `count`, and `baz`:

    class Foo(E.Entity):

        bar = f.string()
        count = f.integer()

        class _Update(T.Update):

            baz = f.entity('Baz')

When a field with an existing name is defined, it replaces the old field definition and is added to the end. For example, the Update class here has two fields, `count` and `bar`:

    class Foo(E.Entity):

        bar = f.string()
        count = f.integer()

        class _Update(T.Update):

            bar = f.entity('Bar')

To change the properties of a field without changing the order of it, make those changes in the `_setup` method by using the `f` namespace:

    class Foo(E.Entity):

        bar = f.string()
        count = f.integer()

        class _Update(T.Update):

            def _setup(self):
                self.f.count.hidden = True

## Available hook methods

### Create subclasses

`_setup(self)`
  Called during `__init__` after setting fields based on keyword arguments, before setting default values for fields that weren’t assigned a value.
`_before_execute(self, db)`
  Called during transaction execution, before the create operation takes place.
`_after_execute(self, db, entity)`
  Called during transaction execution, after the create operation takes place. The newly-created entity is passed in.

### Delete subclasses

`_setup(self)`
  Called at end of `__init__`.
`_before_execute(self, db, entity)`
  Called during transaction execution, before the delete operation takes place. The entity about to be deleted is passed in.
`_after_execute(self, db)`
  Called during transaction execution, after the delete operation has taken place.

### Update subclasses

`_setup(self)`
  Called at end of `__init__`.
`_before_execute(self, db, entity)`
  Called during transaction execution, before the update operation takes place. The entity about to be updated is passed in.
`_after_execute(self, db, entity)`
  Called during transaction execution, after the update operation has taken place. The entity that was just updated is passed in.

### Navigation

- index
- next |
- previous |
- libschevo 3.2.4 documentation »
- Schevo References »