server/hooks.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 12 Oct 2009 13:13:11 +0200
branchstable
changeset 3642 8bc800f8b173
parent 3628 440931181322
child 3662 9eeadad82d93
permissions -rw-r--r--
...
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})
3628
440931181322 [wf engine] support for subwf exit point with no destination state: go back to state from which we entered into the subworkflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3618
diff changeset
   562
        tostate = wftr.get_exit_point(forentity, entity['to_state'])
2992
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')