cubicweb/server/hook.py
author Philippe Pepiot <philippe.pepiot@logilab.fr>
Thu, 05 Mar 2020 10:15:38 +0100
changeset 12900 2cc3f481ecd0
parent 12870 2695357a8bfc
permissions -rw-r--r--
Merge 3.27
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11765
diff changeset
     1
# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5287
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    18
"""
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    19
Generalities
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    20
------------
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    21
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    22
Paraphrasing the `emacs`_ documentation, let us say that hooks are an important
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    23
mechanism for customizing an application. A hook is basically a list of
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    24
functions to be called on some well-defined occasion (this is called `running
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    25
the hook`).
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    26
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    27
.. _`emacs`: http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    28
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    29
Hooks
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    30
~~~~~
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    31
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    32
In |cubicweb|, hooks are subclasses of the :class:`~cubicweb.server.hook.Hook`
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    33
class. They are selected over a set of pre-defined `events` (and possibly more
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    34
conditions, hooks being selectable appobjects like views and components).  They
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    35
should implement a :meth:`~cubicweb.server.hook.Hook.__call__` method that will
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    36
be called when the hook is triggered.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    38
There are two families of events: data events (before / after any individual
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    39
update of an entity / or a relation in the repository) and server events (such
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    40
as server startup or shutdown).  In a typical application, most of the hooks are
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    41
defined over data events.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    42
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    43
Also, some :class:`~cubicweb.server.hook.Operation` may be registered by hooks,
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
    44
which will be fired when the transaction is commited or rolled back.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    45
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    46
The purpose of data event hooks is usually to complement the data model as
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    47
defined in the schema, which is static by nature and only provide a restricted
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    48
builtin set of dynamic constraints, with dynamic or value driven behaviours.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    49
For instance they can serve the following purposes:
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    50
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    51
* enforcing constraints that the static schema cannot express (spanning several
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    52
  entities/relations, exotic value ranges and cardinalities, etc.)
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    53
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    54
* implement computed attributes
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    55
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    56
It is functionally equivalent to a `database trigger`_, except that database
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    57
triggers definition languages are not standardized, hence not portable (for
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    58
instance, PL/SQL works with Oracle and PostgreSQL but not SqlServer nor Sqlite).
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    59
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    60
.. _`database trigger`: http://en.wikipedia.org/wiki/Database_trigger
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
6366
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
    63
.. hint::
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
    64
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
    65
   It is a good practice to write unit tests for each hook. See an example in
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
    66
   :ref:`hook_test`
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
    67
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    68
Operations
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    69
~~~~~~~~~~
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    70
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    71
Operations are subclasses of the :class:`~cubicweb.server.hook.Operation` class
7638
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    72
that may be created by hooks and scheduled to happen on `precommit`,
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    73
`postcommit` or `rollback` event (i.e. respectivly before/after a commit or
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    74
before a rollback of a transaction).
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    75
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    76
Hooks are being fired immediately on data operations, and it is sometime
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    77
necessary to delay the actual work down to a time where we can expect all
12621
092d201a7c17 [doc] fix several typos
Noe Gaumont <ngaumont@logilab.fr>
parents: 12578
diff changeset
    78
information to be there, or when all other hooks have run (though take care
7638
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    79
since operations may themselves trigger hooks). Also while the order of
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    80
execution of hooks is data dependant (and thus hard to predict), it is possible
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    81
to force an order on operations.
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    82
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    83
So, for such case where you may miss some information that may be set later in
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    84
the transaction, you should instantiate an operation in the hook.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    85
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    86
Operations may be used to:
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    87
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    88
* implements a validation check which needs that all relations be already set on
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    89
  an entity
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    90
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    91
* process various side effects associated with a transaction such as filesystem
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    92
  udpates, mail notifications, etc.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    93
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    94
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    95
Events
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    96
------
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    97
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    98
Hooks are mostly defined and used to handle `dataflow`_ operations. It
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
    99
means as data gets in (entities added, updated, relations set or
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   100
unset), specific events are issued and the Hooks matching these events
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   101
are called.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   102
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   103
You can get the event that triggered a hook by accessing its `event`
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   104
attribute.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   105
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   106
.. _`dataflow`: http://en.wikipedia.org/wiki/Dataflow
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   109
Entity modification related events
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   110
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   111
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   112
When called for one of these events, hook will have an `entity` attribute
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   113
containing the entity instance.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   114
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   115
- `before_add_entity`, `before_update_entity`:
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   116
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   117
  On those events, you can access the modified attributes of the entity using
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   118
  the `entity.cw_edited` dictionary. The values can be modified and the old
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   119
  values can be retrieved.
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   120
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   121
  If you modify the `entity.cw_edited` dictionary in the hook, that is before
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   122
  the database operations take place, you will avoid the need to process a whole
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   123
  new rql query and the underlying backend query (eg usually sql) will contain
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   124
  the modified data. For example:
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   125
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   126
  .. sourcecode:: python
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   127
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   128
     self.entity.cw_edited['age'] = 42
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   129
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   130
  will modify the age before it is written to the backend storage.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   131
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   132
  Similarly, removing an attribute from `cw_edited` will cancel its
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   133
  modification:
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   134
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   135
  .. sourcecode:: python
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   136
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   137
     del self.entity.cw_edited['age']
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   138
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   139
  On a `before_update_entity` event, you can access the old and new values:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   141
  .. sourcecode:: python
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   142
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   143
     old, new = entity.cw_edited.oldnewvalue('age')
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   144
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   145
- `after_add_entity`, `after_update_entity`
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   146
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   147
  On those events, you can get the list of attributes that were modified using
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   148
  the `entity.cw_edited` dictionary, but you can not modify it or get the old
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   149
  value of an attribute.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   150
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   151
- `before_delete_entity`, `after_delete_entity`
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   152
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   153
  On those events, the entity has no `cw_edited` dictionary.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   154
8483
4ba11607d84a [entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   155
.. note:: `self.entity.cw_set(age=42)` will set the `age` attribute to
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   156
  42. But to do so, it will generate a rql query that will have to be processed,
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   157
  hence may trigger some hooks, etc. This could lead to infinitely looping hooks.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   158
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   159
Relation modification related events
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   160
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   161
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   162
When called for one of these events, hook will have `eidfrom`, `rtype`, `eidto`
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   163
attributes containing respectively the eid of the subject entity, the relation
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   164
type and the eid of the object entity.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   165
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   166
* `before_add_relation`, `before_delete_relation`
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   167
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   168
  On those events, you can still get the original relation by issuing a rql query.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   169
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   170
* `after_add_relation`, `after_delete_relation`
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   171
9314
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   172
Specific selectors are shipped for these kinds of events, see in particular
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   173
:class:`~cubicweb.server.hook.match_rtype`.
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   174
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   175
Also note that relations can be added or deleted, but not updated.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   176
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   177
Non data events
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   178
~~~~~~~~~~~~~~~
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
8394
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   180
Hooks called on server start/maintenance/stop event (e.g.
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   181
`server_startup`, `server_maintenance`, `before_server_shutdown`,
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   182
`server_shutdown`) have a `repo` attribute, but *their `_cw` attribute
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   183
is None*.  The `server_startup` is called on regular startup, while
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   184
`server_maintenance` is called on cubicweb-ctl upgrade or shell
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   185
commands. `server_shutdown` is called anyway but connections to the
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   186
native source is impossible; `before_server_shutdown` handles that.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   187
8394
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   188
Hooks called on backup/restore event (eg `server_backup`,
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   189
`server_restore`) have a `repo` and a `timestamp` attributes, but
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   190
*their `_cw` attribute is None*.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   191
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   192
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   193
API
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   194
---
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   195
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   196
Hooks control
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   197
~~~~~~~~~~~~~
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   198
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   199
It is sometimes convenient to explicitly enable or disable some hooks. For
8561
77ea3eed9946 [session] promote usage of [deny|all]_all_hooks_but session methods rather than hooks_control context manager directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8535
diff changeset
   200
instance if you want to disable some integrity checking hook. This can be
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   201
controlled more finely through the `category` class attribute, which is a string
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   202
giving a category name.  One can then uses the
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   203
:meth:`~cubicweb.server.session.Connection.deny_all_hooks_but` and
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   204
:meth:`~cubicweb.server.session.Connection.allow_all_hooks_but` context managers to
8561
77ea3eed9946 [session] promote usage of [deny|all]_all_hooks_but session methods rather than hooks_control context manager directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8535
diff changeset
   205
explicitly enable or disable some categories.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   206
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   207
The existing categories are:
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   208
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   209
* ``security``, security checking hooks
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   210
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   211
* ``worfklow``, workflow handling hooks
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   212
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   213
* ``metadata``, hooks setting meta-data on newly created entities
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   214
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   215
* ``notification``, email notification hooks
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   216
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   217
* ``integrity``, data integrity checking hooks
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   218
6880
4be32427b2b9 [book] fixes some references and other doc construction pbs
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6834
diff changeset
   219
* ``activeintegrity``, data integrity consistency hooks, that you should **never**
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   220
  want to disable
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   221
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   222
* ``syncsession``, hooks synchronizing existing sessions
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   223
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   224
* ``syncschema``, hooks synchronizing instance schema (including the physical database)
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   225
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   226
* ``email``, email address handling hooks
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   227
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   228
* ``bookmark``, bookmark entities handling hooks
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   229
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   230
8561
77ea3eed9946 [session] promote usage of [deny|all]_all_hooks_but session methods rather than hooks_control context manager directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8535
diff changeset
   231
Nothing precludes one to invent new categories and use existing mechanisms to
77ea3eed9946 [session] promote usage of [deny|all]_all_hooks_but session methods rather than hooks_control context manager directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8535
diff changeset
   232
filter them in or out.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   233
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   234
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   235
Hooks specific predicates
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   236
~~~~~~~~~~~~~~~~~~~~~~~~~
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   237
.. autoclass:: cubicweb.server.hook.match_rtype
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   238
.. autoclass:: cubicweb.server.hook.match_rtype_sets
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   239
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   240
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   241
Hooks and operations classes
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   242
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   243
.. autoclass:: cubicweb.server.hook.Hook
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   244
.. autoclass:: cubicweb.server.hook.Operation
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   245
.. autoclass:: cubicweb.server.hook.LateOperation
6784
562dd184cbc7 [doc] fix bad class ref
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6767
diff changeset
   246
.. autoclass:: cubicweb.server.hook.DataOperationMixIn
5848
b5640328ffad [security] use set_operation for relation permission checking operation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5837
diff changeset
   247
"""
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10351
diff changeset
   248
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   249
from logging import getLogger
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   250
from itertools import chain
12900
2cc3f481ecd0 Merge 3.27
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12870
diff changeset
   251
