server/hook.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 16 Sep 2010 18:43:03 +0200
branchstable
changeset 6275 20f30e01ae59
parent 6263 e91ac6e95116
child 6279 42079f752a9c
child 6345 1a7f4bfbf92b
permissions -rw-r--r--
[ReST] settings update: add traceback=True to avoid sys.exit, and set stylesheet to None since we don't care about it and that may makes docutils stupidly fail according to the cwd at import time...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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/>.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
"""Hooks management
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
This module defined the `Hook` class and registry and a set of abstract classes
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
for operations.
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    24
Hooks are called before / after any individual update of entities / relations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    25
in the repository and on special events such as server startup or shutdown.
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    26
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
Operations may be registered by hooks during a transaction, which will  be
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
fired when the pool is commited or rollbacked.
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    30
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    31
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    32
Entity hooks (eg before_add_entity, after_add_entity, before_update_entity,
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    33
after_update_entity, before_delete_entity, after_delete_entity) all have an
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    34
`entity` attribute
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
Relation (eg before_add_relation, after_add_relation, before_delete_relation,
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
after_delete_relation) all have `eidfrom`, `rtype`, `eidto` attributes.
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
5019
72734c210836 [c-c] new server_maintenance hook, called on c-c shell / upgrade
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    39
Server start/maintenance/stop hooks (eg server_startup, server_maintenance,
72734c210836 [c-c] new server_maintenance hook, called on c-c shell / upgrade
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    40
server_shutdown) have a `repo` attribute, but *their `_cw` attribute is None*.
72734c210836 [c-c] new server_maintenance hook, called on c-c shell / upgrade
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    41
The `server_startup` is called on regular startup, while `server_maintenance`
72734c210836 [c-c] new server_maintenance hook, called on c-c shell / upgrade
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    42
is called on cubicweb-ctl upgrade or shell commands. `server_shutdown` is
72734c210836 [c-c] new server_maintenance hook, called on c-c shell / upgrade
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    43
called anyway.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    44
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
Backup/restore hooks (eg server_backup, server_restore) have a `repo` and a
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
    46
`timestamp` attributes, but *their `_cw` attribute is None*.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    47
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    48
Session hooks (eg session_open, session_close) have no special attribute.
5848
b5640328ffad [security] use set_operation for relation permission checking operation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5837
diff changeset
    49
"""
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    50
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
    51
from __future__ import with_statement
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
    52
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
__docformat__ = "restructuredtext en"
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
from warnings import warn
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
from logging import getLogger
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
    57
from itertools import chain
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
from logilab.common.decorators import classproperty
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
    60
from logilab.common.deprecation import deprecated, class_renamed
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
from logilab.common.logging_ext import set_log_methods
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    63
from cubicweb import RegistryNotFound
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
from cubicweb.cwvreg import CWRegistry, VRegistry
4699
8757fca2c308 [hooks] match_rtype and match_rtype_sets don't need to extend match_search_state
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4522
diff changeset
    65
from cubicweb.selectors import (objectify_selector, lltrace, ExpectedValueSelector,
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5848
diff changeset
    66
                                is_instance)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
from cubicweb.appobject import AppObject
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
    68
