hooks/integrity.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 25 Aug 2010 10:29:18 +0200
changeset 6142 8bc6eac1fac1
parent 5877 0c7b7b76a84f
child 6376 f8662240ed4d
permissions -rw-r--r--
[session] cleanup hook / operation / entity edition api Operation api ~~~~~~~~~~~~~ * commit_event killed, recently introduced postcommit_event is enough and has a better name * kill SingleOperation class, it's a) currently never used b) superseeded by set_operation if needed. Entity edition api ~~~~~~~~~~~~~~~~~~ edited_attributes turned into a special object holding edition specific attributes: - attributes to be edited (simply mirrored in cw_attr_cache, actual values are there) - former _cw_skip_security set (cw_edited) and querier_pending_relations It has also been renamed to `cw_edited` on the way (it may also contains inlined relations) The entity dict interface has been deprecated. One should explicitly use either cw_attr_cache or cw_edited according to the need. Also, there is now a control that we don't try to hi-jack edited attributes once this has no more effect (eg modification have already been saved) At last, _cw_set_defaults/cw_check internal methods have been moved to this special object Hook api ~~~~~~~~ hook.entity_oldnewvalue function now moved to a method of cw_edited object.
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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: 5060
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
"""Core hooks: check for data integrity according to the instance'schema
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
validity
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
    20
"""
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
__docformat__ = "restructuredtext en"
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    24
from threading import Lock
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    25
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
    26
from yams.schema import role_name
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
    27
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
from cubicweb import ValidationError
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3894
diff changeset
    29
from cubicweb.schema import RQLConstraint, RQLUniqueConstraint
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: 5538
diff changeset
    30
from cubicweb.selectors import is_instance
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4003
diff changeset
    31