from typing import Union, Tuple
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   252
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   253
from logilab.common.decorators import classproperty, cached
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   254
from logilab.common.logging_ext import set_log_methods
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9340
diff changeset
   255
from logilab.common.registry import (NotPredicate, OrPredicate,
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9340
diff changeset
   256
                                     objectify_predicate)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   257
8626
e2ba137b2bf9 [server] add debugging for Hooks & Operations (closes #2470048)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8596
diff changeset
   258
from cubicweb import RegistryNotFound, server
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   259
from cubicweb.cwvreg import CWRegistry, CWRegistryStore
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   260
from cubicweb.predicates import ExpectedValuePredicate, is_instance
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   261
from cubicweb.appobject import AppObject
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   262
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11765
diff changeset
   263
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   264
ENTITIES_HOOKS = set(('before_add_entity',    'after_add_entity',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   265
                      'before_update_entity', 'after_update_entity',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   266
                      'before_delete_entity', 'after_delete_entity'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   267
RELATIONS_HOOKS = set(('before_add_relation',   'after_add_relation' ,
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   268
                       'before_delete_relation','after_delete_relation'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   269
SYSTEM_HOOKS = set(('server_backup', 'server_restore',
8393
77c7158916c1 [events] add a new before_shutdown event (closes #2345728)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
   270
                    'server_startup', 'server_maintenance',
12036
4c2c731f9190 [session] Kill support for a 'session_open' hook event
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 12027
diff changeset
   271
                    'server_shutdown', 'before_server_shutdown',))
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11765
diff changeset
   272
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   273
ALL_HOOKS = ENTITIES_HOOKS | RELATIONS_HOOKS | SYSTEM_HOOKS
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   274
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11765
diff changeset
   275
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   276
def _iter_kwargs(entities, eids_from_to, kwargs):
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   277
    if not entities and not eids_from_to:
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   278
        yield kwargs
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   279
    elif entities:
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   280
        for entity in entities:
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   281
            kwargs['entity'] = entity
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   282
            yield kwargs
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   283
    else:
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   284
        for subject, object in eids_from_to:
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   285
            kwargs.update({'eidfrom': subject, 'eidto': object})
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   286
            yield kwargs
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   287
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   288
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   289
class HooksRegistry(CWRegistry):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   290
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   291
    def register(self, obj, **kwargs):
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   292
        obj.check_events()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   293
        super(HooksRegistry, self).register(obj, **kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   294
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   295
    def call_hooks(self, event, cnx=None, **kwargs):
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   296
        """call `event` hooks for an entity or a list of entities (passed
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   297
        respectively as the `entity` or ``entities`` keyword argument).
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   298
        """
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   299
        kwargs['event'] = event
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   300
        if cnx is None: # True for events such as server_start
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   301
            for hook in sorted(self.possible_objects(cnx, **kwargs),
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   302
                               key=lambda x: x.order):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
   303
                hook()
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   304
        else:
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   305
            if 'entities' in kwargs:
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   306
                assert 'entity' not in kwargs, \
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   307
                       'can\'t pass "entities" and "entity" arguments simultaneously'
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   308
                assert 'eids_from_to' not in kwargs, \
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   309
                       'can\'t pass "entities" and "eids_from_to" arguments simultaneously'
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   310
                entities = kwargs.pop('entities')
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   311
                eids_from_to = []
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   312
            elif 'eids_from_to' in kwargs:
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   313
                entities = []
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   314
                eids_from_to = kwargs.pop('eids_from_to')
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   315
            else:
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   316
                entities = []
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   317
                eids_from_to = []
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   318
            pruned = self.get_pruned_hooks(cnx, event,
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   319
                                           entities, eids_from_to, kwargs)
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   320
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   321
            # by default, hooks are executed with security turned off
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   322
            with cnx.security_enabled(read=False):
7237
9f619715665b [server] improve the speed of setting relations between entities (closes #1625257)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7157
diff changeset
   323
                for _kwargs in _iter_kwargs(entities, eids_from_to, kwargs):
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   324
                    hooks = sorted(self.filtered_possible_objects(pruned, cnx, **_kwargs),
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   325
                                   key=lambda x: x.order)
8626
e2ba137b2bf9 [server] add debugging for Hooks & Operations (closes #2470048)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8596
diff changeset
   326
                    debug = server.DEBUG & server.DBG_HOOKS
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   327
                    with cnx.security_enabled(write=False):
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   328
                        with cnx.running_hooks_ops():
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   329
                            for hook in hooks:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   330
                                if debug:
10589
7c23b7de2b8d [py3k] print function
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10351
diff changeset
   331
                                    print(event, _kwargs, hook)
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   332
                                hook()
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   333
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   334
    def get_pruned_hooks(self, cnx, event, entities, eids_from_to, kwargs):
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   335
        """return a set of hooks that should not be considered by filtered_possible objects
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   336
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   337
        the idea is to make a first pass over all the hooks in the
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   338
        registry and to mark put some of them in a pruned list. The
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   339
        pruned hooks are the one which:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   340
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   341
        * are disabled at the connection level
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   342
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   343
        * have a selector containing a :class:`match_rtype` or an
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   344
          :class:`is_instance` predicate which does not match the rtype / etype
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   345
          of the relations / entities for which we are calling the hooks. This
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   346
          works because the repository calls the hooks grouped by rtype or by
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   347
          etype when using the entities or eids_to_from keyword arguments
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   348
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   349
        Only hooks with a simple predicate or an AndPredicate of simple
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   350
        predicates are considered for disabling.
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   351
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   352
        """
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   353
        if 'entity' in kwargs:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   354
            entities = [kwargs['entity']]
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   355
        if len(entities):
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   356
            look_for_selector = is_instance
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   357
            etype = entities[0].__regid__
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   358
        elif 'rtype' in kwargs:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   359
            look_for_selector = match_rtype
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   360
            etype = None
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   361
        else: # nothing to prune, how did we get there ???
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   362
            return set()
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   363
        cache_key = (event, kwargs.get('rtype'), etype)
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   364
        pruned = cnx.pruned_hooks_cache.get(cache_key)
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   365
        if pruned is not None:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   366
            return pruned
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   367
        pruned = set()
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   368
        cnx.pruned_hooks_cache[cache_key] = pruned
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   369
        if look_for_selector is not None:
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10589
diff changeset
   370
            for id, hooks in self.items():
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   371
                for hook in hooks:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   372
                    enabled_cat, main_filter = hook.filterable_selectors()
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   373
                    if enabled_cat is not None:
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   374
                        if not enabled_cat(hook, cnx):
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   375
                            pruned.add(hook)
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   376
                            continue
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   377
                    if main_filter is not None:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   378
                        if isinstance(main_filter, match_rtype) and \
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   379
                           (main_filter.frometypes is not None  or \
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   380
                            main_filter.toetypes is not None):
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   381
                            continue
10669
155c29e0ed1c [py3k] use next builtin instead of next method
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
   382
                        first_kwargs = next(_iter_kwargs(entities, eids_from_to, kwargs))
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   383
                        if not main_filter(hook, cnx, **first_kwargs):
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   384
                            pruned.add(hook)
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   385
        return pruned
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   386
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   388
    def filtered_possible_objects(self, pruned, *args, **kwargs):
10663
54b8a1f249fb [py3k] dict.itervalues → dict.values
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
   389
        for appobjects in self.values():
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   390
            if pruned:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   391
                filtered_objects = [obj for obj in appobjects if obj not in pruned]
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   392
                if not filtered_objects:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   393
                    continue
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   394
            else:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   395
                filtered_objects = appobjects
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   396
            obj = self._select_best(filtered_objects,
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   397
                                    *args, **kwargs)
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   398
            if obj is None:
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   399
                continue
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   400
            yield obj
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   401
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   402
class HooksManager(object):
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   403
    def __init__(self, vreg):
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   404
        self.vreg = vreg
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   405
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   406
    def call_hooks(self, event, cnx=None, **kwargs):
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   407
        try:
6765
b922e3a817e9 fix ticket #1382716 (problem was actually more subtle than I originally thought)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6753
diff changeset
   408
            registry = self.vreg['%s_hooks' % event]
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   409
        except RegistryNotFound:
6765
b922e3a817e9 fix ticket #1382716 (problem was actually more subtle than I originally thought)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6753
diff changeset
   410
            return # no hooks for this event
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   411
        registry.call_hooks(event, cnx, **kwargs)
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   412
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   413
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   414
for event in ALL_HOOKS:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   415
    CWRegistryStore.REGISTRY_FACTORY['%s_hooks' % event] = HooksRegistry
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   416
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   417
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   418
# some hook specific predicates #################################################
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   419
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   420
@objectify_predicate
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   421
def enabled_category(cls, req, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   422
    if req is None:
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4699
diff changeset
   423
        return True # XXX how to deactivate server startup / shutdown event
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4699
diff changeset
   424
    return req.is_hook_activated(cls)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   425
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   426
@objectify_predicate
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   427
def issued_from_user_query(cls, req, **kwargs):
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   428
    return 0 if req.hooks_in_progress else 1
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10006
diff changeset
   429
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   430
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   431
class rechain(object):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   432
    def __init__(self, *iterators):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   433
        self.iterators = iterators
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   434
    def __iter__(self):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   435
        return iter(chain(*self.iterators))
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   436
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   437
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   438
class match_rtype(ExpectedValuePredicate):
9314
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   439
    """accept if the relation type is found in expected ones. Optional
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   440
    named parameters `frometypes` and `toetypes` can be used to restrict
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   441
    target subject and/or object entity types of the relation.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   442
12578
d06a2feae373 Fix DeprecationWarning: invalid escape sequence
Nsukami Patrick <ndkpatt at gmail dot com>
parents: 12567
diff changeset
   443
    :param *expected: possible relation types
9314
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   444
    :param frometypes: candidate entity types as subject of relation
178791fde195 [book] Improve match_rtype selector docstring and "Relation modification related events" section
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9267
diff changeset
   445
    :param toetypes: candidate entity types as object of relation
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   446
    """
4341
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   447
    def __init__(self, *expected, **more):
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   448
        self.expected = expected
4341
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   449
        self.frometypes = more.pop('frometypes', None)
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   450
        self.toetypes = more.pop('toetypes', None)
6767
0a18f25c16a7 check the validity of kwargs passed to match_rtype
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6765
diff changeset
   451
        assert not more, "unexpected kwargs in match_rtype: %s" % more
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   452
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   453
    def __call__(self, cls, req, *args, **kwargs):
4341
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   454
        if kwargs.get('rtype') not in self.expected:
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   455
            return 0
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   456
        if self.frometypes is not None and \
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   457
               req.entity_type(kwargs['eidfrom']) not in self.frometypes:
4341
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   458
            return 0
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   459
        if self.toetypes is not None and \
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   460
               req.entity_type(kwargs['eidto']) not in self.toetypes:
4341
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   461
            return 0
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   462
        return 1
2d2aa2526c56 match_rtype hook selector now accepts frometypes/toetypes optional arguments to match only given subject/object entity types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4339
diff changeset
   463
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   464
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   465
class match_rtype_sets(ExpectedValuePredicate):
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   466
    """accept if the relation type is in one of the sets given as initializer
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   467
    argument. The goal of this predicate is that it keeps reference to original sets,
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   468
    so modification to thoses sets are considered by the predicate. For instance
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   469
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   470
    .. sourcecode:: python
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   471
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   472
      MYSET = set()
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   473
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   474
      class Hook1(Hook):
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   475
          __regid__ = 'hook1'
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   476
          __select__ = Hook.__select__ & match_rtype_sets(MYSET)
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   477
          ...
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   478
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   479
      class Hook2(Hook):
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   480
          __regid__ = 'hook2'
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   481
          __select__ = Hook.__select__ & match_rtype_sets(MYSET)
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   482
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   483
    Client code can now change `MYSET`, this will changes the selection criteria
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   484
    of :class:`Hook1` and :class:`Hook1`.
4086
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   485
    """
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   486
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   487
    def __init__(self, *expected):
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   488
        self.expected = expected
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   489
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   490
    def __call__(self, cls, req, *args, **kwargs):
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   491
        for rel_set in self.expected:
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   492
            if kwargs.get('rtype') in rel_set:
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   493
                return 1
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   494
        return 0
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   495
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   496
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   497
# base class for hook ##########################################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   498
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   499
class Hook(AppObject):
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   500
    """Base class for hook.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   501
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   502
    Hooks being appobjects like views, they have a `__regid__` and a `__select__`
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   503
    class attribute. Like all appobjects, hooks have the `self._cw` attribute which
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   504
    represents the current connection. In entity hooks, a `self.entity` attribute is
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   505
    also present.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   506
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   507
    The `events` tuple is used by the base class selector to dispatch the hook
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   508
    on the right events. It is possible to dispatch on multiple events at once
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   509
    if needed (though take care as hook attribute may vary as described above).
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   510
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   511
    .. Note::
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   512
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   513
      Do not forget to extend the base class selectors as in:
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   514
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   515
      .. sourcecode:: python
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   516
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   517
          class MyHook(Hook):
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   518
            __regid__ = 'whatever'
6366
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
   519
            __select__ = Hook.__select__ & is_instance('Person')
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   520
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   521
      else your hooks will be called madly, whatever the event.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   522
    """
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   523
    __select__ = enabled_category()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   524
    # set this in derivated classes
12900
2cc3f481ecd0 Merge 3.27
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12870
diff changeset
   525
    events: Union[None, Tuple[str], Tuple[str, str]] = None
2cc3f481ecd0 Merge 3.27
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12870
diff changeset
   526
    category: Union[None, str] = None
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   527
    order = 0
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   528
    # stop pylint from complaining about missing attributes in Hooks classes
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7638
diff changeset
   529
    eidfrom = eidto = entity = rtype = repo = None
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   530
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   531
    @classmethod
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   532
    @cached
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   533
    def filterable_selectors(cls):
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   534
        search = cls.__select__.search_selector
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   535
        if search((NotPredicate, OrPredicate)):
7387
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   536
            return None, None
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   537
        enabled_cat = search(enabled_category)
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   538
        main_filter = search((is_instance, match_rtype))
d240cff2d8ba [hooks selection optimization] prune hooks when multiple entities are concerned by a hm.call_hooks() (closes: #1672022)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7288
diff changeset
   539
        return enabled_cat, main_filter
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   540
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   541
    @classmethod
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   542
    def check_events(cls):
5116
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   543
        try:
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   544
            for event in cls.events:
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   545
                if event not in ALL_HOOKS:
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   546
                    raise Exception('bad event %s on %s.%s' % (
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   547
                        event, cls.__module__, cls.__name__))
5116
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   548
        except AttributeError:
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   549
            raise
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   550
        except TypeError:
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   551
            raise Exception('bad .events attribute %s on %s.%s' % (
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   552
                cls.events, cls.__module__, cls.__name__))
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   553
8588
22af622e6e24 [hook] fix hook base class so access to __registries__ doesn't call check_event, only call it in registered callback. Closes #2517748
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8480
diff changeset
   554
    @classmethod
22af622e6e24 [hook] fix hook base class so access to __registries__ doesn't call check_event, only call it in registered callback. Closes #2517748
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8480
diff changeset
   555
    def __registered__(cls, reg):
22af622e6e24 [hook] fix hook base class so access to __registries__ doesn't call check_event, only call it in registered callback. Closes #2517748
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8480
diff changeset
   556
        cls.check_events()
22af622e6e24 [hook] fix hook base class so access to __registries__ doesn't call check_event, only call it in registered callback. Closes #2517748
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8480
diff changeset
   557
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   558
    @classproperty
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   559
    def __registries__(cls):
8588
22af622e6e24 [hook] fix hook base class so access to __registries__ doesn't call check_event, only call it in registered callback. Closes #2517748
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8480
diff changeset
   560
        if cls.events is None:
22af622e6e24 [hook] fix hook base class so access to __registries__ doesn't call check_event, only call it in registered callback. Closes #2517748
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8480
diff changeset
   561
            return []
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   562
        return ['%s_hooks' % ev for ev in cls.events]
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   563
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   564
    known_args = set(('entity', 'rtype', 'eidfrom', 'eidto', 'repo', 'timestamp'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   565
    def __init__(self, req, event, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   566
        for arg in self.known_args:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   567
            if arg in kwargs:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   568
                setattr(self, arg, kwargs.pop(arg))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   569
        super(Hook, self).__init__(req, **kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   570
        self.event = event
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   571
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   572
set_log_methods(Hook, getLogger('cubicweb.hook'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   573
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   574
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   575
# abtract hooks for relation propagation #######################################
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   576
# See example usage in hooks of the nosylist cube
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   577
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   578
class PropagateRelationHook(Hook):
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   579
    """propagate some `main_rtype` relation on entities linked as object of
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   580
    `subject_relations` or as subject of `object_relations` (the watched
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   581
    relations).
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   582
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   583
    This hook ensure that when one of the watched relation is added, the
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   584
    `main_rtype` relation is added to the target entity of the relation.
6345
1a7f4bfbf92b [doc] add note about propagation on deletion of a watched relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6263
diff changeset
   585
    Notice there are no default behaviour defined when a watched relation is
1a7f4bfbf92b [doc] add note about propagation on deletion of a watched relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6263
diff changeset
   586
    deleted, you'll have to handle this by yourself.
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   587
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   588
    You usually want to use the :class:`match_rtype_sets` predicate on concrete
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   589
    classes.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   590
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   591
    events = ('after_add_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   592
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   593
    # to set in concrete class
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   594
    main_rtype = None
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   595
    subject_relations = None
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   596
    object_relations = None
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   597
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   598
    def __call__(self):
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   599
        assert self.main_rtype
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   600
        for eid in (self.eidfrom, self.eidto):
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   601
            etype = self._cw.entity_type(eid)
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   602
            if self.main_rtype not in self._cw.vreg.schema.eschema(etype).subjrels:
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   603
                return
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   604
        if self.rtype in self.subject_relations:
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   605
            meid, seid = self.eidfrom, self.eidto
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   606
        else:
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   607
            assert self.rtype in self.object_relations
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   608
            meid, seid = self.eidto, self.eidfrom
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   609
        self._cw.execute(
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   610
            'SET E %s P WHERE X %s P, X eid %%(x)s, E eid %%(e)s, NOT E %s P'
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   611
            % (self.main_rtype, self.main_rtype, self.main_rtype),
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   612
            {'x': meid, 'e': seid})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   613
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   614
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   615
class PropagateRelationAddHook(Hook):
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   616
    """Propagate to entities at the end of watched relations when a `main_rtype`
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   617
    relation is added.
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   618
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   619
    `subject_relations` and `object_relations` attributes should be specified on
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   620
    subclasses and are usually shared references with attributes of the same
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   621
    name on :class:`PropagateRelationHook`.
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   622
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   623
    Because of those shared references, you can use `skip_subject_relations` and
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   624
    `skip_object_relations` attributes when you don't want to propagate to
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   625
    entities linked through some particular relations.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   626
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   627
    events = ('after_add_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   628
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   629
    # to set in concrete class (mandatory)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   630
    subject_relations = None
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   631
    object_relations = None
10903
da30851f9706 spelling: *aly → *ally
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10669
diff changeset
   632
    # to set in concrete class (optionally)
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   633
    skip_subject_relations = ()
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   634
    skip_object_relations = ()
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   635
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   636
    def __call__(self):
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   637
        eschema = self._cw.vreg.schema.eschema(self._cw.entity_type(self.eidfrom))
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   638
        execute = self._cw.execute
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   639
        for rel in self.subject_relations:
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   640
            if rel in eschema.subjrels and not rel in self.skip_subject_relations:
3090
8184bec7414d backport 3.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3087
diff changeset
   641
                execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   642
                        'X %s R, NOT R %s P' % (self.rtype, rel, self.rtype),
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   643
                        {'x': self.eidfrom, 'p': self.eidto})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   644
        for rel in self.object_relations:
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   645
            if rel in eschema.objrels and not rel in self.skip_object_relations:
3090
8184bec7414d backport 3.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3087
diff changeset
   646
                execute('SET R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   647
                        'R %s X, NOT R %s P' % (self.rtype, rel, self.rtype),
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   648
                        {'x': self.eidfrom, 'p': self.eidto})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   649
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   650
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   651
class PropagateRelationDelHook(PropagateRelationAddHook):
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   652
    """Propagate to entities at the end of watched relations when a `main_rtype`
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   653
    relation is deleted.
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   654
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   655
    This is the opposite of the :class:`PropagateRelationAddHook`, see its
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   656
    documentation for how to use this class.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   657
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   658
    events = ('after_delete_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   659
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   660
    def __call__(self):
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   661
        eschema = self._cw.vreg.schema.eschema(self._cw.entity_type(self.eidfrom))
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   662
        execute = self._cw.execute
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   663
        for rel in self.subject_relations:
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   664
            if rel in eschema.subjrels and not rel in self.skip_subject_relations:
3090
8184bec7414d backport 3.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3087
diff changeset
   665
                execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   666
                        'X %s R' % (self.rtype, rel),
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   667
                        {'x': self.eidfrom, 'p': self.eidto})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   668
        for rel in self.object_relations:
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   669
            if rel in eschema.objrels and not rel in self.skip_object_relations:
3090
8184bec7414d backport 3.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3087
diff changeset
   670
                execute('DELETE R %s P WHERE X eid %%(x)s, P eid %%(p)s, '
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   671
                        'R %s X' % (self.rtype, rel),
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   672
                        {'x': self.eidfrom, 'p': self.eidto})
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   673
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   674
6263
e91ac6e95116 [propagation hooks] support to skip some relation when propagating to linked entities. Proper renaming and enhance documentation on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   675
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   676
# abstract classes for operation ###############################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   677
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   678
class Operation(object):
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   679
    """Base class for operations.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   680
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   681
    Operation may be instantiated in the hooks' `__call__` method. It always
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   682
    takes a connection object as first argument (accessible as `.cnx` from the
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   683
    operation instance), and optionally all keyword arguments needed by the
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   684
    operation. These keyword arguments will be accessible as attributes from the
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   685
    operation instance.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   686
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7387
diff changeset
   687
    An operation is triggered on connections set events related to commit /
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7387
diff changeset
   688
    rollback transations. Possible events are:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   689
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   690
    * `precommit`:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   691
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   692
      the transaction is being prepared for commit. You can freely do any heavy
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   693
      computation, raise an exception if the commit can't go. or even add some
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   694
      new operations during this phase. If you do anything which has to be
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   695
      reverted if the commit fails afterwards (eg altering the file system for
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   696
      instance), you'll have to support the 'revertprecommit' event to revert
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   697
      things by yourself
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   698
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   699
    * `revertprecommit`:
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   700
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   701
      if an operation failed while being pre-commited, this event is triggered
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   702
      for all operations which had their 'precommit' event already fired to let
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   703
      them revert things (including the operation which made the commit fail)
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   704
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   705
    * `rollback`:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   706
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
   707
      the transaction has been either rolled back either:
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   708
10903
da30851f9706 spelling: *aly → *ally
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10669
diff changeset
   709
       * intentionally
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
   710
       * a 'precommit' event failed, in which case all operations are rolled back
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   711
         once 'revertprecommit'' has been called
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   712
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   713
    * `postcommit`:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   714
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   715
      the transaction is over. All the ORM entities accessed by the earlier
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   716
      transaction are invalid. If you need to work on the database, you need to
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   717
      start a new transaction, for instance using a new internal connection,
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   718
      which you will need to commit.
5837
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   719
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   720
    For an operation to support an event, one has to implement the `<event
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   721
    name>_event` method with no arguments.
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   722
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   723
    The order of operations may be important, and is controlled according to
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   724
    the insert_index's method output (whose implementation vary according to the
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   725
    base hook class used).
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   726
    """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   727
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   728
    def __init__(self, cnx, **kwargs):
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   729
        self.cnx = cnx
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   730
        self.__dict__.update(kwargs)
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   731
        self.register(cnx)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   732
        # execution information
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   733
        self.processed = None # 'precommit', 'commit'
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   734
        self.failed = False
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   735
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   736
    def register(self, cnx):
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   737
        cnx.add_operation(self, self.insert_index())
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   738
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   739
    def insert_index(self):
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   740
        """return the index of the latest instance which is not a
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   741
        LateOperation instance
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   742
        """
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   743
        # faster by inspecting operation in reverse order for heavy transactions
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   744
        i = None
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   745
        for i, op in enumerate(reversed(self.cnx.pending_operations)):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   746
            if isinstance(op, (LateOperation, SingleLastOperation)):
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   747
                continue
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   748
            return -i or None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   749
        if i is None:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   750
            return None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   751
        return -(i + 1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   752
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   753
    def handle_event(self, event):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   754
        """delegate event handling to the opertaion"""
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   755
        getattr(self, event)()
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   756
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   757
    def precommit_event(self):
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7387
diff changeset
   758
        """the observed connections set is preparing a commit"""
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   759
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   760
    def revertprecommit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   761
        """an error went when pre-commiting this operation or a later one
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   762
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   763
        should revert pre-commit's changes but take care, they may have not
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   764
        been all considered if it's this operation which failed
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   765
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   766
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   767
    def rollback_event(self):
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
   768
        """the observed connections set has been rolled back
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   769
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7387
diff changeset
   770
        do nothing by default
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   771
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   772
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   773
    def postcommit_event(self):
7398
26695dd703d8 [repository api] definitly kill usage of word 'pool' to refer to connections set used by a session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7387
diff changeset
   774
        """the observed connections set has committed"""
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   775
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   776
    # these are overridden by set_log_methods below
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   777
    # only defining here to prevent pylint from complaining
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   778
    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   779
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   780
set_log_methods(Operation, getLogger('cubicweb.session'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   781
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   782
def _container_add(container, value):
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   783
    {set: set.add, list: list.append}[container.__class__](container, value)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   784
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   785
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   786
class DataOperationMixIn(object):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   787
    """Mix-in class to ease applying a single operation on a set of data,
12621
092d201a7c17 [doc] fix several typos
Noe Gaumont <ngaumont@logilab.fr>
parents: 12578
diff changeset
   788
    avoiding creating as many operations as there are individual modifications.
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   789
    The body of the operation must then iterate over the values that have been
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   790
    stored in a single operation instance.
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   791
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   792
    You should try to use this instead of creating on operation for each
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   793
    `value`, since handling operations becomes costly on massive data import.
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   794
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   795
    Usage looks like:
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   796
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   797
    .. sourcecode:: python
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   798
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   799
        class MyEntityHook(Hook):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   800
            __regid__ = 'my.entity.hook'
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   801
            __select__ = Hook.__select__ & is_instance('MyEntity')
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   802
            events = ('after_add_entity',)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   803
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   804
            def __call__(self):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   805
                MyOperation.get_instance(self._cw).add_data(self.entity)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   806
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   807
6730
253dd28cc35f [hook] update DataOperationMixIn docstring
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6426
diff changeset
   808
        class MyOperation(DataOperationMixIn, Operation):
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   809
            def precommit_event(self):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   810
                for bucket in self.get_data():
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   811
                    process(bucket)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   812
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   813
    You can modify the `containercls` class attribute, which defines the
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   814
    container class that should be instantiated to hold payloads. An instance is
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   815
    created on instantiation, and then the :meth:`add_data` method will add the
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   816
    given data to the existing container. Default to a `set`. Give `list` if you
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   817
    want to keep arrival ordering. You can also use another kind of container
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   818
    by redefining :meth:`_build_container` and :meth:`add_data`
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   819
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   820
    More optional parameters can be given to the `get_instance` operation, that
7286
a0d3ea01f4bf [doc] fix doc and tutorials about hooks and operations
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7157
diff changeset
   821
    will be given to the operation constructor (for obvious reasons those
a0d3ea01f4bf [doc] fix doc and tutorials about hooks and operations
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7157
diff changeset
   822
    parameters should not vary accross different calls to this method for a
a0d3ea01f4bf [doc] fix doc and tutorials about hooks and operations
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7157
diff changeset
   823
    given operation).
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   824
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   825
    .. Note::
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   826
        For sanity reason `get_data` will reset the operation, so that once
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   827
        the operation has started its treatment, if some hook want to push
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   828
        additional data to this same operation, a new instance will be created
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   829
        (else that data has a great chance to be never treated). This implies:
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   830
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   831
        * you should **always** call `get_data` when starting treatment
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   832
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   833
        * you should **never** call `get_data` for another reason.
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   834
    """
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   835
    containercls = set
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   836
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   837
    @classproperty
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   838
    def data_key(cls):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   839
        return ('cw.dataops', cls.__name__)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   840
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   841
    @classmethod
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   842
    def get_instance(cls, cnx, **kwargs):
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   843
        # no need to lock: transaction_data already comes from thread's local storage
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   844
        try:
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   845
            return cnx.transaction_data[cls.data_key]
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   846
        except KeyError:
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   847
            op = cnx.transaction_data[cls.data_key] = cls(cnx, **kwargs)
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   848
            return op
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   849
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   850
    def __init__(self, *args, **kwargs):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   851
        super(DataOperationMixIn, self).__init__(*args, **kwargs)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   852
        self._container = self._build_container()
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   853
        self._processed = False
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   854
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   855
    def __contains__(self, value):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   856
        return value in self._container
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   857
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   858
    def _build_container(self):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   859
        return self.containercls()
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   860
7498
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   861
    def union(self, data):
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   862
        """only when container is a set"""
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   863
        assert not self._processed, """Trying to add data to a closed operation.
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   864
Iterating over operation data closed it and should be reserved to precommit /
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   865
postcommit method of the operation."""
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   866
        self._container |= data
dc823b9ce74b [data hook] new .union operation on DataOperationMixIn, only when container is a set, not a list
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7288
diff changeset
   867
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   868
    def add_data(self, data):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   869
        assert not self._processed, """Trying to add data to a closed operation.
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   870
Iterating over operation data closed it and should be reserved to precommit /
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   871
postcommit method of the operation."""
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   872
        _container_add(self._container, data)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   873
6993
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   874
    def remove_data(self, data):
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   875
        assert not self._processed, """Trying to add data to a closed operation.
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   876
Iterating over operation data closed it and should be reserved to precommit /
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   877
postcommit method of the operation."""
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   878
        self._container.remove(data)
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   879
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   880
    def get_data(self):
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   881
        assert not self._processed, """Trying to get data from a closed operation.
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   882
Iterating over operation data closed it and should be reserved to precommit /
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   883
postcommit method of the operation."""
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   884
        self._processed = True
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   885
        op = self.cnx.transaction_data.pop(self.data_key)
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   886
        assert op is self, "Bad handling of operation data, found %s instead of %s for key %s" % (
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   887
            op, self, self.data_key)
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   888
        return self._container
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   889
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   890
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   891
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   892
class LateOperation(Operation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   893
    """special operation which should be called after all possible (ie non late)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   894
    operations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   895
    """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   896
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   897
        """return the index of  the lastest instance which is not a
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   898
        SingleLastOperation instance
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   899
        """
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   900
        # faster by inspecting operation in reverse order for heavy transactions
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   901
        i = None
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   902
        for i, op in enumerate(reversed(self.cnx.pending_operations)):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   903
            if isinstance(op, SingleLastOperation):
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   904
                continue
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   905
            return -i or None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   906
        if i is None:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   907
            return None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   908
        return -(i + 1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   909
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   910
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   911
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   912
class SingleLastOperation(Operation):
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   913
    """special operation which should be called once and after all other
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   914
    operations
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   915
    """
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   916
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   917
    def register(self, cnx):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   918
        """override register to handle cases where this operation has already
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   919
        been added
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   920
        """
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   921
        operations = cnx.pending_operations
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   922
        index = self.equivalent_index(operations)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   923
        if index is not None:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   924
            equivalent = operations.pop(index)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   925
        else:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   926
            equivalent = None
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   927
        cnx.add_operation(self, self.insert_index())
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   928
        return equivalent
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   929
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   930
    def equivalent_index(self, operations):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   931
        """return the index of the equivalent operation if any"""
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   932
        for i, op in enumerate(reversed(operations)):
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   933
            if op.__class__ is self.__class__:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   934
                return -(i+1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   935
        return None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   936
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   937
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   938
        return None
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   939
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   940
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   941
class SendMailOp(SingleLastOperation):
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   942
    def __init__(self, cnx, msg=None, recipients=None, **kwargs):
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   943
        # may not specify msg yet, as
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   944
        # `cubicweb.sobjects.supervision.SupervisionMailOp`
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   945
        if msg is not None:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   946
            assert recipients
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   947
            self.to_send = [(msg, recipients)]
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   948
        else:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   949
            assert recipients is None
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   950
            self.to_send = []
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   951
        super(SendMailOp, self).__init__(cnx, **kwargs)
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   952
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   953
    def register(self, cnx):
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   954
        previous = super(SendMailOp, self).register(cnx)
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   955
        if previous:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   956
            self.to_send = previous.to_send + self.to_send
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   957
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   958
    def postcommit_event(self):
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   959
        self.cnx.repo.threaded_task(self.sendmails)
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   960
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   961
    def sendmails(self):
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   962
        self.cnx.vreg.config.sendmails(self.to_send)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   963
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   964
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   965
class RQLPrecommitOperation(Operation):
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7638
diff changeset
   966
    # to be defined in concrete classes
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7638
diff changeset
   967
    rqls = None
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7638
diff changeset
   968
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   969
    def precommit_event(self):
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   970
        execute = self.cnx.execute
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   971
        for rql in self.rqls:
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   972
            execute(*rql)
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   973
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   974
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   975
class CleanupNewEidsCacheOp(DataOperationMixIn, SingleLastOperation):
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   976
    """on rollback of a insert query we have to remove from repository's
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   977
    type/source cache eids of entities added in that transaction.
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   978
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   979
    NOTE: querier's rqlst/solutions cache may have been polluted too with
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
   980
    queries such as Any X WHERE X eid 32 if 32 has been rolled back however
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   981
    generated queries are unpredictable and analysing all the cache probably
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   982
    too expensive. Notice that there is no pb when using args to specify eids
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   983
    instead of giving them into the rql string.
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   984
    """
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   985
    data_key = 'neweids'
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   986
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   987
    def rollback_event(self):
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
   988
        """the observed connections set has been rolled back,
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   989
        remove inserted eid from repository type/source cache
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   990
        """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   991
        try:
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   992
            self.cnx.repo.clear_caches(self.get_data())
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   993
        except KeyError:
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   994
            pass
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   995
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
   996
class CleanupDeletedEidsCacheOp(DataOperationMixIn, SingleLastOperation):
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   997
    """on commit of delete query, we have to remove from repository's
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   998
    type/source cache eids of entities deleted in that transaction.
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   999
    """
6426
541659c39f6a [hook/operation] nicer api to achieve same result as set_operation, as described in #1253630
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6366
diff changeset
  1000
    data_key = 'pendingeids'
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
  1001
    def postcommit_event(self):
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 8694
diff changeset
  1002
        """the observed connections set has been rolled back,
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1003
        remove inserted eid from repository type/source cache
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1004
        """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1005
        try:
8211
543e1579ba0d [repo] Add a publish/subscribe mechanism for inter-instance communication using zmq
Julien Cristau <julien.cristau@logilab.fr>, Quentin Roquefort <quentin@kpsule.me>
parents: 8190
diff changeset
  1006
            eids = self.get_data()
9608
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
  1007
            self.cnx.repo.clear_caches(eids)
e4d9a489ec3f [server/hook] operations get a connection instead of a session
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
  1008
            self.cnx.repo.app_instances_bus.publish(['delete'] + list(str(eid) for eid in eids))
5067
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1009
        except KeyError:
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1010
            pass