server/hook.py
author Pierre-Yves David <pierre-yves.david@logilab.fr>
Tue, 25 Jun 2013 10:59:01 +0200
changeset 9070 4a803380f718
parent 8694 d901c36bcfce
child 9257 ce338133c92c
child 9267 24d9b86dfa54
permissions -rw-r--r--
PARTIAL: Using the repoapi in test Test now use the repoapi.ClientConnection to access the repo. This is very big change. The current method to access the repo are kept for backward compatibility. The new methods will be introduced much later. The TestCase keep a ClientConnection To an admin session for the whole test. This changeset does not makes all tests pass without the next one that change set htt without the next one that change the http stack
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
     1
# copyright 2003-2012 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,
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
    44
which will be fired when the transaction is commited or rollbacked.
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
cc7cde77184f [doc, hook] more backport of syt mbox documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7514
diff changeset
    78
information to be there, or when all other hooks have run (though take case
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
7157
7469fd77f48f [doc] improve dostring of server.hook
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 7083
diff changeset
   172
Take 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
   173
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
   174
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
   175
~~~~~~~~~~~~~~~
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
8394
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   177
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
   178
`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
   179
`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
   180
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
   181
`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
   182
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
   183
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
   184
8394
b8b23af60019 [server/hook] a tiny bit of doc about before_server_shutdown
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8393
diff changeset
   185
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
   186
`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
   187
*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
   188
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   189
Hooks called on session event (eg `session_open`, `session_close`) have no
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
   190
special 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
   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
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
   203
:meth:`~cubicweb.server.session.Session.deny_all_hooks_but` and
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
   204
:meth:`~cubicweb.server.session.Session.allow_all_hooks_but` context managers 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
   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
"""
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   248
__docformat__ = "restructuredtext en"
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   249
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   250
from warnings import warn
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   251
from logging import getLogger
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   252
from itertools import chain
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   253
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
   254
from logilab.common.decorators import classproperty, cached
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
   255
from logilab.common.deprecation import deprecated, class_renamed
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   256
from logilab.common.logging_ext import set_log_methods
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   257
from logilab.common.registry import (Predicate, NotPredicate, OrPredicate,
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8626
diff changeset
   258
                                     objectify_predicate, yes)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   259
8626
e2ba137b2bf9 [server] add debugging for Hooks & Operations (closes #2470048)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8596
diff changeset
   260
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
   261
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
   262
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
   263
from cubicweb.appobject import AppObject
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   264
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   265
ENTITIES_HOOKS = set(('before_add_entity',    'after_add_entity',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   266
                      'before_update_entity', 'after_update_entity',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   267
                      'before_delete_entity', 'after_delete_entity'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   268
RELATIONS_HOOKS = set(('before_add_relation',   'after_add_relation' ,
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   269
                       'before_delete_relation','after_delete_relation'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   270
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
   271
                    'server_startup', 'server_maintenance',
77c7158916c1 [events] add a new before_shutdown event (closes #2345728)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8239
diff changeset
   272
                    'server_shutdown', 'before_server_shutdown',
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   273
                    'session_open', 'session_close'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   274
ALL_HOOKS = ENTITIES_HOOKS | RELATIONS_HOOKS | SYSTEM_HOOKS
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
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
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
   295
    def call_hooks(self, event, session=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
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   300
        if session is None: # True for events such as server_start
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
   301
            for hook in sorted(self.possible_objects(session, **kwargs),
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 = []
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
   318
            pruned = self.get_pruned_hooks(session, event,
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)
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
   320
            # by default, hooks are executed with security turned off
8562
0d2fb4604265 [session] fix arguments default value and promote usage of security_enabled as session method. Closes #2481820
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8561
diff changeset
   321
            with session.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
   322
                for _kwargs in _iter_kwargs(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
   323
                    hooks = sorted(self.filtered_possible_objects(pruned, session, **_kwargs),
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   324
                                   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
   325
                    debug = server.DEBUG & server.DBG_HOOKS
8562
0d2fb4604265 [session] fix arguments default value and promote usage of security_enabled as session method. Closes #2481820
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8561
diff changeset
   326
                    with session.security_enabled(write=False):
6889
37668bf302f5 improve massive deletion performance
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6880
diff changeset
   327
                        for hook in hooks:
8626
e2ba137b2bf9 [server] add debugging for Hooks & Operations (closes #2470048)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8596
diff changeset
   328
                            if debug:
e2ba137b2bf9 [server] add debugging for Hooks & Operations (closes #2470048)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8596
diff changeset
   329
                                print event, _kwargs, hook
8426
1cb51cdb4ce7 [server/hook] fix identation
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8394
diff changeset
   330
                            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
   331
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
   332
    def get_pruned_hooks(self, session, event, entities, eids_from_to, 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
   333
        """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
   334
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
        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
   336
        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
   337
        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
   338
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
        * are disabled at the session level
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
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   341
        * 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
   342
          :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
   343
          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
   344
          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
   345
          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
   346
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   347
        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
   348
        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
   349
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
   350
        """
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
        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
   352
            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
   353
        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
   354
            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
   355
            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
   356
        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
   357
            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
   358
            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
   359
        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
   360
            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
   361
        cache_key = (event, kwargs.get('rtype'), etype)
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
        pruned = session.pruned_hooks_cache.get(cache_key)
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
        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
   364
            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
   365
        pruned = 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
   366
        session.pruned_hooks_cache[cache_key] = 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
        if look_for_selector 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
   368
            for id, hooks in self.iteritems():
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
                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
   370
                    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
   371
                    if enabled_cat 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
   372
                        if not enabled_cat(hook, session):
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
                            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
   374
                            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
   375
                    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
   376
                        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
   377
                           (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
   378
                            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
   379
                            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
   380
                        first_kwargs = _iter_kwargs(entities, eids_from_to, kwargs).next()
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
                        if not main_filter(hook, session, **first_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
   382
                            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
   383
        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
   384
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
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
    def filtered_possible_objects(self, pruned, *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
   387
        for appobjects in self.itervalues():
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
            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
   389
                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
   390
                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
   391
                    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
   392
            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
   393
                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
   394
            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
   395
                                    *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
   396
            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
   397
                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
   398
            yield obj
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   399
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   400
class HooksManager(object):
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   401
    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
   402
        self.vreg = vreg
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   403
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   404
    def call_hooks(self, event, session=None, **kwargs):
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   405
        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
   406
            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
   407
        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
   408
            return # no hooks for this event
b922e3a817e9 fix ticket #1382716 (problem was actually more subtle than I originally thought)
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6753
diff changeset
   409
        registry.call_hooks(event, session, **kwargs)
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   410
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   411
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   412
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
   413
    CWRegistryStore.REGISTRY_FACTORY['%s_hooks' % event] = HooksRegistry
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   414
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   415
@deprecated('[3.10] use entity.cw_edited.oldnewvalue(attr)')
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   416
def entity_oldnewvalue(entity, attr):
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   417
    return entity.cw_edited.oldnewvalue(attr)
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   418
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
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
# some hook specific predicates #################################################
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   421
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   422
@objectify_predicate
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   423
def enabled_category(cls, req, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   424
    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
   425
        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
   426
    return req.is_hook_activated(cls)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   427
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   428
@objectify_predicate
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
   429
def from_dbapi_query(cls, req, **kwargs):
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
   430
    if req.running_dbapi_query:
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
   431
        return 1
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
   432
    return 0
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   433
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   434
class rechain(object):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   435
    def __init__(self, *iterators):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   436
        self.iterators = iterators
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   437
    def __iter__(self):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   438
        return iter(chain(*self.iterators))
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   439
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   440
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   441
class match_rtype(ExpectedValuePredicate):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   442
    """accept if parameters specified as initializer arguments are specified
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   443
    in named arguments given to the predicate
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   444
8032
bcb87336c7d2 [doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   445
    :param \*expected: parameters (eg `basestring`) which are expected to be
bcb87336c7d2 [doc] fix most of ReST compilation errors and warnings
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 7990
diff changeset
   446
                       found in named arguments (kwargs)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   447
    """
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
   448
    def __init__(self, *expected, **more):
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   449
        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
   450
        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
   451
        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
   452
        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
   453
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   454
    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
   455
        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
   456
            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
   457
        if self.frometypes is not None and \
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
               req.describe(kwargs['eidfrom'])[0] not in self.frometypes:
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
            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
   460
        if self.toetypes is not None and \
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
               req.describe(kwargs['eidto'])[0] not in self.toetypes:
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 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
   463
        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
   464
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   465
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   466
class match_rtype_sets(ExpectedValuePredicate):
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   467
    """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
   468
    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
   469
    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
   470
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   471
    .. sourcecode:: python
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   472
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   473
      MYSET = set()
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   474
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   475
      class Hook1(Hook):
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   476
          __regid__ = 'hook1'
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   477
          __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
   478
          ...
6834
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   479
8480
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   480
      class Hook2(Hook):
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   481
          __regid__ = 'hook2'
086cff6a306a [book] fix build warnings/errors. Closes #2430042
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8426
diff changeset
   482
          __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
   483
b4befa12bbcc [doc] fix match_rtype_sets docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6831
diff changeset
   484
    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
   485
    of :class:`Hook1` and :class:`Hook1`.
4086
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
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   488
    def __init__(self, *expected):
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   489
        self.expected = expected
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   490
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   491
    def __call__(self, cls, req, *args, **kwargs):
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   492
        for rel_set in self.expected:
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   493
            if kwargs.get('rtype') in rel_set:
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   494
                return 1
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   495
        return 0
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   496
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   497
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   498
# base class for hook ##########################################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   499
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   500
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
   501
    """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
   502
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
    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
   504
    class attribute. Like all appobjects, hooks have the `self._cw` attribute which
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
    represents the current session. In entity hooks, a `self.entity` attribute is
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
    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
   507
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
    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
   509
    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
   510
    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
   511
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
    .. 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
   513
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   514
      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
   515
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
      .. 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
   517
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
          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
   519
            __regid__ = 'whatever'
6366
1806148d6ce8 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6279 6345
diff changeset
   520
            __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
   521
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
      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
   523
    """
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   524
    __select__ = enabled_category()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   525
    # set this in derivated classes
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   526
    events = None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   527
    category = None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   528
    order = 0
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   529
    # 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
   530
    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
   531
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
   532
    @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
   533
    @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
   534
    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
   535
        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
   536
        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
   537
            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
   538
        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
   539
        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
   540
        return enabled_cat, main_filter
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   541
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   542
    @classmethod
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   543
    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
   544
        try:
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   545
            for event in cls.events:
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   546
                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
   547
                    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
   548
                        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
   549
        except AttributeError:
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   550
            raise
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   551
        except TypeError:
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   552
            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
   553
                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
   554
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
   555
    @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
   556
    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
   557
        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
   558
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   559
    @classproperty
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   560
    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
   561
        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
   562
            return []
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   563
        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
   564
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   565
    known_args = set(('entity', 'rtype', 'eidfrom', 'eidto', 'repo', 'timestamp'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   566
    def __init__(self, req, event, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   567
        for arg in self.known_args:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   568
            if arg in kwargs:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   569
                setattr(self, arg, kwargs.pop(arg))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   570
        super(Hook, self).__init__(req, **kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   571
        self.event = event
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   572
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   573
set_log_methods(Hook, getLogger('cubicweb.hook'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   574
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   575
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
   576
# 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
   577
# 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
   578
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
   579
class PropagateRelationHook(Hook):
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   580
    """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
   581
    `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
   582
    relations).
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   583
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   584
    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
   585
    `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
   586
    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
   587
    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
   588
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8032
diff changeset
   589
    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
   590
    classes.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   591
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   592
    events = ('after_add_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   593
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   594
    # to set in concrete class
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   595
    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
   596
    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
   597
    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
   598
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   599
    def __call__(self):
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   600
        assert self.main_rtype
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   601
        for eid in (self.eidfrom, self.eidto):
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   602
            etype = self._cw.describe(eid)[0]
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   603
            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
   604
                return
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   605
        if self.rtype in self.subject_relations:
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   606
            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
   607
        else:
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   608
            assert self.rtype in self.object_relations
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   609
            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
   610
        self._cw.execute(
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   611
            '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
   612
            % (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
   613
            {'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
   614
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   615
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
   616
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
   617
    """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
   618
    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
   619
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
    `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
   621
    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
   622
    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
   623
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
    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
   625
    `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
   626
    entities linked through some particular relations.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   627
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   628
    events = ('after_add_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   629
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
   630
    # 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
   631
    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
   632
    object_relations = None
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
    # to set in concrete class (optionaly)
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_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
   635
    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
   636
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   637
    def __call__(self):
4104
7e478d7caf20 [mq]: small_api_changes_for_3.6
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4086
diff changeset
   638
        eschema = self._cw.vreg.schema.eschema(self._cw.describe(self.eidfrom)[0])
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
   639
        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
   640
        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
   641
            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
   642
                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
   643
                        '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
   644
                        {'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
   645
        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
   646
            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
   647
                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
   648
                        '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
   649
                        {'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
   650
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   651
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
   652
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
   653
    """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
   654
    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
   655
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
    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
   657
    documentation for how to use this class.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   658
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   659
    events = ('after_delete_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   660
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   661
    def __call__(self):
4104
7e478d7caf20 [mq]: small_api_changes_for_3.6
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4086
diff changeset
   662
        eschema = self._cw.vreg.schema.eschema(self._cw.describe(self.eidfrom)[0])
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
   663
        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
   664
        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
   665
            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
   666
                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
   667
                        '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
   668
                        {'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
   669
        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
   670
            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
   671
                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
   672
                        '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
   673
                        {'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
   674
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   675
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
   676
PropagateSubjectRelationHook = class_renamed(
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
   677
    'PropagateSubjectRelationHook', 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
   678
    '[3.9] PropagateSubjectRelationHook has been renamed to 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
   679
PropagateSubjectRelationAddHook = class_renamed(
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
   680
    'PropagateSubjectRelationAddHook', 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
   681
    '[3.9] PropagateSubjectRelationAddHook has been renamed to 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
   682
PropagateSubjectRelationDelHook = class_renamed(
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
   683
    'PropagateSubjectRelationDelHook', PropagateRelationDelHook,
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
   684
    '[3.9] PropagateSubjectRelationDelHook has been renamed to PropagateRelationDelHook')
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
   685
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
   686
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   687
# abstract classes for operation ###############################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   688
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   689
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
   690
    """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
   691
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
    Operation may be instantiated in the hooks' `__call__` method. It always
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
    takes a session object as first argument (accessible as `.session` 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
   694
    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
   695
    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
   696
    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
   697
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
   698
    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
   699
    rollback transations. Possible events are:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   700
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   701
    * `precommit`:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   702
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
   703
      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
   704
      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
   705
      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
   706
      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
   707
      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
   708
      things by yourself
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   709
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   710
    * `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
   711
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
      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
   713
      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
   714
      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
   715
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   716
    * `rollback`:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   717
5220
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   718
      the transaction has been either rollbacked 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
   719
5220
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   720
       * intentionaly
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
   721
       * a 'precommit' event failed, in which case all operations are rollbacked
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
         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
   723
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   724
    * `postcommit`:
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   725
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
   726
      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
   727
      transaction are invalid. If you need to work on the database, you need 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
   728
      start a new transaction, for instance using a new internal session, which
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
   729
      you will need to commit (and close!).
5837
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   730
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
   731
    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
   732
    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
   733
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   734
    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
   735
    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
   736
    base hook class used).
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   737
    """
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 __init__(self, session, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   740
        self.session = session
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   741
        self.__dict__.update(kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   742
        self.register(session)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   743
        # execution information
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   744
        self.processed = None # 'precommit', 'commit'
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   745
        self.failed = False
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   746
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   747
    def register(self, session):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   748
        session.add_operation(self, self.insert_index())
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   749
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   750
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   751
        """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
   752
        LateOperation instance
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   753
        """
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   754
        # faster by inspecting operation in reverse order for heavy transactions
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   755
        i = None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   756
        for i, op in enumerate(reversed(self.session.pending_operations)):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   757
            if isinstance(op, (LateOperation, SingleLastOperation)):
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   758
                continue
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   759
            return -i or None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   760
        if i is None:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   761
            return None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   762
        return -(i + 1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   763
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   764
    def handle_event(self, event):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   765
        """delegate event handling to the opertaion"""
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   766
        if event == 'postcommit_event' and hasattr(self, 'commit_event'):
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   767
            warn('[3.10] %s: commit_event method has been replaced by postcommit_event'
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8626
diff changeset
   768
                 % self.__class__, DeprecationWarning)
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
   769
            self.commit_event() # pylint: disable=E1101
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   770
        getattr(self, event)()
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
    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
   773
        """the observed connections set is preparing a commit"""
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   774
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   775
    def revertprecommit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   776
        """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
   777
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   778
        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
   779
        been all considered if it's this operation which failed
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   780
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   781
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   782
    def rollback_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
   783
        """the observed connections set has been rollbacked
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   784
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
   785
        do nothing by default
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   786
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   787
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   788
    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
   789
        """the observed connections set has committed"""
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   790
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 6993
diff changeset
   791
    # 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
   792
    # 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
   793
    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
   794
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   795
set_log_methods(Operation, getLogger('cubicweb.session'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   796
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   797
def _container_add(container, value):
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   798
    {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
   799
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
   800
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
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
   802
    """Mix-in class to ease applying a single operation on a set of 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
   803
    avoiding to create as many as operation as they are individual modification.
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
    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
   805
    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
   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
    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
   808
    `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
   809
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
    Usage looks like:
6753
2bbc1010494c [doc/book] fix/update a bit the hooks chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6730
diff changeset
   811
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
   812
    .. 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
   813
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
        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
   815
            __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
   816
            __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
   817
            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
   818
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
            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
   820
                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
   821
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
   822
6730
253dd28cc35f [hook] update DataOperationMixIn docstring
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6426
diff changeset
   823
        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
   824
            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
   825
                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
   826
                    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
   827
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
    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
   829
    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
   830
    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
   831
    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
   832
    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
   833
    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
   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
    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
   836
    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
   837
    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
   838
    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
   839
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
    .. 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
   841
        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
   842
        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
   843
        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
   844
        (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
   845
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
        * 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
   847
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
        * 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
   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
    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
   851
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
    @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
   853
    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
   854
        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
   855
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
    @classmethod
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
    def get_instance(cls, session, **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
   858
        # 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
   859
        try:
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
            return session.transaction_data[cls.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
   861
        except KeyError:
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
   862
            op = session.transaction_data[cls.data_key] = cls(session, **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
   863
            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
   864
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
   865
    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
   866
        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
   867
        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
   868
        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
   869
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
    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
   871
        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
   872
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
    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
   874
        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
   875
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
   876
    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
   877
        """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
   878
        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
   879
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
   880
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
   881
        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
   882
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
   883
    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
   884
        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
   885
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
   886
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
   887
        _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
   888
6993
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   889
    def remove_data(self, data):
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   890
        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
   891
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
   892
postcommit method of the operation."""
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   893
        self._container.remove(data)
656561eddd1d [data operation] add new remove_data method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6954
diff changeset
   894
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
   895
    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
   896
        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
   897
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
   898
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
   899
        self._processed = True
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
   900
        op = self.session.transaction_data.pop(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
   901
        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
   902
            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
   903
        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
   904
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
   905
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
   906
@deprecated('[3.10] use opcls.get_instance(session, **opkwargs).add_data(value)')
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   907
def set_operation(session, datakey, value, opcls, containercls=set, **opkwargs):
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
   908
    """Function to ease applying a single operation on a set of data, avoiding
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
   909
    to create as many as operation as they are individual modification. You
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
   910
    should try to use this instead of creating on operation for each `value`,
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
   911
    since handling operations becomes coslty on massive data import.
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
   912
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
   913
    Arguments 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
   914
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
   915
    * the `session` object
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
   916
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
   917
    * `datakey`, a specially forged key that will be used as key in
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
   918
      session.transaction_data
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
   919
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
   920
    * `value` that is the actual payload of an individual 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
   921
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
   922
    * `opcls`, the class of the operation. An instance is created on the first
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
   923
      call for the given key, and then subsequent calls will simply add 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
   924
      payload to the container (hence `opkwargs` is only used on that first
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
   925
      call)
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
   926
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
   927
    * `containercls`, the container class that should be instantiated to hold
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
   928
      payloads.  An instance is created on the first call for the given key, and
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
   929
      then subsequent calls will add the data to the existing container. Default
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
   930
      to a set. Give `list` if you want to keep arrival ordering.
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
   931
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
   932
    * more optional parameters to give to the operation (here the rtype which do not
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
   933
      vary accross 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
   934
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
   935
    The body of the operation must then iterate over the values that have been mapped
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
   936
    in the transaction_data dictionary to the forged key, e.g.:
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
   937
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
   938
    .. sourcecode:: python
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
   939
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
   940
           for value in self._cw.transaction_data.pop(datakey):
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
   941
               ...
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
   942
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
   943
    .. 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
   944
       **poping** the key from `transaction_data` is not an option, else you may
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
   945
       get unexpected data loss in some case of nested hooks.
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
   946
    """
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   947
    try:
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
   948
        # Search for session.transaction_data[`datakey`] (expected to be a set):
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
   949
        # if found, simply append `value`
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   950
        _container_add(session.transaction_data[datakey], value)
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
   951
    except KeyError:
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
   952
        # else, initialize it to containercls([`value`]) and instantiate the given
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
   953
        # `opcls` operation class with additional keyword arguments
5194
395f076512a1 [hooks] fix set_operation options passing (** -> *)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5191
diff changeset
   954
        opcls(session, **opkwargs)
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   955
        session.transaction_data[datakey] = containercls()
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   956
        _container_add(session.transaction_data[datakey], value)
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
   957
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   958
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   959
class LateOperation(Operation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   960
    """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
   961
    operations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   962
    """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   963
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   964
        """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
   965
        SingleLastOperation instance
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   966
        """
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   967
        # faster by inspecting operation in reverse order for heavy transactions
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   968
        i = None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   969
        for i, op in enumerate(reversed(self.session.pending_operations)):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   970
            if isinstance(op, SingleLastOperation):
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   971
                continue
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   972
            return -i or None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   973
        if i is None:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   974
            return None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   975
        return -(i + 1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   976
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   977
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   978
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   979
class SingleLastOperation(Operation):
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   980
    """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
   981
    operations
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   982
    """
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   983
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   984
    def register(self, session):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   985
        """override register to handle cases where this operation has already
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   986
        been added
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   987
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   988
        operations = session.pending_operations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   989
        index = self.equivalent_index(operations)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   990
        if index is not None:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   991
            equivalent = operations.pop(index)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   992
        else:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   993
            equivalent = None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   994
        session.add_operation(self, self.insert_index())
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   995
        return equivalent
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   996
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   997
    def equivalent_index(self, operations):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   998
        """return the index of the equivalent operation if any"""
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   999
        for i, op in enumerate(reversed(operations)):
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
  1000
            if op.__class__ is self.__class__:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
  1001
                return -(i+1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
  1002
        return None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
  1003
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
  1004
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
  1005
        return None
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1006
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1007
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1008
class SendMailOp(SingleLastOperation):
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1009
    def __init__(self, session, msg=None, recipients=None, **kwargs):
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1010
        # may not specify msg yet, as
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1011
        # `cubicweb.sobjects.supervision.SupervisionMailOp`
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1012
        if msg is not None:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1013
            assert recipients
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1014
            self.to_send = [(msg, recipients)]
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1015
        else:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1016
            assert recipients is None
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1017
            self.to_send = []
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1018
        super(SendMailOp, self).__init__(session, **kwargs)
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1019
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1020
    def register(self, session):
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1021
        previous = super(SendMailOp, self).register(session)
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1022
        if previous:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1023
            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
  1024
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
  1025
    def postcommit_event(self):
3418
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
  1026
        self.session.repo.threaded_task(self.sendmails)
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1027
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
  1028
    def sendmails(self):
3418
7b49fa7e942d [api] use _cw, cw_row, cw_col, cw_rset etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3396
diff changeset
  1029
        self.session.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
  1030
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
  1031
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
  1032
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
  1033
    # 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
  1034
    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
  1035
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
  1036
    def precommit_event(self):
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
  1037
        execute = self.session.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
  1038
        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
  1039
            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
  1040
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1041
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
  1042
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
  1043
    """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
  1044
    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
  1045
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1046
    NOTE: querier's rqlst/solutions cache may have been polluted too with
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1047
    queries such as Any X WHERE X eid 32 if 32 has been rollbacked however
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1048
    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
  1049
    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
  1050
    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
  1051
    """
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
  1052
    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
  1053
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1054
    def rollback_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
  1055
        """the observed connections set has been rollbacked,
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
  1056
        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
  1057
        """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1058
        try:
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
  1059
            self.session.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
  1060
        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
  1061
            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
  1062
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
  1063
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
  1064
    """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
  1065
    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
  1066
    """
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
  1067
    data_key = 'pendingeids'
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
  1068
    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
  1069
        """the observed connections set has been rollbacked,
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
  1070
        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
  1071
        """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
  1072
        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
  1073
            eids = self.get_data()
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
  1074
            self.session.repo.clear_caches(eids)
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
  1075
            self.session.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
  1076
        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
  1077
            pass