author | Aurelien Campeas <aurelien.campeas@logilab.fr> |
Fri, 09 Apr 2010 19:18:55 +0200 | |
branch | stable |
changeset 5202 | 4a77da652759 |
parent 5191 | 6d182c7d4392 |
child 5220 | 42f854b6083d |
permissions | -rw-r--r-- |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
1 |
.. -*- coding: utf-8 -*- |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
2 |
|
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
3 |
.. _hooks: |
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
4 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
5 |
Hooks and Operations |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
6 |
==================== |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
7 |
|
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
8 |
Generalities |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
9 |
------------ |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
10 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
11 |
Paraphrasing the `emacs`_ documentation, let us say that hooks are an |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
12 |
important mechanism for customizing an application. A hook is |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
13 |
basically a list of functions to be called on some well-defined |
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
14 |
occasion (this is called `running the hook`). |
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
15 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
16 |
.. _`emacs`: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
17 |
|
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
18 |
In CubicWeb, hooks are subclasses of the Hook class in |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
19 |
`server/hook.py`, implementing their own `call` method, and selected |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
20 |
over a set of pre-defined `events` (and possibly more conditions, |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
21 |
hooks being selectable AppObjects like views and components). |
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
22 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
23 |
There are two families of events: data events and server events. In a |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
24 |
typical application, most of the Hooks are defined over data |
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
25 |
events. |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
26 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
27 |
The purpose of data hooks is to complement the data model as defined |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
28 |
in the schema.py, which is static by nature, with dynamic or value |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
29 |
driven behaviours. It is functionally equivalent to a `database |
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
30 |
trigger`_, except that database triggers definition languages are not |
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
31 |
standardized, hence not portable (for instance, PL/SQL works with |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
32 |
Oracle and PostgreSQL but not SqlServer nor Sqlite). |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
33 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
34 |
.. _`database trigger`: http://en.wikipedia.org/wiki/Database_trigger |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
35 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
36 |
Data hooks can serve the following purposes: |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
37 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
38 |
* enforcing constraints that the static schema cannot express |
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
39 |
(spanning several entities/relations, specific value ranges, exotic |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
40 |
cardinalities, etc.) |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
41 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
42 |
* implement computed attributes (an example could be the maintenance |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
43 |
of a relation representing the transitive closure of another relation) |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
44 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
45 |
Operations are Hook-like objects that are created by Hooks and |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
46 |
scheduled to happen just before (or after) the `commit` event. Hooks |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
47 |
being fired immediately on data operations, it is sometime necessary |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
48 |
to delay the actual work down to a time where all other Hooks have run |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
49 |
and the application state converges towards consistency. Also while |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
50 |
the order of execution of Hooks is data dependant (and thus hard to |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
51 |
predict), it is possible to force an order on Operations. |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
52 |
|
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
53 |
Operations are subclasses of the Operation class in `server/hook.py`, |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
54 |
implementing `precommit_event` and other standard methods (wholly |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
55 |
described later in this chapter). |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
56 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
57 |
Events |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
58 |
------ |
2172
cf8f9180e63e
delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1714
diff
changeset
|
59 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
60 |
Hooks are mostly defined and used to handle `dataflow`_ operations. It |
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
61 |
means as data gets in (entities added, updated, relations set or |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
62 |
unset), specific events are issued and the Hooks matching these events |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
63 |
are called. |
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
64 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
65 |
.. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
66 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
67 |
Below comes a list of the dataflow events related to entities operations: |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
68 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
69 |
* before_add_entity |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
70 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
71 |
* before_update_entity |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
72 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
73 |
* before_delete_entity |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
74 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
75 |
* after_add_entity |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
76 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
77 |
* after_update_entity |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
78 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
79 |
* after_delete_entity |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
80 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
81 |
These define ENTTIES HOOKS. RELATIONS HOOKS are defined |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
82 |
over the following events: |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
83 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
84 |
* after_add_relation |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
85 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
86 |
* after_delete_relation |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
87 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
88 |
* before_add_relation |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
89 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
90 |
* before_delete_relation |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
91 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
92 |
This is an occasion to remind us that relations support the add/delete |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
93 |
operation, but no delete. |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
94 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
95 |
Non data events also exist. These are called SYSTEM HOOKS. |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
96 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
97 |
* server_startup |
2172
cf8f9180e63e
delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1714
diff
changeset
|
98 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
99 |
* server_shutdown |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
100 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
101 |
* server_maintenance |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
102 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
103 |
* server_backup |
2172
cf8f9180e63e
delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
1714
diff
changeset
|
104 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
105 |
* server_restore |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
106 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
107 |
* session_open |
1714
a721966779be
new book layout, do not compile yet
sylvain.thenault@logilab.fr
parents:
diff
changeset
|
108 |
|
5191
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
109 |
* session_close |
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
110 |
|
6d182c7d4392
[doc/book] begin chapter on Hooks/Operations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
2172
diff
changeset
|
111 |
|
5202
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
112 |
Using Hooks |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
113 |
----------- |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
114 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
115 |
We will use a very simple example to show hooks usage. Let us start |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
116 |
with the following schema. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
117 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
118 |
.. sourcecode:: python |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
119 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
120 |
class Person(EntityType): |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
121 |
age = Int(required=True) |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
122 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
123 |
An entity hook |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
124 |
~~~~~~~~~~~~~~ |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
125 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
126 |
We would like to add a range constraint over a person's age. Let's |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
127 |
write an hook. It shall be placed into mycube/hooks.py. If this file |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
128 |
were to grow too much, we can easily have a mycube/hooks/... package |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
129 |
containing hooks in various modules. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
130 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
131 |
.. sourcecode:: python |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
132 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
133 |
from cubicweb import ValidationError |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
134 |
from cubicweb.selectors import implements |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
135 |
from cubicweb.server.hook import Hook |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
136 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
137 |
class PersonAgeRange(Hook): |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
138 |
__regid__ = 'person_age_range' |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
139 |
events = ('before_add_entity', 'before_update_entity') |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
140 |
__select__ = Hook.__select__ & implements('Person') |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
141 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
142 |
def __call__(self): |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
143 |
if 0 >= self.entity.age <= 120: |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
144 |
return |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
145 |
msg = self._cw._('age must be between 0 and 120') |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
146 |
raise ValidationError(self.entity.eid, {'age': msg}) |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
147 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
148 |
Hooks being AppObjects like views, they have a __regid__ and a |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
149 |
__select__ class attribute. The base __select__ is augmented with an |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
150 |
`implements` selector matching the desired entity type. The `events` |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
151 |
tuple is used by the Hook.__select__ base selector to dispatch the |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
152 |
hook on the right events. In an entity hook, it is possible to |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
153 |
dispatch on any entity event at once if needed. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
154 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
155 |
Like all appobjects, hooks have the self._cw attribute which |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
156 |
represents the current session. In entity hooks, a self.entity |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
157 |
attribute is also present. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
158 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
159 |
When a condition is not met in a Hook, it must raise a |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
160 |
ValidationError. Raising anything but a (subclass of) ValidationError |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
161 |
is a programming error. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
162 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
163 |
The ValidationError exception is used to convey enough information up |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
164 |
to the user interface. Hence its constructor is different from the |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
165 |
default Exception constructor.It accepts, positionally: |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
166 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
167 |
* an entity eid, |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
168 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
169 |
* a dict whose keys represent attributes and values a message relating |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
170 |
the problem; such a message will be presented to the end-users; |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
171 |
hence it must be properly translated. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
172 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
173 |
A relation hook |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
174 |
~~~~~~~~~~~~~~~ |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
175 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
176 |
Let us add another entity type with a relation to person (in |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
177 |
mycube/schema.py). |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
178 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
179 |
.. sourcecode:: python |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
180 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
181 |
class Company(EntityType): |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
182 |
name = String(required=True) |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
183 |
boss = SubjectRelation('Person', cardinality='1*') |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
184 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
185 |
We would like to constrain the company's bosses to have a minimum |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
186 |
(legal) age. Let's write an hook for this, which will be fired when |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
187 |
the `boss` relation is established. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
188 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
189 |
.. sourcecode:: python |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
190 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
191 |
class CompanyBossLegalAge(Hook): |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
192 |
__regid__ = 'company_boss_legal_age' |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
193 |
events = ('before_add_relation',) |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
194 |
__select__ = Hook.__select__ & match_rtype('boss') |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
195 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
196 |
def __call__(self): |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
197 |
boss = self._cw.entity_from_eid(self.eidto) |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
198 |
if boss.age < 18: |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
199 |
msg = self._cw._('the minimum age for a boss is 18') |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
200 |
raise ValidationError(self.eidfrom, {'boss': msg}) |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
201 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
202 |
We use the `match_rtype` selector to select the proper relation type. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
203 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
204 |
The essential difference with respect to an entity hook is that there |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
205 |
is no self.entity, but `self.eidfrom` and `self.eidto` hook attributes |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
206 |
which represent the subject and object eid of the relation. |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
207 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
208 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
209 |
# XXX talk about |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
210 |
|
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
211 |
dict access to entities in before_[add|update] |
4a77da652759
[doc/book] more about hooks (simple examples with entities and relations)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5191
diff
changeset
|
212 |
set_operation |