author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
Fri, 21 May 2010 08:45:25 +0200 | |
branch | stable |
changeset 5560 | b9a8e7109370 |
parent 5538 | 752bc67064f2 |
child 5877 | 0c7b7b76a84f |
permissions | -rw-r--r-- |
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 |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
20 |
|
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 |
4075
e710f4052bd6
use implements instead of entity_implements
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4027
diff
changeset
|
30 |
from cubicweb.selectors import implements |
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 commit_event(self): |
d45cde54d464
backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4307
diff
changeset
|
68 |
pass |
d45cde54d464
backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4307
diff
changeset
|
69 |
def postcommit_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 |
def rollback_event(self): |
d45cde54d464
backport stable branch and some vreg cleanups:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4307
diff
changeset
|
72 |
_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
|
73 |
|
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
74 |
|
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
|
75 |
class _CheckRequiredRelationOperation(hook.LateOperation): |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
76 |
"""checking relation cardinality has to be done after commit in |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
77 |
case the relation is being replaced |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
78 |
""" |
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
|
79 |
role = key = base_rql = None |
2835
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 |
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
|
82 |
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
|
83 |
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
|
84 |
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
|
85 |
# 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
|
86 |
# 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
|
87 |
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
|
88 |
# 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
|
89 |
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
|
90 |
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
|
91 |
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
|
92 |
continue |
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5060
diff
changeset
|
93 |
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
|
94 |
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
|
95 |
_ = 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
|
96 |
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
|
97 |
'%(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
|
98 |
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
|
99 |
raise ValidationError(eid, {role_name(rtype, self.role): msg}) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
100 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
101 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
102 |
class _CheckSRelationOp(_CheckRequiredRelationOperation): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
103 |
"""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
|
104 |
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
|
105 |
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
|
106 |
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
|
107 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
108 |
class _CheckORelationOp(_CheckRequiredRelationOperation): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
109 |
"""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
|
110 |
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
|
111 |
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
|
112 |
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
|
113 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
114 |
|
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
|
115 |
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
|
116 |
__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
|
117 |
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
|
118 |
|
107ba1c45227
rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2835
diff
changeset
|
119 |
|
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
|
120 |
class CheckCardinalityHook(IntegrityHook): |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
121 |
"""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
|
122 |
__regid__ = 'checkcard' |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
123 |
events = ('after_add_entity', 'before_delete_relation') |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
124 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
125 |
def __call__(self): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
126 |
getattr(self, self.event)() |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
127 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
128 |
def after_add_entity(self): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
129 |
eid = self.entity.eid |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
130 |
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
|
131 |
for rschema, targetschemas, role in eschema.relation_definitions(): |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
132 |
# skip automatically handled relations |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
133 |
if rschema.type in DONT_CHECK_RTYPES_ON_ADD: |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
134 |
continue |
3890
d7a270f50f54
backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3731
diff
changeset
|
135 |
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
|
136 |
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
|
137 |
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
|
138 |
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
|
139 |
_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
|
140 |
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
|
141 |
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
|
142 |
_CheckORelationOp, list) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
143 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
144 |
def before_delete_relation(self): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
145 |
rtype = self.rtype |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
146 |
if rtype in DONT_CHECK_RTYPES_ON_DEL: |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
147 |
return |
2847
c2ee28f4d4b1
use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2841
diff
changeset
|
148 |
session = self._cw |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
149 |
eidfrom, eidto = self.eidfrom, self.eidto |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
150 |
pendingrdefs = session.transaction_data.get('pendingrdefs', ()) |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
151 |
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
|
152 |
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
|
153 |
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
|
154 |
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
|
155 |
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
|
156 |
_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
|
157 |
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
|
158 |
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
|
159 |
_CheckORelationOp, list) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
160 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
161 |
|
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
|
162 |
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
|
163 |
""" 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
|
164 |
|
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
165 |
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
|
166 |
session = self.session |
5449
a7e1b316af03
[hooks/...] fix previous commit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5448
diff
changeset
|
167 |
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
|
168 |
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
|
169 |
# 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
|
170 |
# 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
|
171 |
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
|
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 |
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
|
174 |
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
|
175 |
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
|
176 |
# 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
|
177 |
# * 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
|
178 |
# * 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
|
179 |
# 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
|
180 |
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
|
181 |
_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
|
182 |
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
|
183 |
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
|
184 |
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
|
185 |
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
|
186 |
constraint) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
187 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
188 |
def commit_event(self): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
189 |
pass |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
190 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
191 |
|
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
|
192 |
class CheckConstraintHook(IntegrityHook): |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
193 |
"""check the relation satisfy its constraints |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
194 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
195 |
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
|
196 |
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
|
197 |
""" |
3376
f5c69485381f
[appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3086
diff
changeset
|
198 |
__regid__ = 'checkconstraint' |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
199 |
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
|
200 |
|
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
201 |
def __call__(self): |
3998
94cc7cad3d2d
backport stable into default
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3894
diff
changeset
|
202 |
# 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
|
203 |
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
|
204 |
'constraints') |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
205 |
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
|
206 |
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
|
207 |
(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
|
208 |
_CheckConstraintsOp, list) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
209 |
|
4027 | 210 |
|
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
|
211 |
class CheckAttributeConstraintHook(IntegrityHook): |
3630
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
212 |
"""check the attribute relation satisfy its constraints |
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
213 |
|
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
214 |
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
|
215 |
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
|
216 |
""" |
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
217 |
__regid__ = 'checkattrconstraint' |
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
218 |
events = ('after_add_entity', 'after_update_entity') |
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
219 |
|
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
220 |
def __call__(self): |
4190
742e3eb16f81
fix bad merge
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4181
diff
changeset
|
221 |
eschema = self.entity.e_schema |
4181
c79135c217df
backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4075
diff
changeset
|
222 |
for attr in self.entity.edited_attributes: |
c79135c217df
backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4075
diff
changeset
|
223 |
if eschema.subjrels[attr].final: |
c79135c217df
backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4075
diff
changeset
|
224 |
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
|
225 |
if isinstance(c, (RQLUniqueConstraint, RQLConstraint))] |
3630
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
226 |
if constraints: |
5449
a7e1b316af03
[hooks/...] fix previous commit
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5448
diff
changeset
|
227 |
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
|
228 |
(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
|
229 |
_CheckConstraintsOp, list) |
3630
275feb5370c9
oops, feature killed by merge...
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3590
diff
changeset
|
230 |
|
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
|
231 |
|
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
|
232 |
class CheckUniqueHook(IntegrityHook): |
3376
f5c69485381f
[appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3086
diff
changeset
|
233 |
__regid__ = 'checkunique' |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
234 |
events = ('before_add_entity', 'before_update_entity') |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
235 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
236 |
def __call__(self): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
237 |
entity = self.entity |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
238 |
eschema = entity.e_schema |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
239 |
for attr in entity.edited_attributes: |
4024
6a14cff373c3
more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4023
diff
changeset
|
240 |
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
|
241 |
val = entity[attr] |
94ed8f0f0d14
only get value when necessary to check uniqueness
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2968
diff
changeset
|
242 |
if val is None: |
94ed8f0f0d14
only get value when necessary to check uniqueness
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2968
diff
changeset
|
243 |
continue |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
244 |
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
|
245 |
rset = self._cw.execute(rql, {'val': val}) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
246 |
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
|
247 |
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
|
248 |
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
|
249 |
raise ValidationError(entity.eid, {qname: msg % val}) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
250 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
251 |
|
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
|
252 |
class DontRemoveOwnersGroupHook(IntegrityHook): |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
253 |
"""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
|
254 |
""" |
3376
f5c69485381f
[appobjects] use __regid__ instead of __id__, more explicit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3086
diff
changeset
|
255 |
__regid__ = 'checkownersgroup' |
4075
e710f4052bd6
use implements instead of entity_implements
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4027
diff
changeset
|
256 |
__select__ = IntegrityHook.__select__ & implements('CWGroup') |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
257 |
events = ('before_delete_entity', 'before_update_entity') |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
258 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
259 |
def __call__(self): |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
260 |
if self.event == 'before_delete_entity' and self.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
|
261 |
msg = self._cw._('can\'t be deleted') |
5238d9a8dfee
[form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5007
diff
changeset
|
262 |
raise ValidationError(self.entity.eid, {None: msg}) |
5238d9a8dfee
[form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5007
diff
changeset
|
263 |
elif self.event == 'before_update_entity' and \ |
5238d9a8dfee
[form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5007
diff
changeset
|
264 |
'name' in self.entity.edited_attributes: |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
265 |
newname = self.entity.pop('name') |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
266 |
oldname = self.entity.name |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
267 |
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
|
268 |
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
|
269 |
msg = self._cw._('can\'t be changed') |
5238d9a8dfee
[form] put qualified name on validation error, should fix #784299
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5007
diff
changeset
|
270 |
raise ValidationError(self.entity.eid, {qname: msg}) |
2835
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
271 |
self.entity['name'] = newname |
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
272 |
|
04034421b072
[hooks] major refactoring:
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
273 |
|
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
|
274 |
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
|
275 |
"""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
|
276 |
__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
|
277 |
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
|
278 |
|
107ba1c45227
rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2835
diff
changeset
|
279 |
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
|
280 |
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
|
281 |
metaattrs = entity.e_schema.meta_attributes() |
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 |
for metaattr, (metadata, attr) in metaattrs.iteritems(): |
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 metadata == 'format' and attr in entity.edited_attributes: |
107ba1c45227
rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2835
diff
changeset
|
284 |
try: |
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 |
value = entity[attr] |
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 |
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
|
287 |
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
|
288 |
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
|
289 |
if getattr(entity, str(metaattr)) == 'text/html': |
2847
c2ee28f4d4b1
use ._cw instead of .cw_req
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2841
diff
changeset
|
290 |
entity[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
|
291 |
|
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 |
|
107ba1c45227
rewrite hooks in sobjects as new Hook style into hooks sub-package
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2835
diff
changeset
|
293 |
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
|
294 |
"""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
|
295 |
__regid__ = 'stripuserlogin' |
4075
e710f4052bd6
use implements instead of entity_implements
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4027
diff
changeset
|
296 |
__select__ = IntegrityHook.__select__ & implements('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
|
297 |
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
|
298 |
|
2900 | 299 |
def __call__(self): |
300 |
user = self.entity |
|
301 |
if 'login' in user.edited_attributes and user.login: |
|
2968
0e3460341023
somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2901
diff
changeset
|
302 |
user.login = user.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
|
303 |
|
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
|
304 |
|
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 |
# '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
|
306 |
# 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
|
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 |
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
|
309 |
"""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
|
310 |
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
|
311 |
""" |
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
|
312 |
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
|
313 |
|
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
|
314 |
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
|
315 |
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
|
316 |
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
|
317 |
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
|
318 |
# 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
|
319 |
# 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
|
320 |
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
|
321 |
# 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
|
322 |
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
|
323 |
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
|
324 |
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
|
325 |
|
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 |
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
|
327 |
"""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
|
328 |
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
|
329 |
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
|
330 |
|
ee3b856e1406
[repo] optimize massive insertion/deletion by using the new set_operation function
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5030
diff
changeset
|
331 |
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
|
332 |
"""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
|
333 |
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
|
334 |
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
|
335 |
|
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 |
|
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 |
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
|
338 |
"""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
|
339 |
""" |
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 |
__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
|
341 |
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
|
342 |
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
|
343 |
|
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 |
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
|
345 |
# 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
|
346 |
# 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
|
347 |
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
|
348 |
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
|
349 |
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
|
350 |
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
|
351 |
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
|
352 |
'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
|
353 |
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
|
354 |
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
|
355 |
_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
|
356 |
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
|
357 |
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
|
358 |
_DelayedDeleteSEntityOp) |