from cubicweb.uilib import soup2xhtml
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    32
from cubicweb.server import hook
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    33
from cubicweb.server.hook import set_operation
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    34
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
# special relations that don't have to be checked for integrity, usually
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
# because they are handled internally by hooks (so we trust ourselves)
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
DONT_CHECK_RTYPES_ON_ADD = set(('owned_by', 'created_by',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
                                'is', 'is_instance_of',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
                                'wf_info_for', 'from_state', 'to_state'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
DONT_CHECK_RTYPES_ON_DEL = set(('is', 'is_instance_of',
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
                                'wf_info_for', 'from_state', 'to_state'))
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    43
_UNIQUE_CONSTRAINTS_LOCK = Lock()
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    44
_UNIQUE_CONSTRAINTS_HOLDER = None
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    45
4517
0f3c10fc42b2 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4498
diff changeset
    46
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    47
def _acquire_unique_cstr_lock(session):
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    48
    """acquire the _UNIQUE_CONSTRAINTS_LOCK for the session.
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    49
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    50
    This lock used to avoid potential integrity pb when checking
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    51
    RQLUniqueConstraint in two different transactions, as explained in
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    52
    http://intranet.logilab.fr/jpl/ticket/36564
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    53
    """
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: 4530
diff changeset
    54
    if 'uniquecstrholder' in session.transaction_data:
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    55
        return
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    56
    _UNIQUE_CONSTRAINTS_LOCK.acquire()
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: 4530
diff changeset
    57
    session.transaction_data['uniquecstrholder'] = True
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    58
    # register operation responsible to release the lock on commit/rollback
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: 4530
diff changeset
    59
    _ReleaseUniqueConstraintsOperation(session)
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    60
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    61
def _release_unique_cstr_lock(session):
4517
0f3c10fc42b2 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4498
diff changeset
    62
    if 'uniquecstrholder' in session.transaction_data:
0f3c10fc42b2 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4498
diff changeset
    63
        del session.transaction_data['uniquecstrholder']
4490
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    64
        _UNIQUE_CONSTRAINTS_LOCK.release()
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    65
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    66
class _ReleaseUniqueConstraintsOperation(hook.Operation):
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    67
    def postcommit_event(self):
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    68
        _release_unique_cstr_lock(self.session)
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    69
    def rollback_event(self):
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    70
        _release_unique_cstr_lock(self.session)
d45cde54d464 backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
    71
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
    73
class _CheckRequiredRelationOperation(hook.LateOperation):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
    """checking relation cardinality has to be done after commit in
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
    case the relation is being replaced
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
    """
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    77
    role = key = base_rql = None
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
    def precommit_event(self):
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    80
        session =self.session
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    81
        pendingeids = session.transaction_data.get('pendingeids', ())
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    82
        pendingrtypes = session.transaction_data.get('pendingrtypes', ())
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    83
        # poping key is not optional: if further operation trigger new deletion
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    84
        # of relation, we'll need a new operation
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    85
        for eid, rtype in session.transaction_data.pop(self.key):
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    86
            # recheck pending eids / relation types
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    87
            if eid in pendingeids:
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    88
                continue
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    89
            if rtype in pendingrtypes:
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    90
                continue
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
    91
            if not session.execute(self.base_rql % rtype, {'x': eid}):
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    92
                etype = session.describe(eid)[0]
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    93
                _ = session._
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    94
                msg = _('at least one relation %(rtype)s is required on '
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    95
                        '%(etype)s (%(eid)s)')
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    96
                msg %= {'rtype': _(rtype), 'etype': _(etype), 'eid': eid}
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
    97
                raise ValidationError(eid, {role_name(rtype, self.role): msg})
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
class _CheckSRelationOp(_CheckRequiredRelationOperation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
    """check required subject relation"""
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   102
    role = 'subject'
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   103
    key = '_cwisrel'
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   104
    base_rql = 'Any O WHERE S eid %%(x)s, S %s O'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
class _CheckORelationOp(_CheckRequiredRelationOperation):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
    """check required object relation"""
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   108
    role = 'object'
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   109
    key = '_cwiorel'
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   110
    base_rql = 'Any S WHERE O eid %%(x)s, S %s O'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   111
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   112
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   113
class IntegrityHook(hook.Hook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   114
    __abstract__ = True
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   115
    category = 'integrity'
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   116
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   117
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: 4530
diff changeset
   118
class CheckCardinalityHook(IntegrityHook):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
    """check cardinalities are satisfied"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3086
diff changeset
   120
    __regid__ = 'checkcard'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
    events = ('after_add_entity', 'before_delete_relation')
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
    def __call__(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
        getattr(self, self.event)()
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
    def after_add_entity(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
        eid = self.entity.eid
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
        eschema = self.entity.e_schema
3890
d7a270f50f54 backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3731
diff changeset
   129
        for rschema, targetschemas, role in eschema.relation_definitions():
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
            # skip automatically handled relations
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
            if rschema.type in DONT_CHECK_RTYPES_ON_ADD:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
                continue
3890
d7a270f50f54 backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3731
diff changeset
   133
            rdef = rschema.role_rdef(eschema, targetschemas[0], role)
d7a270f50f54 backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3731
diff changeset
   134
            if rdef.role_cardinality(role) in '1+':
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   135
                if role == 'subject':
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   136
                    set_operation(self._cw, '_cwisrel', (eid, rschema.type),
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5450
diff changeset
   137
                                  _CheckSRelationOp, list)
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   138
                else:
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   139
                    set_operation(self._cw, '_cwiorel', (eid, rschema.type),
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5450
diff changeset
   140
                                  _CheckORelationOp, list)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
    def before_delete_relation(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
        rtype = self.rtype
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
        if rtype in DONT_CHECK_RTYPES_ON_DEL:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
            return
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   146
        session = self._cw
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
        eidfrom, eidto = self.eidfrom, self.eidto
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
        pendingrdefs = session.transaction_data.get('pendingrdefs', ())
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
        if (session.describe(eidfrom)[0], rtype, session.describe(eidto)[0]) in pendingrdefs:
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
            return
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   151
        card = session.schema_rproperty(rtype, eidfrom, eidto, 'cardinality')
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   152
        if card[0] in '1+' and not session.deleted_in_transaction(eidfrom):
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   153
            set_operation(self._cw, '_cwisrel', (eidfrom, rtype),
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5450
diff changeset
   154
                          _CheckSRelationOp, list)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   155
        if card[1] in '1+' and not session.deleted_in_transaction(eidto):
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   156
            set_operation(self._cw, '_cwiorel', (eidto, rtype),
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5450
diff changeset
   157
                          _CheckORelationOp, list)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   160
class _CheckConstraintsOp(hook.LateOperation):
5450
269dcd14b92c [hooks/integrity & tests/entities] fix test to check for sibling error (set_operations yields a different order for constraints)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5449
diff changeset
   161
    """ check a new relation satisfy its constraints """
269dcd14b92c [hooks/integrity & tests/entities] fix test to check for sibling error (set_operations yields a different order for constraints)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5449
diff changeset
   162
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
    def precommit_event(self):
5448
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   164
        session = self.session
5449
a7e1b316af03 [hooks/...] fix previous commit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5448
diff changeset
   165
        for values in session.transaction_data.pop('check_constraints_op'):
5450
269dcd14b92c [hooks/integrity & tests/entities] fix test to check for sibling error (set_operations yields a different order for constraints)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5449
diff changeset
   166
            eidfrom, rtype, eidto, constraints = values
5448
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   167
            # first check related entities have not been deleted in the same
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   168
            # transaction
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   169
            if session.deleted_in_transaction(eidfrom):
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   170
                return
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   171
            if session.deleted_in_transaction(eidto):
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   172
                return
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   173
            for constraint in constraints:
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   174
                # XXX
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   175
                # * lock RQLConstraint as well?
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   176
                # * use a constraint id to use per constraint lock and avoid
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   177
                #   unnecessary commit serialization ?
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   178
                if isinstance(constraint, RQLUniqueConstraint):
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   179
                    _acquire_unique_cstr_lock(session)
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   180
                try:
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   181
                    constraint.repo_check(session, eidfrom, rtype, eidto)
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   182
                except NotImplementedError:
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   183
                    self.critical('can\'t check constraint %s, not supported',
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   184
                                  constraint)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
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: 4530
diff changeset
   187
class CheckConstraintHook(IntegrityHook):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   188
    """check the relation satisfy its constraints
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   189
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
    this is delayed to a precommit time operation since other relation which
3630
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   191
    will make constraint satisfied (or unsatisfied) may be added later.
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   192
    """
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3086
diff changeset
   193
    __regid__ = 'checkconstraint'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   194
    events = ('after_add_relation',)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   195
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   196
    def __call__(self):
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3894
diff changeset
   197
        # XXX get only RQL[Unique]Constraints?
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   198
        constraints = self._cw.schema_rproperty(self.rtype, self.eidfrom, self.eidto,
3630
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   199
                                                'constraints')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   200
        if constraints:
5448
9bf648d678cd [hooks/operations] use set_operations for three ops (huge gains for massive imports)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   201
            hook.set_operation(self._cw, 'check_constraints_op',
5450
269dcd14b92c [hooks/integrity & tests/entities] fix test to check for sibling error (set_operations yields a different order for constraints)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5449
diff changeset
   202
                               (self.eidfrom, self.rtype, self.eidto, tuple(constraints)),
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5450
diff changeset
   203
                               _CheckConstraintsOp, list)
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
4027
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4024
diff changeset
   205
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: 4530
diff changeset
   206
class CheckAttributeConstraintHook(IntegrityHook):
3630
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   207
    """check the attribute relation satisfy its constraints
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   208
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   209
    this is delayed to a precommit time operation since other relation which
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   210
    will make constraint satisfied (or unsatisfied) may be added later.
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   211
    """
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   212
    __regid__ = 'checkattrconstraint'
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   213
    events = ('after_add_entity', 'after_update_entity')
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   214
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   215
    def __call__(self):
4190
742e3eb16f81 fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4181
diff changeset
   216
        eschema = self.entity.e_schema
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   217
        for attr in self.entity.cw_edited:
4181
c79135c217df backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4075
diff changeset
   218
            if eschema.subjrels[attr].final:
c79135c217df backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4075
diff changeset
   219
                constraints = [c for c in eschema.rdef(attr).constraints
3998
94cc7cad3d2d backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3894
diff changeset
   220
                               if isinstance(c, (RQLUniqueConstraint, RQLConstraint))]
3630
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   221
                if constraints:
5449
a7e1b316af03 [hooks/...] fix previous commit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5448
diff changeset
   222
                    hook.set_operation(self._cw, 'check_constraints_op',
5450
269dcd14b92c [hooks/integrity & tests/entities] fix test to check for sibling error (set_operations yields a different order for constraints)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5449
diff changeset
   223
                                       (self.entity.eid, attr, None, tuple(constraints)),
5538
752bc67064f2 [integrity] keep ordering for schema integrity checks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5450
diff changeset
   224
                                       _CheckConstraintsOp, list)
3630
275feb5370c9 oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3590
diff changeset
   225
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   226
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: 4530
diff changeset
   227
class CheckUniqueHook(IntegrityHook):
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3086
diff changeset
   228
    __regid__ = 'checkunique'
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   229
    events = ('before_add_entity', 'before_update_entity')
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   230
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   231
    def __call__(self):
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   232
        entity = self.entity
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   233
        eschema = entity.e_schema
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   234
        for attr, val in entity.cw_edited.iteritems():
4024
6a14cff373c3 more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   235
            if eschema.subjrels[attr].final and eschema.has_unique_values(attr):
3086
94ed8f0f0d14 only get value when necessary to check uniqueness
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   236
                if val is None:
94ed8f0f0d14 only get value when necessary to check uniqueness
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   237
                    continue
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   238
                rql = '%s X WHERE X %s %%(val)s' % (entity.e_schema, attr)
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: 4530
diff changeset
   239
                rset = self._cw.execute(rql, {'val': val})
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   240
                if rset and rset[0][0] != entity.eid:
2847
c2ee28f4d4b1 use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2841
diff changeset
   241
                    msg = self._cw._('the value "%s" is already used, use another one')
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   242
                    qname = role_name(attr, 'subject')
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   243
                    raise ValidationError(entity.eid, {qname: msg % val})
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   244
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   245
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   246
class DontRemoveOwnersGroupHook(IntegrityHook):
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   247
    """delete the composed of a composite relation when this relation is deleted
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   248
    """
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3086
diff changeset
   249
    __regid__ = 'checkownersgroup'
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: 5538
diff changeset
   250
    __select__ = IntegrityHook.__select__ & is_instance('CWGroup')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   251
    events = ('before_delete_entity', 'before_update_entity')
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   252
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   253
    def __call__(self):
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   254
        entity = self.entity
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   255
        if self.event == 'before_delete_entity' and entity.name == 'owners':
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   256
            msg = self._cw._('can\'t be deleted')
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   257
            raise ValidationError(entity.eid, {None: msg})
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   258
        elif self.event == 'before_update_entity' \
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   259
                 and 'name' in entity.cw_edited:
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   260
            oldname, newname = entity.cw_edited.oldnewvalue('name')
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   261
            if oldname == 'owners' and newname != oldname:
5030
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   262
                qname = role_name('name', 'subject')
5238d9a8dfee [form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5007
diff changeset
   263
                msg = self._cw._('can\'t be changed')
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   264
                raise ValidationError(entity.eid, {qname: msg})
2835
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   265
04034421b072 [hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   266
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: 4530
diff changeset
   267
class TidyHtmlFields(IntegrityHook):
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   268
    """tidy HTML in rich text strings"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3086
diff changeset
   269
    __regid__ = 'htmltidy'
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   270
    events = ('before_add_entity', 'before_update_entity')
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   271
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   272
    def __call__(self):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   273
        entity = self.entity
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   274
        metaattrs = entity.e_schema.meta_attributes()
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   275
        edited = entity.cw_edited
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   276
        for metaattr, (metadata, attr) in metaattrs.iteritems():
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   277
            if metadata == 'format' and attr in edited:
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   278
                try:
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   279
                    value = edited[attr]
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   280
                except KeyError:
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   281
                    continue # no text to tidy
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   282
                if isinstance(value, unicode): # filter out None and Binary
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   283
                    if getattr(entity, str(metaattr)) == 'text/html':
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   284
                        edited[attr] = soup2xhtml(value, self._cw.encoding)
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   285
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   286
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   287
class StripCWUserLoginHook(IntegrityHook):
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   288
    """ensure user logins are stripped"""
3376
f5c69485381f [appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3086
diff changeset
   289
    __regid__ = 'stripuserlogin'
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: 5538
diff changeset
   290
    __select__ = IntegrityHook.__select__ & is_instance('CWUser')
2841
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   291
    events = ('before_add_entity', 'before_update_entity',)
107ba1c45227 rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2835
diff changeset
   292
2900
9d65e0350aa1 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2896
diff changeset
   293
    def __call__(self):
6142
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   294
        login = self.entity.cw_edited.get('login')
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   295
        if login:
8bc6eac1fac1 [session] cleanup hook / operation / entity edition api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5877
diff changeset
   296
            self.entity.cw_edited['login'] = login.strip()
5007
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   297
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   298
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   299
# 'active' integrity hooks: you usually don't want to deactivate them, they are
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   300
# not really integrity check, they maintain consistency on changes
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   301
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   302
class _DelayedDeleteOp(hook.Operation):
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   303
    """delete the object of composite relation except if the relation has
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   304
    actually been redirected to another composite
5007
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   305
    """
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   306
    key = base_rql = None
5007
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   307
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   308
    def precommit_event(self):
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   309
        session = self.session
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   310
        pendingeids = session.transaction_data.get('pendingeids', ())
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   311
        neweids = session.transaction_data.get('neweids', ())
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   312
        # poping key is not optional: if further operation trigger new deletion
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   313
        # of composite relation, we'll need a new operation
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   314
        for eid, rtype in session.transaction_data.pop(self.key):
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   315
            # don't do anything if the entity is being created or deleted
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   316
            if not (eid in pendingeids or eid in neweids):
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   317
                etype = session.describe(eid)[0]
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5060
diff changeset
   318
                session.execute(self.base_rql % (etype, rtype), {'x': eid})
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   319
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   320
class _DelayedDeleteSEntityOp(_DelayedDeleteOp):
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   321
    """delete orphan subject entity of a composite relation"""
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   322
    key = '_cwiscomp'
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   323
    base_rql = 'DELETE %s X WHERE X eid %%(x)s, NOT X %s Y'
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   324
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   325
class _DelayedDeleteOEntityOp(_DelayedDeleteOp):
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   326
    """check required object relation"""
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   327
    key = '_cwiocomp'
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   328
    base_rql = 'DELETE %s X WHERE X eid %%(x)s, NOT Y %s X'
5007
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   329
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   330
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   331
class DeleteCompositeOrphanHook(hook.Hook):
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   332
    """delete the composed of a composite relation when this relation is deleted
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   333
    """
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   334
    __regid__ = 'deletecomposite'
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   335
    events = ('before_delete_relation',)
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   336
    category = 'activeintegrity'
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   337
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   338
    def __call__(self):
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   339
        # if the relation is being delete, don't delete composite's components
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   340
        # automatically
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   341
        pendingrdefs = self._cw.transaction_data.get('pendingrdefs', ())
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   342
        if (self._cw.describe(self.eidfrom)[0], self.rtype,
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   343
            self._cw.describe(self.eidto)[0]) in pendingrdefs:
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   344
            return
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   345
        composite = self._cw.schema_rproperty(self.rtype, self.eidfrom, self.eidto,
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   346
                                              'composite')
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   347
        if composite == 'subject':
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   348
            set_operation(self._cw, '_cwiocomp', (self.eidto, self.rtype),
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   349
                          _DelayedDeleteOEntityOp)
5007
bc0a67a95b69 don't put hooks deleting orphan composites into the 'integrity' category, we usually want it when integrity is deactivated
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   350
        elif composite == 'object':
5060
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   351
            set_operation(self._cw, '_cwiscomp', (self.eidfrom, self.rtype),
ee3b856e1406 [repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5030
diff changeset
   352
                          _DelayedDeleteSEntityOp)