17 |
17 |
18 class Person(EntityType): |
18 class Person(EntityType): |
19 age = Int(required=True) |
19 age = Int(required=True) |
20 |
20 |
21 We would like to add a range constraint over a person's age. Let's write an hook |
21 We would like to add a range constraint over a person's age. Let's write an hook |
22 (supposing yams can not handle this nativly, which is wrong). It shall be placed |
22 (supposing yams can not handle this natively, which is wrong). It shall be placed |
23 into `mycube/hooks.py`. If this file were to grow too much, we can easily have a |
23 into `mycube/hooks.py`. If this file were to grow too much, we can easily have a |
24 `mycube/hooks/... package` containing hooks in various modules. |
24 `mycube/hooks/... package` containing hooks in various modules. |
25 |
25 |
26 .. sourcecode:: python |
26 .. sourcecode:: python |
27 |
27 |
42 raise ValidationError(self.entity.eid, {'age': msg}) |
42 raise ValidationError(self.entity.eid, {'age': msg}) |
43 |
43 |
44 In our example the base `__select__` is augmented with an `is_instance` selector |
44 In our example the base `__select__` is augmented with an `is_instance` selector |
45 matching the desired entity type. |
45 matching the desired entity type. |
46 |
46 |
47 The `events` tuple is used specify that our hook should be called before the |
47 The `events` tuple is used to specify that our hook should be called before the |
48 entity is added or updated. |
48 entity is added or updated. |
49 |
49 |
50 Then in the hook's `__call__` method, we: |
50 Then in the hook's `__call__` method, we: |
51 |
51 |
52 * check if the 'age' attribute is edited |
52 * check if the 'age' attribute is edited |
53 * if so, check the value is in the range |
53 * if so, check the value is in the range |
54 * if not, raise a validation error properly |
54 * if not, raise a validation error properly |
55 |
55 |
56 Now Let's augment our schema with new `Company` entity type with some relation to |
56 Now let's augment our schema with a new `Company` entity type with some relation to |
57 `Person` (in 'mycube/schema.py'). |
57 `Person` (in 'mycube/schema.py'). |
58 |
58 |
59 .. sourcecode:: python |
59 .. sourcecode:: python |
60 |
60 |
61 class Company(EntityType): |
61 class Company(EntityType): |
152 check_cycle(self.session, eid, self.rtype) |
152 check_cycle(self.session, eid, self.rtype) |
153 |
153 |
154 |
154 |
155 Here, we call :func:`set_operation` so that we will simply accumulate eids of |
155 Here, we call :func:`set_operation` so that we will simply accumulate eids of |
156 entities to check at the end in a single `CheckSubsidiaryCycleOp` |
156 entities to check at the end in a single `CheckSubsidiaryCycleOp` |
157 operation. Value are stored in a set associated to the |
157 operation. Values are stored in a set associated to the |
158 'subsidiary_cycle_detection' transaction data key. The set initialization and |
158 'subsidiary_cycle_detection' transaction data key. The set initialization and |
159 operation creation are handled nicely by :func:`set_operation`. |
159 operation creation are handled nicely by :func:`set_operation`. |
160 |
160 |
161 A more realistic example can be found in the advanced tutorial chapter |
161 A more realistic example can be found in the advanced tutorial chapter |
162 :ref:`adv_tuto_security_propagation`. |
162 :ref:`adv_tuto_security_propagation`. |