server/hook.py
branchstable
changeset 7157 7469fd77f48f
parent 7083 b8e35cde46e9
child 7237 9f619715665b
child 7286 a0d3ea01f4bf
equal deleted inserted replaced
7155:4bab50b02927 7157:7469fd77f48f
    91 Hooks are mostly defined and used to handle `dataflow`_ operations. It
    91 Hooks are mostly defined and used to handle `dataflow`_ operations. It
    92 means as data gets in (entities added, updated, relations set or
    92 means as data gets in (entities added, updated, relations set or
    93 unset), specific events are issued and the Hooks matching these events
    93 unset), specific events are issued and the Hooks matching these events
    94 are called.
    94 are called.
    95 
    95 
    96 You can get the event that triggered a hook by accessing its :attr:event
    96 You can get the event that triggered a hook by accessing its `event`
    97 attribute.
    97 attribute.
    98 
    98 
    99 .. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow
    99 .. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow
   100 
   100 
   101 
   101 
   103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   104 
   104 
   105 When called for one of these events, hook will have an `entity` attribute
   105 When called for one of these events, hook will have an `entity` attribute
   106 containing the entity instance.
   106 containing the entity instance.
   107 
   107 
   108 * `before_add_entity`, `before_update_entity`:
   108 - `before_add_entity`, `before_update_entity`:
   109 
   109 
   110   - on those events, you can check what attributes of the entity are modified in
   110   On those events, you can access the modified attributes of the entity using
   111     `entity.cw_edited` (by definition the database is not yet updated in a before
   111   the `entity.cw_edited` dictionnary. The values can be modified and the old
   112     event)
   112   values can be retrieved.
   113 
   113 
   114   - you are allowed to further modify the entity before database
   114   If you modify the `entity.cw_edited` dictionnary in the hook, that is before
   115     operations, using the dictionary notation on `cw_edited`. By doing
   115   the database operations take place, you will avoid the need to process a whole
   116     this, you'll avoid the need for a whole new rql query processing,
   116   new rql query and the underlying backend query (eg usually sql) will contain
   117     the only difference is that the underlying backend query (eg
   117   the modified data. For example:
   118     usually sql) will contains the additional data. For example:
   118 
   119 
   119   .. sourcecode:: python
   120     .. sourcecode:: python
   120 
   121 
   121      self.entity.cw_edited['age'] = 42
   122        self.entity.set_attributes(age=42)
   122 
   123 
   123   will modify the age before it is written to the backend storage.
   124     will set the `age` attribute of the entity to 42. But to do so, it will
   124 
   125     generate a rql query that will have to be processed, then trigger some
   125   Similarly, removing an attribute from `cw_edited` will cancel its
   126     hooks, and so one (potentially leading to infinite hook loops or such
   126   modification:
   127     awkward situations..) You can avoid this by doing the modification that way:
   127 
   128 
   128   .. sourcecode:: python
   129     .. sourcecode:: python
   129 
   130 
   130      del self.entity.cw_edited['age']
   131        self.entity.cw_edited['age'] = 42
   131 
   132 
   132   On a `before_update_entity` event, you can access the old and new values:
   133     Here the attribute will simply be edited in the same query that the
   133 
   134     one that triggered the hook.
   134   .. sourcecode:: python
   135 
   135 
   136     Similarly, removing an attribute from `cw_edited` will cancel its
   136      old, new = entity.cw_edited.oldnewvalue('age')
   137     modification.
   137 
   138 
   138 - `after_add_entity`, `after_update_entity`
   139   - on `before_update_entity` event, you can access to old and new values in
   139 
   140     this hook, by using `entity.cw_edited.oldnewvalue(attr)`
   140   On those events, you can get the list of attributes that were modified using
   141 
   141   the `entity.cw_edited` dictionnary, but you can not modify it or get the old
   142 
   142   value of an attribute.
   143 * `after_add_entity`, `after_update_entity`
   143 
   144 
   144 - `before_delete_entity`, `after_delete_entity`
   145   - on those events, you can still check what attributes of the entity are
   145 
   146     modified in `entity.cw_edited` but you can't get anymore the old value, nor
   146   On those events, the entity has no `cw_edited` dictionnary.
   147     modify it.
   147 
   148 
   148 .. note:: `self.entity.set_attributes(age=42)` will set the `age` attribute to
   149 * `before_delete_entity`, `after_delete_entity`
   149   42. But to do so, it will generate a rql query that will have to be processed,
   150 
   150   hence may trigger some hooks, etc. This could lead to infinitely looping hooks.
   151   - on those events, the entity has no `cw_edited` set.
       
   152 
       
   153 
   151 
   154 Relation modification related events
   152 Relation modification related events
   155 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   153 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   156 
   154 
   157 When called for one of these events, hook will have `eidfrom`, `rtype`, `eidto`
   155 When called for one of these events, hook will have `eidfrom`, `rtype`, `eidto`
   158 attributes containing respectivly the eid of the subject entity, the relation
   156 attributes containing respectively the eid of the subject entity, the relation
   159 type and the eid of the object entity.
   157 type and the eid of the object entity.
   160 
   158 
   161 * `before_add_relation`, `before_delete_relation`
   159 * `before_add_relation`, `before_delete_relation`
   162 
   160 
   163   - on those events, you can still get original relation by issuing a rql query
   161   On those events, you can still get the original relation by issuing a rql query.
   164 
   162 
   165 * `after_add_relation`, `after_delete_relation`
   163 * `after_add_relation`, `after_delete_relation`
   166 
   164 
   167 This is an occasion to remind us that relations support the add / delete
   165 Take note that relations can be added or deleted, but not updated.
   168 operation, but no update.
       
   169 
       
   170 
   166 
   171 Non data events
   167 Non data events
   172 ~~~~~~~~~~~~~~~
   168 ~~~~~~~~~~~~~~~
   173 
   169 
   174 Hooks called on server start/maintenance/stop event (eg `server_startup`,
   170 Hooks called on server start/maintenance/stop event (eg `server_startup`,