server/hooks.py
author Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
Wed, 07 Oct 2009 19:59:46 +0200
branchstable
changeset 3608 5a46e68c3d3c
parent 3568 87a7ca9d8ce6
child 3617 9036a8fbbd57
permissions -rw-r--r--
[editcontroller] backout (sort of) removal of entity.complete() in validate_form entity is passed to js callbacks when there's one. In that case, we want as much information as we can. The removal was there to avoid complete to fail when all constraints (required relations / attributes) aren't satisfied. This fix only does the complete() after the commit is done, any ValidationError should have been raised at this point.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""Core hooks: check schema validity, unsure we are not deleting necessary
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
entities...
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     4
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1802
diff changeset
     5
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1802
diff changeset
     7
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 479
diff changeset
    11
from datetime import datetime
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
from cubicweb import UnknownProperty, ValidationError, BadConnectionId
3554
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
    14
from cubicweb.schema import RQLVocabularyConstraint
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
from cubicweb.server.pool import Operation, LateOperation, PreCommitOperation
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
    16
from cubicweb.server.hookhelper import (check_internal_entity, 
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
    17
                                        get_user_sessions, rproperty)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
from cubicweb.server.repository import FTIndexEntityOp
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
2605
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    20
# special relations that don't have to be checked for integrity, usually
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    21
# because they are handled internally by hooks (so we trust ourselves)
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    22
DONT_CHECK_RTYPES_ON_ADD = set(('owned_by', 'created_by',
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    23
                                'is', 'is_instance_of',
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    24
                                'wf_info_for', 'from_state', 'to_state'))
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    25
DONT_CHECK_RTYPES_ON_DEL = set(('is', 'is_instance_of',
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    26
                                'wf_info_for', 'from_state', 'to_state'))
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    27
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    28
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
def relation_deleted(session, eidfrom, rtype, eidto):
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    30
    session.transaction_data.setdefault('pendingrelations', []).append(
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    31
        (eidfrom, rtype, eidto))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    32
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    33
def eschema_type_eid(session, etype):
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    34
    """get eid of the CWEType entity for the given yams type"""
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    35
    eschema = session.repo.schema.eschema(etype)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    36
    # eschema.eid is None if schema has been readen from the filesystem, not
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    37
    # from the database (eg during tests)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    38
    if eschema.eid is None:
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    39
        eschema.eid = session.unsafe_execute(
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
    40
            'Any X WHERE X is CWEType, X name %(name)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
    41
            {'name': str(etype)})[0][0]
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    42
    return eschema.eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    44
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    45
# base meta-data handling ######################################################
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
def setctime_before_add_entity(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
    """before create a new entity -> set creation and modification date
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    49
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    this is a conveniency hook, you shouldn't have to disable it
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
    """
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    52
    timestamp = datetime.now()
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    53
    entity.setdefault('creation_date', timestamp)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    54
    entity.setdefault('modification_date', timestamp)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    55
    if not session.get_shared_data('do-not-insert-cwuri'):
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    56
        entity.setdefault('cwuri', u'%seid/%s' % (session.base_url(), entity.eid))
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    57
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
def setmtime_before_update_entity(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
    """update an entity -> set modification date"""
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    61
    entity.setdefault('modification_date', datetime.now())
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    62
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    63
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
class SetCreatorOp(PreCommitOperation):
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    65
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
    def precommit_event(self):
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    67
        session = self.session
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    68
        if self.entity.eid in session.transaction_data.get('pendingeids', ()):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
            # entity have been created and deleted in the same transaction
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
            return
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    71
        if not self.entity.created_by:
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    72
            session.add_relation(self.entity.eid, 'created_by', session.user.eid)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    73
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
def setowner_after_add_entity(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
    """create a new entity -> set owner and creator metadata"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
    asession = session.actual_session()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
    if not asession.is_internal_session:
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    79
        session.add_relation(entity.eid, 'owned_by', asession.user.eid)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    80
        SetCreatorOp(asession, entity=entity)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    81
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
def setis_after_add_entity(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    """create a new entity -> set is relation"""
1250
5c20a7f13c84 new recreate argument to extid2eid when an external source want to recreate entities previously imported with a predictable ext id
sylvain.thenault@logilab.fr
parents: 479
diff changeset
    85
    if hasattr(entity, '_cw_recreating'):
5c20a7f13c84 new recreate argument to extid2eid when an external source want to recreate entities previously imported with a predictable ext id
sylvain.thenault@logilab.fr
parents: 479
diff changeset
    86
        return
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    87
    try:
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    88
        session.add_relation(entity.eid, 'is',
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    89
                             eschema_type_eid(session, entity.id))
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    90
    except IndexError:
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    91
        # during schema serialization, skip
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    92
        return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    # XXX < 2.50 bw compat
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    if not session.get_shared_data('do-not-insert-is_instance_of'):
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    95
        for etype in entity.e_schema.ancestors() + [entity.e_schema]:
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    96
            session.add_relation(entity.eid, 'is_instance_of',
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    97
                                 eschema_type_eid(session, etype))
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
    98
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
def setowner_after_add_user(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
    """when a user has been created, add owned_by relation on itself"""
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   102
    session.add_relation(entity.eid, 'owned_by', entity.eid)
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   103
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
def fti_update_after_add_relation(session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
    """sync fulltext index when relevant relation is added. Reindexing the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
    contained entity is enough since it will implicitly reindex the container
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
    entity.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
    ftcontainer = session.repo.schema.rschema(rtype).fulltext_container
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
    if ftcontainer == 'subject':
2195
58bef4f707ce update calls to a deprecated method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
   112
        FTIndexEntityOp(session, entity=session.entity_from_eid(eidto))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
    elif ftcontainer == 'object':
2195
58bef4f707ce update calls to a deprecated method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
   114
        FTIndexEntityOp(session, entity=session.entity_from_eid(eidfrom))
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   115
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   116
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
def fti_update_after_delete_relation(session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
    """sync fulltext index when relevant relation is deleted. Reindexing both
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
    entities is necessary.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
    if session.repo.schema.rschema(rtype).fulltext_container:
2195
58bef4f707ce update calls to a deprecated method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
   122
        FTIndexEntityOp(session, entity=session.entity_from_eid(eidto))
58bef4f707ce update calls to a deprecated method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2101
diff changeset
   123
        FTIndexEntityOp(session, entity=session.entity_from_eid(eidfrom))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   124
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   125
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
class SyncOwnersOp(PreCommitOperation):
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   127
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
    def precommit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
        self.session.unsafe_execute('SET X owned_by U WHERE C owned_by U, C eid %(c)s,'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                                    'NOT EXISTS(X owned_by U, X eid %(x)s)',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
                                    {'c': self.compositeeid, 'x': self.composedeid},
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
                                    ('c', 'x'))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   133
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   134
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
def sync_owner_after_add_composite_relation(session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
    """when adding composite relation, the composed should have the same owners
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
    has the composite
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
    if rtype == 'wf_info_for':
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   140
        # skip this special composite relation # XXX (syt) why?
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    composite = rproperty(session, rtype, eidfrom, eidto, 'composite')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
    if composite == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        SyncOwnersOp(session, compositeeid=eidfrom, composedeid=eidto)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
    elif composite == 'object':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        SyncOwnersOp(session, compositeeid=eidto, composedeid=eidfrom)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   147
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   148
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
def _register_metadata_hooks(hm):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
    """register meta-data related hooks on the hooks manager"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
    hm.register_hook(setctime_before_add_entity, 'before_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
    hm.register_hook(setmtime_before_update_entity, 'before_update_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
    hm.register_hook(setowner_after_add_entity, 'after_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
    hm.register_hook(sync_owner_after_add_composite_relation, 'after_add_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
    hm.register_hook(fti_update_after_add_relation, 'after_add_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
    hm.register_hook(fti_update_after_delete_relation, 'after_delete_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
    if 'is' in hm.schema:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
        hm.register_hook(setis_after_add_entity, 'after_add_entity', '')
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   159
    if 'CWUser' in hm.schema:
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   160
        hm.register_hook(setowner_after_add_user, 'after_add_entity', 'CWUser')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   161
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   162
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
# core hooks ##################################################################
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   164
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
class DelayedDeleteOp(PreCommitOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
    """delete the object of composite relation except if the relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
    has actually been redirected to another composite
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
    """
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   169
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
    def precommit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        session = self.session
2607
5d889b4928bb [F hooks] skip new eids as well as pending ones in DelayedDelete operation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2606
diff changeset
   172
        # don't do anything if the entity is being created or deleted
5d889b4928bb [F hooks] skip new eids as well as pending ones in DelayedDelete operation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2606
diff changeset
   173
        if not (self.eid in session.transaction_data.get('pendingeids', ()) or
5d889b4928bb [F hooks] skip new eids as well as pending ones in DelayedDelete operation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2606
diff changeset
   174
                self.eid in session.transaction_data.get('neweids', ())):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
            etype = session.describe(self.eid)[0]
3568
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   176
            if self.role == 'subject':
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   177
                rql = 'DELETE %s X WHERE X eid %%(x)s, NOT X %s Y'
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   178
            else: # self.role == 'object':
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   179
                rql = 'DELETE %s X WHERE X eid %%(x)s, NOT Y %s X'
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   180
            session.unsafe_execute(rql % (etype, self.rtype), {'x': self.eid}, 'x')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   181
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   182
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
def handle_composite_before_del_relation(session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
    """delete the object of composite relation"""
3568
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   185
    # if the relation is being delete, don't delete composite's components
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   186
    # automatically
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   187
    pendingrdefs = session.transaction_data.get('pendingrdefs', ())
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   188
    if (session.describe(eidfrom)[0], rtype, session.describe(eidto)[0]) in pendingrdefs:
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   189
        return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
    composite = rproperty(session, rtype, eidfrom, eidto, 'composite')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
    if composite == 'subject':
3568
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   192
        DelayedDeleteOp(session, eid=eidto, rtype=rtype, role='object')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
    elif composite == 'object':
3568
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   194
        DelayedDeleteOp(session, eid=eidfrom, rtype=rtype, role='subject')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   196
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
def before_del_group(session, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
    """check that we don't remove the owners group"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
    check_internal_entity(session, eid, ('owners',))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
# schema validation hooks #####################################################
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   203
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
class CheckConstraintsOperation(LateOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
    """check a new relation satisfy its constraints
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    def precommit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        eidfrom, rtype, eidto = self.rdef
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        # first check related entities have not been deleted in the same
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        # transaction
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   211
        pending = self.session.transaction_data.get('pendingeids', ())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        if eidfrom in pending:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        if eidto in pending:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        for constraint in self.constraints:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
                constraint.repo_check(self.session, eidfrom, rtype, eidto)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
            except NotImplementedError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
                self.critical('can\'t check constraint %s, not supported',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
                              constraint)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   222
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
        pass
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   225
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   226
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
def cstrcheck_after_add_relation(session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
    """check the relation satisfy its constraints
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
    this is delayed to a precommit time operation since other relation which
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
    will make constraint satisfied may be added later.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
    constraints = rproperty(session, rtype, eidfrom, eidto, 'constraints')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
    if constraints:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
        CheckConstraintsOperation(session, constraints=constraints,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
                                  rdef=(eidfrom, rtype, eidto))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
def uniquecstrcheck_before_modification(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
    eschema = entity.e_schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
    for attr, val in entity.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        if val is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        if eschema.subject_relation(attr).is_final() and \
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
               eschema.has_unique_values(attr):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
            rql = '%s X WHERE X %s %%(val)s' % (entity.e_schema, attr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
            rset = session.unsafe_execute(rql, {'val': val})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
            if rset and rset[0][0] != entity.eid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
                msg = session._('the value "%s" is already used, use another one')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
                raise ValidationError(entity.eid, {attr: msg % val})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
3554
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   251
def cstrcheck_after_update_attributes(session, entity):
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   252
    schema = session.vreg.schema
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   253
    for attr in entity.edited_attributes:
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   254
        if schema.rschema(attr).is_final():
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   255
            constraints = [c for c in entity.e_schema.constraints(attr)
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   256
                           if isinstance(c, RQLVocabularyConstraint)]
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   257
            if constraints:
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   258
                CheckConstraintsOperation(session, rdef=(entity.eid, attr, None),
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   259
                                          constraints=constraints)
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   260
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
class CheckRequiredRelationOperation(LateOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
    """checking relation cardinality has to be done after commit in
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
    case the relation is being replaced
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
    eid, rtype = None, None
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   267
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
    def precommit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
        # recheck pending eids
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   270
        if self.eid in self.session.transaction_data.get('pendingeids', ()):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        if self.session.unsafe_execute(*self._rql()).rowcount < 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
            etype = self.session.describe(self.eid)[0]
2241
fcf08ac5f8c0 translate schema types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2195
diff changeset
   274
            _ = self.session._
fcf08ac5f8c0 translate schema types
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2195
diff changeset
   275
            msg = _('at least one relation %(rtype)s is required on %(etype)s (%(eid)s)')
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   276
            msg %= {'rtype': _(self.rtype), 'etype': _(etype), 'eid': self.eid}
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   277
            raise ValidationError(self.eid, {self.rtype: msg})
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   278
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        pass
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   281
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
    def _rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
        raise NotImplementedError()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   284
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   285
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
class CheckSRelationOp(CheckRequiredRelationOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
    """check required subject relation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
    def _rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
        return 'Any O WHERE S eid %%(x)s, S %s O' % self.rtype, {'x': self.eid}, 'x'
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   290
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   291
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
class CheckORelationOp(CheckRequiredRelationOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
    """check required object relation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
    def _rql(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        return 'Any S WHERE O eid %%(x)s, S %s O' % self.rtype, {'x': self.eid}, 'x'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   296
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   297
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
def checkrel_if_necessary(session, opcls, rtype, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
    """check an equivalent operation has not already been added"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
    for op in session.pending_operations:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
        if isinstance(op, opcls) and op.rtype == rtype and op.eid == eid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
            break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
        opcls(session, rtype=rtype, eid=eid)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   305
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   306
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
def cardinalitycheck_after_add_entity(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
    """check cardinalities are satisfied"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
    eid = entity.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
    for rschema, targetschemas, x in entity.e_schema.relation_definitions():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
        # skip automatically handled relations
2605
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
   312
        if rschema.type in DONT_CHECK_RTYPES_ON_ADD:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
        if x == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
            subjtype = entity.e_schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
            objtype = targetschemas[0].type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
            cardindex = 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
            opcls = CheckSRelationOp
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
            subjtype = targetschemas[0].type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
            objtype = entity.e_schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
            cardindex = 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
            opcls = CheckORelationOp
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
        card = rschema.rproperty(subjtype, objtype, 'cardinality')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   325
        if card[cardindex] in '1+':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
            checkrel_if_necessary(session, opcls, rschema.type, eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
def cardinalitycheck_before_del_relation(session, eidfrom, rtype, eidto):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
    """check cardinalities are satisfied"""
2605
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
   330
    if rtype in DONT_CHECK_RTYPES_ON_DEL:
c4f6a53884ec [R hooks] use DONT_CHECK_RTYPES_ON_[ADD|DEL] constant, don't check wf related internal relations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
   331
        return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
    card = rproperty(session, rtype, eidfrom, eidto, 'cardinality')
2745
0dafa29ace1f [schema migration] test reproducing pb when deleting a relation definition with mandatory card and without removing the associated rtype + fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2695
diff changeset
   333
    pendingrdefs = session.transaction_data.get('pendingrdefs', ())
0dafa29ace1f [schema migration] test reproducing pb when deleting a relation definition with mandatory card and without removing the associated rtype + fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2695
diff changeset
   334
    if (session.describe(eidfrom)[0], rtype, session.describe(eidto)[0]) in pendingrdefs:
0dafa29ace1f [schema migration] test reproducing pb when deleting a relation definition with mandatory card and without removing the associated rtype + fix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2695
diff changeset
   335
        return
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   336
    pendingeids = session.transaction_data.get('pendingeids', ())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   337
    if card[0] in '1+' and not eidfrom in pendingeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
        checkrel_if_necessary(session, CheckSRelationOp, rtype, eidfrom)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
    if card[1] in '1+' and not eidto in pendingeids:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
        checkrel_if_necessary(session, CheckORelationOp, rtype, eidto)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
def _register_core_hooks(hm):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
    hm.register_hook(handle_composite_before_del_relation, 'before_delete_relation', '')
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   345
    hm.register_hook(before_del_group, 'before_delete_entity', 'CWGroup')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   346
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
    #hm.register_hook(cstrcheck_before_update_entity, 'before_update_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
    hm.register_hook(cardinalitycheck_after_add_entity, 'after_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
    hm.register_hook(cardinalitycheck_before_del_relation, 'before_delete_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   350
    hm.register_hook(cstrcheck_after_add_relation, 'after_add_relation', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   351
    hm.register_hook(uniquecstrcheck_before_modification, 'before_add_entity', '')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
    hm.register_hook(uniquecstrcheck_before_modification, 'before_update_entity', '')
3554
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   353
    hm.register_hook(cstrcheck_after_update_attributes, 'after_add_entity', '')
26e586f3c15c [schema] make RQL* constraints usable w/ attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   354
    hm.register_hook(cstrcheck_after_update_attributes, 'after_update_entity', '')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
# user/groups synchronisation #################################################
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   357
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
class GroupOperation(Operation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    """base class for group operation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
    geid = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
    def __init__(self, session, *args, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        """override to get the group name before actual groups manipulation:
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   363
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   364
        we may temporarily loose right access during a commit event, so
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
        no query should be emitted while comitting
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
        rql = 'Any N WHERE G eid %(x)s, G name N'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
        result = session.execute(rql, {'x': kwargs['geid']}, 'x', build_descr=False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        Operation.__init__(self, session, *args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
        self.group = result[0][0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   372
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
class DeleteGroupOp(GroupOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
    """synchronize user when a in_group relation has been deleted"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
        """the observed connections pool has been commited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
        groups = self.cnxuser.groups
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
            groups.remove(self.group)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
            self.error('user %s not in group %s',  self.cnxuser, self.group)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
            return
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   383
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   384
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
def after_del_in_group(session, fromeid, rtype, toeid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
    """modify user permission, need to update users"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
    for session_ in get_user_sessions(session.repo, fromeid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
        DeleteGroupOp(session, cnxuser=session_.user, geid=toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   390
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
class AddGroupOp(GroupOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
    """synchronize user when a in_group relation has been added"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
        """the observed connections pool has been commited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
        groups = self.cnxuser.groups
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
        if self.group in groups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
            self.warning('user %s already in group %s', self.cnxuser,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
                         self.group)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
        groups.add(self.group)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   402
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
def after_add_in_group(session, fromeid, rtype, toeid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
    """modify user permission, need to update users"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
    for session_ in get_user_sessions(session.repo, fromeid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
        AddGroupOp(session, cnxuser=session_.user, geid=toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
class DelUserOp(Operation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
    """synchronize user when a in_group relation has been added"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   411
    def __init__(self, session, cnxid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   412
        self.cnxid = cnxid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
        Operation.__init__(self, session)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   414
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   415
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   416
        """the observed connections pool has been commited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
            self.repo.close(self.cnxid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
        except BadConnectionId:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
            pass # already closed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   421
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   422
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   423
def after_del_user(session, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
    """modify user permission, need to update users"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
    for session_ in get_user_sessions(session.repo, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
        DelUserOp(session, session_.id)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   427
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   428
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
def _register_usergroup_hooks(hm):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
    """register user/group related hooks on the hooks manager"""
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   431
    hm.register_hook(after_del_user, 'after_delete_entity', 'CWUser')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
    hm.register_hook(after_add_in_group, 'after_add_relation', 'in_group')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
    hm.register_hook(after_del_in_group, 'after_delete_relation', 'in_group')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
# workflow handling ###########################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   438
from cubicweb.entities.wfobjs import WorkflowTransition, WorkflowException
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   439
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   440
def _change_state(session, x, oldstate, newstate):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   441
    nocheck = session.transaction_data.setdefault('skip-security', set())
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   442
    nocheck.add((x, 'in_state', oldstate))
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   443
    nocheck.add((x, 'in_state', newstate))
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   444
    # delete previous state first in case we're using a super session
3039
7d5a4d27d052 [multi-sources] in ms config, don't try to delete previous state in some condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   445
    fromsource = session.describe(x)[1]
7d5a4d27d052 [multi-sources] in ms config, don't try to delete previous state in some condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   446
    # don't try to remove previous state if in_state isn't stored in the system
7d5a4d27d052 [multi-sources] in ms config, don't try to delete previous state in some condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   447
    # source
7d5a4d27d052 [multi-sources] in ms config, don't try to delete previous state in some condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   448
    if fromsource == 'system' or \
7d5a4d27d052 [multi-sources] in ms config, don't try to delete previous state in some condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   449
       not session.repo.sources_by_uri[fromsource].support_relation('in_state'):
7d5a4d27d052 [multi-sources] in ms config, don't try to delete previous state in some condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   450
        session.delete_relation(x, 'in_state', oldstate)
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   451
    session.add_relation(x, 'in_state', newstate)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   452
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   453
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   454
class FireAutotransitionOp(PreCommitOperation):
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   455
    """try to fire auto transition after state changes"""
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   456
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   457
    def precommit_event(self):
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   458
        session = self.session
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   459
        entity = self.entity
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   460
        autotrs = list(entity.possible_transitions('auto'))
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   461
        if autotrs:
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   462
            assert len(autotrs) == 1
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   463
            entity.fire_transition(autotrs[0])
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   464
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   465
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   466
def before_add_trinfo(session, entity):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   467
    """check the transition is allowed, add missing information. Expect that:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   468
    * wf_info_for inlined relation is set
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   469
    * by_transition or to_state (managers only) inlined relation is set
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
    """
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   471
    # first retreive entity to which the state change apply
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   472
    try:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   473
        foreid = entity['wf_info_for']
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   474
    except KeyError:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   475
        msg = session._('mandatory relation')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   476
        raise ValidationError(entity.eid, {'wf_info_for': msg})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   477
    forentity = session.entity_from_eid(foreid)
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   478
    # then check it has a workflow set, unless we're in the process of changing
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   479
    # entity's workflow
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   480
    if session.transaction_data.get((forentity.eid, 'customwf')):
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   481
        wfeid = session.transaction_data[(forentity.eid, 'customwf')]
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   482
        wf = session.entity_from_eid(wfeid)
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   483
    else:
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   484
        wf = forentity.current_workflow
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   485
    if wf is None:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   486
        msg = session._('related entity has no workflow set')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   487
        raise ValidationError(entity.eid, {None: msg})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   488
    # then check it has a state set
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   489
    fromstate = forentity.current_state
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   490
    if fromstate is None:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   491
        msg = session._('related entity has no state')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   492
        raise ValidationError(entity.eid, {None: msg})
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   493
    # True if we are coming back from subworkflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   494
    swtr = session.transaction_data.pop((forentity.eid, 'subwfentrytr'), None)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   495
    cowpowers = session.is_super_session or 'managers' in session.user.groups
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   496
    # no investigate the requested state change...
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   497
    try:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   498
        treid = entity['by_transition']
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   499
    except KeyError:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   500
        # no transition set, check user is a manager and destination state is
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   501
        # specified (and valid)
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   502
        if not cowpowers:
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   503
            msg = session._('mandatory relation')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   504
            raise ValidationError(entity.eid, {'by_transition': msg})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   505
        deststateeid = entity.get('to_state')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   506
        if not deststateeid:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   507
            msg = session._('mandatory relation')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   508
            raise ValidationError(entity.eid, {'by_transition': msg})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   509
        deststate = wf.state_by_eid(deststateeid)
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   510
        if not cowpowers and deststate is None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   511
            msg = entity.req._("state doesn't belong to entity's workflow")
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   512
            raise ValidationError(entity.eid, {'to_state': msg})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   513
    else:
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   514
        # check transition is valid and allowed, unless we're coming back from
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   515
        # subworkflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   516
        tr = session.entity_from_eid(treid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   517
        if swtr is None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   518
            if tr is None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   519
                msg = session._("transition doesn't belong to entity's workflow")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   520
                raise ValidationError(entity.eid, {'by_transition': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   521
            if not tr.has_input_state(fromstate):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   522
                msg = session._("transition isn't allowed")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   523
                raise ValidationError(entity.eid, {'by_transition': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   524
            if not tr.may_be_fired(foreid):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   525
                msg = session._("transition may not be fired")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   526
                raise ValidationError(entity.eid, {'by_transition': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   527
        if entity.get('to_state'):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   528
            deststateeid = entity['to_state']
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   529
            if not cowpowers and deststateeid != tr.destination().eid:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   530
                msg = session._("transition isn't allowed")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   531
                raise ValidationError(entity.eid, {'by_transition': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   532
            if swtr is None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   533
                deststate = session.entity_from_eid(deststateeid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   534
                if not cowpowers and deststate is None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   535
                    msg = entity.req._("state doesn't belong to entity's workflow")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   536
                    raise ValidationError(entity.eid, {'to_state': msg})
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
        else:
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   538
            deststateeid = tr.destination().eid
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   539
    # everything is ok, add missing information on the trinfo entity
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   540
    entity['from_state'] = fromstate.eid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   541
    entity['to_state'] = deststateeid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   542
    nocheck = session.transaction_data.setdefault('skip-security', set())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   543
    nocheck.add((entity.eid, 'from_state', fromstate.eid))
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   544
    nocheck.add((entity.eid, 'to_state', deststateeid))
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   545
    FireAutotransitionOp(session, entity=forentity)
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3508
diff changeset
   546
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   547
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   548
def after_add_trinfo(session, entity):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   549
    """change related entity state"""
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   550
    _change_state(session, entity['wf_info_for'],
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   551
                  entity['from_state'], entity['to_state'])
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   552
    forentity = session.entity_from_eid(entity['wf_info_for'])
3568
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   553
    assert forentity.current_state.eid == entity['to_state'], (
87a7ca9d8ce6 [hooks] don't delete composed of a composite where relation is being removed from the schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3554
diff changeset
   554
        forentity.eid, forentity.current_state.name)
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   555
    if forentity.main_workflow.eid != forentity.current_workflow.eid:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   556
        # we're in a subworkflow, check if we've reached an exit point
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   557
        wftr = forentity.subworkflow_input_transition()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   558
        if wftr is None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   559
            # inconsistency detected
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   560
            msg = entity.req._("state doesn't belong to entity's current workflow")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   561
            raise ValidationError(entity.eid, {'to_state': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   562
        tostate = wftr.get_exit_point(entity['to_state'])
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   563
        if tostate is not None:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   564
            # reached an exit point
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   565
            msg = session._('exiting from subworkflow %s')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   566
            msg %= session._(forentity.current_workflow.name)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   567
            session.transaction_data[(forentity.eid, 'subwfentrytr')] = True
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   568
            # XXX iirk
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   569
            req = forentity.req
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   570
            forentity.req = session.super_session
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   571
            try:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   572
                trinfo = forentity.change_state(tostate, msg, u'text/plain',
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   573
                                                tr=wftr)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   574
            finally:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   575
                forentity.req = req
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   576
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   577
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
class SetInitialStateOp(PreCommitOperation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
    """make initial state be a default state"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   581
    def precommit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
        session = self.session
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
        entity = self.entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
        # if there is an initial state and the entity's state is not set,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   585
        # use the initial state as a default state
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   586
        pendingeids = session.transaction_data.get('pendingeids', ())
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   587
        if not entity.eid in pendingeids and not entity.in_state and \
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   588
               entity.main_workflow:
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   589
            state = entity.main_workflow.initial
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   590
            if state:
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   591
                # use super session to by-pass security checks
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   592
                session.super_session.add_relation(entity.eid, 'in_state',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   593
                                                   state.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   594
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   595
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
def set_initial_state_after_add(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
    SetInitialStateOp(session, entity=entity)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   598
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   599
2983
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   600
def before_add_in_state(session, eidfrom, rtype, eidto):
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   601
    """check state apply, in case of direct in_state change using unsafe_execute
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   602
    """
3508
d9915224f9a5 [B] server: fix initial data structure in session.transaction_data
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 3071
diff changeset
   603
    nocheck = session.transaction_data.setdefault('skip-security', set())
2983
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   604
    if (eidfrom, 'in_state', eidto) in nocheck:
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   605
        # state changed through TrInfo insertion, so we already know it's ok
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   606
        return
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   607
    entity = session.entity_from_eid(eidfrom)
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   608
    mainwf = entity.main_workflow
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   609
    if mainwf is None:
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   610
        msg = session._('entity has no workflow set')
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   611
        raise ValidationError(entity.eid, {None: msg})
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   612
    for wf in mainwf.iter_workflows():
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   613
        if wf.state_by_eid(eidto):
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   614
            break
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   615
    else:
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   616
        msg = session._("state doesn't belong to entity's workflow. You may "
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   617
                        "want to set a custom workflow for this entity first.")
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   618
        raise ValidationError(eidfrom, {'in_state': msg})
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   619
    if entity.current_workflow and wf.eid != entity.current_workflow.eid:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   620
        msg = session._("state doesn't belong to entity's current workflow")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   621
        raise ValidationError(eidfrom, {'in_state': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   622
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   623
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   624
class CheckTrExitPoint(PreCommitOperation):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   625
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   626
    def precommit_event(self):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   627
        tr = self.session.entity_from_eid(self.treid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   628
        outputs = set()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   629
        for ep in tr.subworkflow_exit:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   630
            if ep.subwf_state.eid in outputs:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   631
                msg = self.session._("can't have multiple exits on the same state")
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   632
                raise ValidationError(self.treid, {'subworkflow_exit': msg})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   633
            outputs.add(ep.subwf_state.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   634
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   635
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   636
def after_add_subworkflow_exit(session, eidfrom, rtype, eidto):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   637
    CheckTrExitPoint(session, treid=eidfrom)
2983
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   638
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   639
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   640
class WorkflowChangedOp(PreCommitOperation):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   641
    """fix entity current state when changing its workflow"""
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   642
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   643
    def precommit_event(self):
2985
79185b3ccf2c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2983
diff changeset
   644
        # notice that enforcement that new workflow apply to the entity's type is
79185b3ccf2c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2983
diff changeset
   645
        # done by schema rule, no need to check it here
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   646
        session = self.session
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   647
        pendingeids = session.transaction_data.get('pendingeids', ())
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   648
        if self.eid in pendingeids:
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   649
            return
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   650
        entity = session.entity_from_eid(self.eid)
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   651
        # check custom workflow has not been rechanged to another one in the same
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   652
        # transaction
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   653
        mainwf = entity.main_workflow
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   654
        if mainwf.eid == self.wfeid:
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   655
            deststate = mainwf.initial
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   656
            if not deststate:
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   657
                msg = session._('workflow has no initial state')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   658
                raise ValidationError(entity.eid, {'custom_workflow': msg})
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   659
            if mainwf.state_by_eid(entity.current_state.eid):
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   660
                # nothing to do
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   661
                return
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   662
            # if there are no history, simply go to new workflow's initial state
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   663
            if not entity.workflow_history:
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   664
                if entity.current_state.eid != deststate.eid:
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   665
                    _change_state(session, entity.eid,
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   666
                                  entity.current_state.eid, deststate.eid)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   667
                return
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   668
            msg = session._('workflow changed to "%s"')
2978
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   669
            msg %= session._(mainwf.name)
d8c5ad14ab8e [wf] distinguish main workflow / current workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   670
            session.transaction_data[(entity.eid, 'customwf')] = self.wfeid
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   671
            entity.change_state(deststate, msg, u'text/plain')
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   672
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   673
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   674
def set_custom_workflow(session, eidfrom, rtype, eidto):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   675
    WorkflowChangedOp(session, eid=eidfrom, wfeid=eidto)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   676
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   677
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   678
def del_custom_workflow(session, eidfrom, rtype, eidto):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   679
    entity = session.entity_from_eid(eidfrom)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   680
    typewf = entity.cwetype_workflow()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   681
    if typewf is not None:
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   682
        WorkflowChangedOp(session, eid=eidfrom, wfeid=typewf.eid)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   683
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   684
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   685
def after_del_workflow(session, eid):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   686
    # workflow cleanup
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   687
    session.execute('DELETE State X WHERE NOT X state_of Y')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   688
    session.execute('DELETE Transition X WHERE NOT X transition_of Y')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   689
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   690
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   691
def _register_wf_hooks(hm):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   692
    """register workflow related hooks on the hooks manager"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   693
    if 'in_state' in hm.schema:
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   694
        hm.register_hook(before_add_trinfo, 'before_add_entity', 'TrInfo')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   695
        hm.register_hook(after_add_trinfo, 'after_add_entity', 'TrInfo')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   696
        #hm.register_hook(relation_deleted, 'before_delete_relation', 'in_state')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   697
        for eschema in hm.schema.entities():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   698
            if 'in_state' in eschema.subject_relations():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   699
                hm.register_hook(set_initial_state_after_add, 'after_add_entity',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   700
                                 str(eschema))
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   701
        hm.register_hook(set_custom_workflow, 'after_add_relation', 'custom_workflow')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
   702
        hm.register_hook(del_custom_workflow, 'after_delete_relation', 'custom_workflow')
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2909
diff changeset
   703
        hm.register_hook(after_del_workflow, 'after_delete_entity', 'Workflow')
2983
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2978
diff changeset
   704
        hm.register_hook(before_add_in_state, 'before_add_relation', 'in_state')
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   705
        hm.register_hook(after_add_subworkflow_exit, 'after_add_relation', 'subworkflow_exit')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   706
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   707
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   708
# CWProperty hooks #############################################################
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   709
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   710
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   711
class DelCWPropertyOp(Operation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   712
    """a user's custom properties has been deleted"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   713
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   714
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   715
        """the observed connections pool has been commited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   716
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   717
            del self.epropdict[self.key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   718
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   719
            self.error('%s has no associated value', self.key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   720
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   721
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   722
class ChangeCWPropertyOp(Operation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   723
    """a user's custom properties has been added/changed"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   724
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   725
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   726
        """the observed connections pool has been commited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   727
        self.epropdict[self.key] = self.value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   728
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   729
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   730
class AddCWPropertyOp(Operation):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   731
    """a user's custom properties has been added/changed"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   732
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   733
    def commit_event(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   734
        """the observed connections pool has been commited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   735
        eprop = self.eprop
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   736
        if not eprop.for_user:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   737
            self.repo.vreg.eprop_values[eprop.pkey] = eprop.value
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   738
        # if for_user is set, update is handled by a ChangeCWPropertyOp operation
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   739
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   740
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   741
def after_add_eproperty(session, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   742
    key, value = entity.pkey, entity.value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   743
    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   744
        value = session.vreg.typed_value(key, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   745
    except UnknownProperty:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   746
        raise ValidationError(entity.eid, {'pkey': session._('unknown property key')})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   747
    except ValueError, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   748
        raise ValidationError(entity.eid, {'value': session._(str(ex))})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   749
    if not session.user.matching_groups('managers'):
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   750
        session.add_relation(entity.eid, 'for_user', session.user.eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   751
    else:
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   752
        AddCWPropertyOp(session, eprop=entity)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   753
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   754
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   755
def after_update_eproperty(session, entity):
2695
56439c45781c [hooks] check key or value is actually edited
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2607
diff changeset
   756
    if not ('pkey' in entity.edited_attributes or
56439c45781c [hooks] check key or value is actually edited
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2607
diff changeset
   757
            'value' in entity.edited_attributes):
56439c45781c [hooks] check key or value is actually edited
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2607
diff changeset
   758
        return
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   759
    key, value = entity.pkey, entity.value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   760
    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   761
        value = session.vreg.typed_value(key, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   762
    except UnknownProperty:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   763
        return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   764
    except ValueError, ex:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   765
        raise ValidationError(entity.eid, {'value': session._(str(ex))})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   766
    if entity.for_user:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   767
        for session_ in get_user_sessions(session.repo, entity.for_user[0].eid):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   768
            ChangeCWPropertyOp(session, epropdict=session_.user.properties,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   769
                              key=key, value=value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   770
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   771
        # site wide properties
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   772
        ChangeCWPropertyOp(session, epropdict=session.vreg.eprop_values,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   773
                          key=key, value=value)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   774
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   775
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   776
def before_del_eproperty(session, eid):
2101
08003e0354a7 update transaction data api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   777
    for eidfrom, rtype, eidto in session.transaction_data.get('pendingrelations', ()):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   778
        if rtype == 'for_user' and eidfrom == eid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   779
            # if for_user was set, delete has already been handled
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   780
            break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   781
    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   782
        key = session.execute('Any K WHERE P eid %(x)s, P pkey K',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   783
                              {'x': eid}, 'x')[0][0]
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   784
        DelCWPropertyOp(session, epropdict=session.vreg.eprop_values, key=key)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   785
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   786
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   787
def after_add_for_user(session, fromeid, rtype, toeid):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   788
    if not session.describe(fromeid)[0] == 'CWProperty':
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   789
        return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   790
    key, value = session.execute('Any K,V WHERE P eid %(x)s,P pkey K,P value V',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   791
                                 {'x': fromeid}, 'x')[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   792
    if session.vreg.property_info(key)['sitewide']:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   793
        raise ValidationError(fromeid,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   794
                              {'for_user': session._("site-wide property can't be set for user")})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   795
    for session_ in get_user_sessions(session.repo, toeid):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   796
        ChangeCWPropertyOp(session, epropdict=session_.user.properties,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   797
                          key=key, value=value)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   798
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   799
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   800
def before_del_for_user(session, fromeid, rtype, toeid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   801
    key = session.execute('Any K WHERE P eid %(x)s, P pkey K',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   802
                          {'x': fromeid}, 'x')[0][0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   803
    relation_deleted(session, fromeid, rtype, toeid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   804
    for session_ in get_user_sessions(session.repo, toeid):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   805
        DelCWPropertyOp(session, epropdict=session_.user.properties, key=key)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   806
2603
e47d63351891 [R hooks] optmize insertion by using direct repository methods when possible
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2463
diff changeset
   807
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   808
def _register_eproperty_hooks(hm):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   809
    """register workflow related hooks on the hooks manager"""
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   810
    hm.register_hook(after_add_eproperty, 'after_add_entity', 'CWProperty')
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   811
    hm.register_hook(after_update_eproperty, 'after_update_entity', 'CWProperty')
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   812
    hm.register_hook(before_del_eproperty, 'before_delete_entity', 'CWProperty')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   813
    hm.register_hook(after_add_for_user, 'after_add_relation', 'for_user')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   814
    hm.register_hook(before_del_for_user, 'before_delete_relation', 'for_user')