from cubicweb.server.session import security_enabled
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
ENTITIES_HOOKS = set(('before_add_entity',    'after_add_entity',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
                      'before_update_entity', 'after_update_entity',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
                      'before_delete_entity', 'after_delete_entity'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
RELATIONS_HOOKS = set(('before_add_relation',   'after_add_relation' ,
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
                       'before_delete_relation','after_delete_relation'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
SYSTEM_HOOKS = set(('server_backup', 'server_restore',
5019
72734c210836 [c-c] new server_maintenance hook, called on c-c shell / upgrade
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4845
diff changeset
    76
                    'server_startup', 'server_maintenance', 'server_shutdown',
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
                    'session_open', 'session_close'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
ALL_HOOKS = ENTITIES_HOOKS | RELATIONS_HOOKS | SYSTEM_HOOKS
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    81
class HooksRegistry(CWRegistry):
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    82
    def initialization_completed(self):
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    83
        for appobjects in self.values():
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    84
            for cls in appobjects:
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    85
                if not cls.enabled:
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    86
                    warn('[3.6] %s: enabled is deprecated' % cls)
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
    87
                    self.unregister(cls)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    89
    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
    90
        obj.check_events()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    91
        super(HooksRegistry, self).register(obj, **kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    92
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
    93
    def call_hooks(self, event, session=None, **kwargs):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    94
        kwargs['event'] = event
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
    95
        if session is None:
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
    96
            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
    97
                               key=lambda x: x.order):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
    98
                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
    99
        else:
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
   100
            # by default, hooks are executed with security turned off
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
   101
            with security_enabled(session, read=False):
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
   102
                hooks = 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
   103
                               key=lambda x: x.order)
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
   104
                with security_enabled(session, write=False):
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
   105
                    for hook in hooks:
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
   106
                        hook()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   108
class HooksManager(object):
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   109
    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
   110
        self.vreg = vreg
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   111
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   112
    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
   113
        try:
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   114
            self.vreg['%s_hooks' % event].call_hooks(event, session, **kwargs)
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   115
        except RegistryNotFound:
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   116
            pass # no hooks for this event
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   117
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   118
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   119
for event in ALL_HOOKS:
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   120
    VRegistry.REGISTRY_FACTORY['%s_hooks' % event] = HooksRegistry
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
4838
d4187a08ccdf [hook] entity_oldnew_value may cause bug on attributes explicitly set to None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4699
diff changeset
   122
_MARKER = object()
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   123
def entity_oldnewvalue(entity, attr):
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   124
    """returns the couple (old attr value, new attr value)
5744
6b2a987370e8 [hooks] entity_oldnewvalue should never return _MARKER: if the attribute isn't in the entity dict (hence unmodified), return the old value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5538
diff changeset
   125
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   126
    NOTE: will only work in a before_update_entity hook
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   127
    """
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   128
    # get new value and remove from local dict to force a db query to
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   129
    # fetch old value
4838
d4187a08ccdf [hook] entity_oldnew_value may cause bug on attributes explicitly set to None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4699
diff changeset
   130
    newvalue = entity.pop(attr, _MARKER)
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   131
    oldvalue = getattr(entity, attr)
4838
d4187a08ccdf [hook] entity_oldnew_value may cause bug on attributes explicitly set to None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4699
diff changeset
   132
    if newvalue is not _MARKER:
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   133
        entity[attr] = newvalue
5744
6b2a987370e8 [hooks] entity_oldnewvalue should never return _MARKER: if the attribute isn't in the entity dict (hence unmodified), return the old value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5538
diff changeset
   134
    else:
6b2a987370e8 [hooks] entity_oldnewvalue should never return _MARKER: if the attribute isn't in the entity dict (hence unmodified), return the old value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5538
diff changeset
   135
        newvalue = oldvalue
4011
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   136
    return oldvalue, newvalue
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   137
394f853bb653 [migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4008
diff changeset
   138
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
# some hook specific selectors #################################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
@objectify_selector
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
@lltrace
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
def enabled_category(cls, req, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
    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
   145
        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
   146
    return req.is_hook_activated(cls)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
@objectify_selector
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
@lltrace
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
   150
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
   151
    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
   152
        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
   153
    return 0
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   154
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   155
class rechain(object):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   156
    def __init__(self, *iterators):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   157
        self.iterators = iterators
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   158
    def __iter__(self):
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   159
        return iter(chain(*self.iterators))
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   160
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   161
4699
8757fca2c308 [hooks] match_rtype and match_rtype_sets don't need to extend match_search_state
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4522
diff changeset
   162
class match_rtype(ExpectedValueSelector):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
    """accept if parameters specified as initializer arguments are specified
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
    in named arguments given to the selector
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   166
    :param *expected: parameters (eg `basestring`) which are expected to be
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
                      found in named arguments (kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
    """
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
   169
    def __init__(self, *expected, **more):
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   170
        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
   171
        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
   172
        self.toetypes = more.pop('toetypes', None)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
    @lltrace
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   175
    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
   176
        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
   177
            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
   178
        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
   179
               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
   180
            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
   181
        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
   182
               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
   183
            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
   184
        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
   185
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
4699
8757fca2c308 [hooks] match_rtype and match_rtype_sets don't need to extend match_search_state
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 4522
diff changeset
   187
class match_rtype_sets(ExpectedValueSelector):
4086
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   188
    """accept if parameters specified as initializer arguments are specified
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   189
    in named arguments given to the selector
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   190
    """
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   191
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   192
    def __init__(self, *expected):
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   193
        self.expected = expected
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   194
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   195
    @lltrace
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   196
    def __call__(self, cls, req, *args, **kwargs):
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   197
        for rel_set in self.expected:
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   198
            if kwargs.get('rtype') in rel_set:
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   199
                return 1
9b96126e0b14 add hook selector
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4075
diff changeset
   200
        return 0
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   201
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   202
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   203
# base class for hook ##########################################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   205
class Hook(AppObject):
5093
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   206
    __select__ = enabled_category()
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   207
    # set this in derivated classes
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   208
    events = None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   209
    category = None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   210
    order = 0
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   211
    # XXX deprecated
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   212
    enabled = True
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   213
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   214
    @classmethod
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   215
    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
   216
        try:
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   217
            for event in cls.events:
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   218
                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
   219
                    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
   220
                        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
   221
        except AttributeError:
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   222
            raise
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   223
        except TypeError:
a2ce436e00ad [hooks] better message on bad .event class attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5093
diff changeset
   224
            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
   225
                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
   226
8d073d2e089d [optimization] improve massive write performance by optimizing hooks selection
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5072
diff changeset
   227
    @classproperty
5287
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   228
    def __registries__(cls):
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   229
        cls.check_events()
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   230
        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
   231
6346f1fd0a50 [hook] backport bad .events fix from default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5220
diff changeset
   232
    @classproperty
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3195
diff changeset
   233
    def __regid__(cls):
3383
c6aff16e5aed nicer warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   234
        warn('[3.6] %s.%s: please specify an id for your hook'
c6aff16e5aed nicer warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   235
             % (cls.__module__, cls.__name__), DeprecationWarning)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   236
        return str(id(cls))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   237
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   238
    @classmethod
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4341
diff changeset
   239
    def __registered__(cls, reg):
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4341
diff changeset
   240
        super(Hook, cls).__registered__(reg)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   241
        if getattr(cls, 'accepts', None):
3383
c6aff16e5aed nicer warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   242
            warn('[3.6] %s.%s: accepts is deprecated, define proper __select__'
c6aff16e5aed nicer warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   243
                 % (cls.__module__, cls.__name__), DeprecationWarning)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   244
            rtypes = []
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   245
            for ertype in cls.accepts:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   246
                if ertype.islower():
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   247
                    rtypes.append(ertype)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   248
                else:
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5848
diff changeset
   249
                    cls.__select__ = cls.__select__ & is_instance(ertype)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   250
            if rtypes:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   251
                cls.__select__ = cls.__select__ & match_rtype(*rtypes)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   252
        return cls
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   253
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   254
    known_args = set(('entity', 'rtype', 'eidfrom', 'eidto', 'repo', 'timestamp'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   255
    def __init__(self, req, event, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   256
        for arg in self.known_args:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   257
            if arg in kwargs:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   258
                setattr(self, arg, kwargs.pop(arg))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   259
        super(Hook, self).__init__(req, **kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   260
        self.event = event
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   261
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   262
    def __call__(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   263
        if hasattr(self, 'call'):
3383
c6aff16e5aed nicer warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   264
            cls = self.__class__
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5848
diff changeset
   265
            warn('[3.6] %s.%s: call is deprecated, implement __call__'
3383
c6aff16e5aed nicer warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3376
diff changeset
   266
                 % (cls.__module__, cls.__name__), DeprecationWarning)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   267
            if self.event.endswith('_relation'):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
   268
                self.call(self._cw, self.eidfrom, self.rtype, self.eidto)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   269
            elif 'delete' in self.event:
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
   270
                self.call(self._cw, self.entity.eid)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   271
            elif self.event.startswith('server_'):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   272
                self.call(self.repo)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   273
            elif self.event.startswith('session_'):
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
   274
                self.call(self._cw)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   275
            else:
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
   276
                self.call(self._cw, self.entity)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   277
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   278
set_log_methods(Hook, getLogger('cubicweb.hook'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   279
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   280
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
   281
# 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
   282
# 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
   283
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
   284
class PropagateRelationHook(Hook):
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   285
    """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
   286
    `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
   287
    relations).
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   288
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   289
    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
   290
    `main_rtype` relation is added to the target entity of the relation.
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
   291
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
   292
    You usually want to use the :class:`match_rtype_sets` selector on concret
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
   293
    classes.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   294
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   295
    events = ('after_add_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   296
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   297
    # to set in concrete class
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   298
    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
   299
    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
   300
    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
   301
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   302
    def __call__(self):
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   303
        assert self.main_rtype
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   304
        for eid in (self.eidfrom, self.eidto):
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   305
            etype = self._cw.describe(eid)[0]
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   306
            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
   307
                return
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   308
        if self.rtype in self.subject_relations:
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   309
            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
   310
        else:
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   311
            assert self.rtype in self.object_relations
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   312
            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
   313
        self._cw.execute(
5509
205e708dd5db [3.8 execute] remove deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
   314
            '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
   315
            % (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
   316
            {'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
   317
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   318
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
   319
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
   320
    """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
   321
    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
   322
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
   323
    `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
   324
    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
   325
    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
   326
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
   327
    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
   328
    `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
   329
    entities linked through some particular relations.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   330
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   331
    events = ('after_add_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   332
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
   333
    # 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
   334
    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
   335
    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
   336
    # 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
   337
    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
   338
    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
   339
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   340
    def __call__(self):
4104
7e478d7caf20 [mq]: small_api_changes_for_3.6
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4086
diff changeset
   341
        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
   342
        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
   343
        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
   344
            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
   345
                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
   346
                        '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
   347
                        {'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
   348
        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
   349
            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
   350
                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
   351
                        '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
   352
                        {'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
   353
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   354
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
   355
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
   356
    """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
   357
    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
   358
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
   359
    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
   360
    documentation for how to use this class.
4522
271f201e3735 propagation hooks cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4490
diff changeset
   361
    """
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   362
    events = ('after_delete_relation',)
3660
7b41a6ba7400 fix/prepare propagation hooks usage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   363
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3423
diff changeset
   364
    def __call__(self):
4104
7e478d7caf20 [mq]: small_api_changes_for_3.6
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 4086
diff changeset
   365
        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
   366
        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
   367
        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
   368
            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
   369
                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
   370
                        '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
   371
                        {'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
   372
        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
   373
            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
   374
                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
   375
                        '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
   376
                        {'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
   377
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   378
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
   379
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
   380
    '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
   381
    '[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
   382
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
   383
    '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
   384
    '[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
   385
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
   386
    '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
   387
    '[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
   388
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
   389
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   390
# abstract classes for operation ###############################################
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   391
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   392
class Operation(object):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   393
    """an operation is triggered on connections pool events related to
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   394
    commit / rollback transations. Possible events are:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   395
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   396
    precommit:
5837
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   397
      the pool is preparing to commit. You shouldn't do anything which
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   398
      has to be reverted if the commit fails at this point, but you can freely
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   399
      do any heavy computation or raise an exception if the commit can't go.
5837
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   400
      You can add some new operations during this phase but their precommit
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   401
      event won't be triggered
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   402
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   403
    commit:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   404
      the pool is preparing to commit. You should avoid to do to expensive
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   405
      stuff or something that may cause an exception in this event
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   406
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   407
    revertcommit:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   408
      if an operation failed while commited, this event is triggered for
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   409
      all operations which had their commit event already to let them
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   410
      revert things (including the operation which made fail the commit)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   411
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   412
    rollback:
5220
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   413
      the transaction has been either rollbacked either:
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   414
       * intentionaly
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   415
       * a precommit event failed, all operations are rollbacked
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   416
       * a commit event failed, all operations which are not been triggered for
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   417
         commit are rollbacked
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   418
5837
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   419
    postcommit:
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   420
      The transaction is over. All the ORM entities are
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   421
      invalid. If you need to work on the database, you need to stard
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   422
      a new transaction, for instance using a new internal_session,
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   423
      which you will need to commit (and close!).
67c722b36f7c updated docstrings on Operation class
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 5744
diff changeset
   424
5220
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   425
    order of operations may be important, and is controlled according to
42f854b6083d [doc/book] complete chapter on hooks & ops
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5194
diff changeset
   426
    the insert_index's method output
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   427
    """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   428
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   429
    def __init__(self, session, **kwargs):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   430
        self.session = session
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   431
        self.__dict__.update(kwargs)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   432
        self.register(session)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   433
        # execution information
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   434
        self.processed = None # 'precommit', 'commit'
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   435
        self.failed = False
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   436
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   437
    def register(self, session):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   438
        session.add_operation(self, self.insert_index())
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   439
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   440
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   441
        """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
   442
        LateOperation instance
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   443
        """
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   444
        # faster by inspecting operation in reverse order for heavy transactions
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   445
        i = None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   446
        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
   447
            if isinstance(op, (LateOperation, SingleLastOperation)):
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   448
                continue
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   449
            return -i or None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   450
        if i is None:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   451
            return None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   452
        return -(i + 1)
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 handle_event(self, event):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   455
        """delegate event handling to the opertaion"""
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   456
        getattr(self, event)()
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   457
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   458
    def precommit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   459
        """the observed connections pool is preparing a commit"""
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   460
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   461
    def revertprecommit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   462
        """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
   463
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   464
        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
   465
        been all considered if it's this operation which failed
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   466
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   467
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   468
    def commit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   469
        """the observed connections pool is commiting"""
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   470
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   471
    def revertcommit_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   472
        """an error went when commiting this operation or a later one
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   473
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   474
        should revert commit's changes but take care, they may have not
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   475
        been all considered if it's this operation which failed
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   476
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   477
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   478
    def rollback_event(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   479
        """the observed connections pool has been rollbacked
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   480
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   481
        do nothing by default, the operation will just be removed from the pool
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   482
        operation list
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   483
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   484
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   485
    def postcommit_event(self):
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   486
        """the observed connections pool has committed"""
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3720
diff changeset
   487
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   488
    @property
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   489
    @deprecated('[3.6] use self.session.user')
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   490
    def user(self):
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   491
        return self.session.user
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   492
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   493
    @property
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   494
    @deprecated('[3.6] use self.session.repo')
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   495
    def repo(self):
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   496
        return self.session.repo
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   497
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   498
    @property
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   499
    @deprecated('[3.6] use self.session.vreg.schema')
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   500
    def schema(self):
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   501
        return self.session.repo.schema
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   502
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   503
    @property
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   504
    @deprecated('[3.6] use self.session.vreg.config')
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   505
    def config(self):
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   506
        return self.session.repo.config
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2847
diff changeset
   507
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   508
set_log_methods(Operation, getLogger('cubicweb.session'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   509
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   510
def _container_add(container, value):
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   511
    {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
   512
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   513
def set_operation(session, datakey, value, opcls, containercls=set, **opkwargs):
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
   514
    """Search for session.transaction_data[`datakey`] (expected to be a set):
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   515
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   516
    * if found, simply append `value`
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   517
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   518
    * else, initialize it to containercls([`value`]) and instantiate the given
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   519
      `opcls` operation class with additional keyword arguments. `containercls`
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   520
      is a set by default. Give `list` if you want to keep arrival ordering.
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
   521
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   522
    You should use this instead of creating on operation for each `value`,
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   523
    since handling operations becomes coslty on massive data import.
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   524
    """
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   525
    try:
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   526
        _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
   527
    except KeyError:
5194
395f076512a1 [hooks] fix set_operation options passing (** -> *)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5191
diff changeset
   528
        opcls(session, **opkwargs)
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   529
        session.transaction_data[datakey] = containercls()
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5509
diff changeset
   530
        _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
   531
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5019
diff changeset
   532
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   533
class LateOperation(Operation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   534
    """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
   535
    operations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   536
    """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   537
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   538
        """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
   539
        SingleLastOperation instance
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   540
        """
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   541
        # faster by inspecting operation in reverse order for heavy transactions
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   542
        i = None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   543
        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
   544
            if isinstance(op, SingleLastOperation):
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   545
                continue
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   546
            return -i or None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   547
        if i is None:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   548
            return None
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   549
        return -(i + 1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   550
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   551
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   552
class SingleOperation(Operation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   553
    """special operation which should be called once"""
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   554
    def register(self, session):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   555
        """override register to handle cases where this operation has already
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   556
        been added
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   557
        """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   558
        operations = session.pending_operations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   559
        index = self.equivalent_index(operations)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   560
        if index is not None:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   561
            equivalent = operations.pop(index)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   562
        else:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   563
            equivalent = None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   564
        session.add_operation(self, self.insert_index())
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   565
        return equivalent
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   566
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   567
    def equivalent_index(self, operations):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   568
        """return the index of the equivalent operation if any"""
3720
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   569
        for i, op in enumerate(reversed(operations)):
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   570
            if op.__class__ is self.__class__:
5376aaadd16b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3660
diff changeset
   571
                return -(i+1)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   572
        return None
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   573
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   574
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   575
class SingleLastOperation(SingleOperation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   576
    """special operation which should be called once and after all other
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   577
    operations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   578
    """
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   579
    def insert_index(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   580
        return None
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   581
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   582
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   583
class SendMailOp(SingleLastOperation):
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   584
    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
   585
        # may not specify msg yet, as
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   586
        # `cubicweb.sobjects.supervision.SupervisionMailOp`
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   587
        if msg is not None:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   588
            assert recipients
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   589
            self.to_send = [(msg, recipients)]
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   590
        else:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   591
            assert recipients is None
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   592
            self.to_send = []
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   593
        super(SendMailOp, self).__init__(session, **kwargs)
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   594
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   595
    def register(self, session):
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   596
        previous = super(SendMailOp, self).register(session)
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   597
        if previous:
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   598
            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
   599
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   600
    def commit_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
   601
        self.session.repo.threaded_task(self.sendmails)
2840
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   602
06daf13195d4 [hooks] deprecates hookhelper module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   603
    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
   604
        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
   605
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   606
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   607
class RQLPrecommitOperation(Operation):
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2855
diff changeset
   608
    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
   609
        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
   610
        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
   611
            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
   612
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   613
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   614
class CleanupNewEidsCacheOp(SingleLastOperation):
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   615
    """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
   616
    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
   617
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   618
    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
   619
    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
   620
    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
   621
    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
   622
    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
   623
    """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   624
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   625
    def rollback_event(self):
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   626
        """the observed connections pool has been rollbacked,
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   627
        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
   628
        """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   629
        try:
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   630
            self.session.repo.clear_caches(
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   631
                self.session.transaction_data['neweids'])
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   632
        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
   633
            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
   634
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   635
class CleanupDeletedEidsCacheOp(SingleLastOperation):
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   636
    """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
   637
    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
   638
    """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   639
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   640
    def commit_event(self):
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   641
        """the observed connections pool has been rollbacked,
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   642
        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
   643
        """
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   644
        try:
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   645
            self.session.repo.clear_caches(
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   646
                self.session.transaction_data['pendingeids'])
adc2122eed03 [repo] more efficient eid cache operations handling based on set_operation; refactor
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   647
        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
   648
            pass