server/session.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Wed, 11 Jun 2014 13:39:56 +0200
changeset 10360 1fdbe2ea63d8
parent 10359 8e4ba1028f55
child 10361 46d72f33c428
permissions -rw-r--r--
[transactions] cleanup after the dbapi removal * end req vs cnx dichotomy * Transaction takes a cnx at __init__ time * a couple of super calls are fixed Related to #3933480.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
     1
# copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5226
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5701
41119f034735 [querier] fix rset description bug with some union queries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5426
diff changeset
    18
"""Repository users' and internal' sessions."""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
import sys
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
import threading
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
from time import time
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4899
diff changeset
    24
from uuid import uuid4
5174
78438ad513ca #759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5130
diff changeset
    25
from warnings import warn
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
    26
import functools
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
    27
from contextlib import contextmanager
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
2613
5e19c2bb370e R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2466
diff changeset
    29
from logilab.common.deprecation import deprecated
7769
8af09eeee130 [session] take care of non-ascii characters in login and session id (closes: #1910849)
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 7757
diff changeset
    30
from logilab.common.textutils import unormalize
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8096
diff changeset
    31
from logilab.common.registry import objectify_predicate
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9466
diff changeset
    33
from cubicweb import QueryError, schema, server, ProgrammingError
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
    34
from cubicweb.req import RequestSessionBase
8542
7e264ce34cd4 [session / querier] reorganize code to building result set descriptions
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8538
diff changeset
    35
from cubicweb.utils import make_uid
3240
8604a15995d1 refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3198
diff changeset
    36
from cubicweb.rqlrewrite import RQLRewriter
7119
8b29c4c2ffc6 [repository] fix crash in optimized [add|remove]_relation w/ inlined relation (broken by cw 3.10 refactoring)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7118
diff changeset
    37
from cubicweb.server.edition import EditedEntity
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
7329
f2d52aa8bcdb [session] new selectors according to session type (eg user or internal
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7237
diff changeset
    39
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4899
diff changeset
    40
NO_UNDO_TYPES = schema.SCHEMA_TYPES.copy()
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4899
diff changeset
    41
NO_UNDO_TYPES.add('CWCache')
5074
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
    42
# is / is_instance_of are usually added by sql hooks except when using
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
    43
# dataimport.NoHookRQLObjectStore, and we don't want to record them
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
    44
# anyway in the later case
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
    45
NO_UNDO_TYPES.add('is')
bc481dab93d4 [undo] consistent is/is_instance_of processing
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5069
diff changeset
    46
NO_UNDO_TYPES.add('is_instance_of')
6427
c8a5ac2d1eaa [schema / sources] store data sources as cubicweb entities
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6401
diff changeset
    47
NO_UNDO_TYPES.add('cw_source')
4913
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4899
diff changeset
    48
# XXX rememberme,forgotpwd,apycot,vcsfile
083b4d454192 server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents: 4899
diff changeset
    49
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8096
diff changeset
    50
@objectify_predicate
7329
f2d52aa8bcdb [session] new selectors according to session type (eg user or internal
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7237
diff changeset
    51
def is_user_session(cls, req, **kwargs):
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    52
    """return 1 when session is not internal.
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    53
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    54
    This predicate can only be used repository side only. """
7330
584907154ce3 [session selector] missing not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7329
diff changeset
    55
    return not req.is_internal_session
7329
f2d52aa8bcdb [session] new selectors according to session type (eg user or internal
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7237
diff changeset
    56
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8096
diff changeset
    57
@objectify_predicate
7329
f2d52aa8bcdb [session] new selectors according to session type (eg user or internal
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7237
diff changeset
    58
def is_internal_session(cls, req, **kwargs):
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    59
    """return 1 when session is not internal.
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    60
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    61
    This predicate can only be used repository side only. """
7329
f2d52aa8bcdb [session] new selectors according to session type (eg user or internal
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7237
diff changeset
    62
    return req.is_internal_session
f2d52aa8bcdb [session] new selectors according to session type (eg user or internal
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7237
diff changeset
    63
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8096
diff changeset
    64
@objectify_predicate
7500
cb0f4da64e86 [repository] new hook selector according to configuration's repairing flag
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7451
diff changeset
    65
def repairing(cls, req, **kwargs):
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    66
    """return 1 when repository is running in repair mode"""
7500
cb0f4da64e86 [repository] new hook selector according to configuration's repairing flag
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7451
diff changeset
    67
    return req.vreg.config.repairing
cb0f4da64e86 [repository] new hook selector according to configuration's repairing flag
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7451
diff changeset
    68
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
7451
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    70
class transaction(object):
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9240
diff changeset
    71
    """Ensure that the transaction is either commited or rolled back at exit
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    72
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
    73
    Context manager to enter a transaction for a session: when exiting the
7451
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    74
    `with` block on exception, call `session.rollback()`, else call
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    75
    `session.commit()` on normal exit
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    76
    """
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    77
    def __init__(self, session, free_cnxset=True):
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    78
        self.session = session
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    79
        self.free_cnxset = free_cnxset
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    80
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    81
    def __enter__(self):
8529
1daea1f433c9 [datafeed] make cnxset handling of datafeed source more robust
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8433
diff changeset
    82
        # ensure session has a cnxset
1daea1f433c9 [datafeed] make cnxset handling of datafeed source more robust
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8433
diff changeset
    83
        self.session.set_cnxset()
7451
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    84
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    85
    def __exit__(self, exctype, exc, traceback):
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    86
        if exctype:
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    87
            self.session.rollback(free_cnxset=self.free_cnxset)
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    88
        else:
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    89
            self.session.commit(free_cnxset=self.free_cnxset)
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    90
8840
bd5b5759c9b3 [session] make hook_control API private
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8817
diff changeset
    91
@deprecated('[3.17] use <object>.allow/deny_all_hooks_but instead')
8915
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    92
def hooks_control(obj, mode, *categories):
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    93
    assert mode in  (HOOKS_ALLOW_ALL, HOOKS_DENY_ALL)
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    94
    if mode == HOOKS_ALLOW_ALL:
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    95
        return obj.allow_all_hooks_but(*categories)
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    96
    elif mode == HOOKS_DENY_ALL:
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    97
        return obj.deny_all_hooks_but(*categories)
c5c6da8e42db [session] fix hooks_control backward compat
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8848
diff changeset
    98
7451
48ba5f0c11de [session] provide a simple transaction context manager for session. Closes #1725640
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7405
diff changeset
    99
9122
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
   100
class _hooks_control(object): # XXX repoapi: remove me when
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
   101
                              # session stop being connection
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   102
    """context manager to control activated hooks categories.
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   103
9557
a3c075fe9385 [server/session] fix a couple typos in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
   104
    If mode is `HOOKS_DENY_ALL`, given hooks categories will
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   105
    be enabled.
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   106
9025
768eb9a6a2db [session] update _hook_control docstring
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9024
diff changeset
   107
    If mode is `HOOKS_ALLOW_ALL`, given hooks categories will
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   108
    be disabled.
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   109
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   110
    .. sourcecode:: python
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   111
9025
768eb9a6a2db [session] update _hook_control docstring
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9024
diff changeset
   112
       with _hooks_control(cnx, HOOKS_ALLOW_ALL, 'integrity'):
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   113
           # ... do stuff with all but 'integrity' hooks activated
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   114
9025
768eb9a6a2db [session] update _hook_control docstring
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9024
diff changeset
   115
       with _hooks_control(cnx, HOOKS_DENY_ALL, 'integrity'):
6147
95c604ec89bf update documentation to follow 6142:8bc6eac1fac1 changes. Try to make it better and move most doc with code on the way
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6142
diff changeset
   116
           # ... do stuff with none but 'integrity' hooks activated
8561
77ea3eed9946 [session] promote usage of [deny|all]_all_hooks_but session methods rather than hooks_control context manager directly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8554
diff changeset
   117
9557
a3c075fe9385 [server/session] fix a couple typos in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
   118
    This is an internal API, you should rather use
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   119
    :meth:`~cubicweb.server.session.Connection.deny_all_hooks_but` or
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   120
    :meth:`~cubicweb.server.session.Connection.allow_all_hooks_but`
9557
a3c075fe9385 [server/session] fix a couple typos in doc strings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9543
diff changeset
   121
    Connection methods.
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   122
    """
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   123
    def __init__(self, cnx, mode, *categories):
8814
37fd037c0526 [session] move context manager logic in the hook controls context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8813
diff changeset
   124
        assert mode in (HOOKS_ALLOW_ALL, HOOKS_DENY_ALL)
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   125
        self.cnx = cnx
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   126
        self.mode = mode
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   127
        self.categories = categories
8814
37fd037c0526 [session] move context manager logic in the hook controls context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8813
diff changeset
   128
        self.oldmode = None
37fd037c0526 [session] move context manager logic in the hook controls context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8813
diff changeset
   129
        self.changes = ()
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   130
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   131
    def __enter__(self):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   132
        self.oldmode = self.cnx.hooks_mode
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   133
        self.cnx.hooks_mode = self.mode
8814
37fd037c0526 [session] move context manager logic in the hook controls context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8813
diff changeset
   134
        if self.mode is HOOKS_DENY_ALL:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   135
            self.changes = self.cnx.enable_hook_categories(*self.categories)
8814
37fd037c0526 [session] move context manager logic in the hook controls context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8813
diff changeset
   136
        else:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   137
            self.changes = self.cnx.disable_hook_categories(*self.categories)
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   138
        self.cnx.ctx_count += 1
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   139
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   140
    def __exit__(self, exctype, exc, traceback):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   141
        self.cnx.ctx_count -= 1
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   142
        try:
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   143
            if self.categories:
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   144
                if self.mode is HOOKS_DENY_ALL:
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   145
                    self.cnx.disable_hook_categories(*self.categories)
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   146
                else:
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   147
                    self.cnx.enable_hook_categories(*self.categories)
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   148
        finally:
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   149
            self.cnx.hooks_mode = self.oldmode
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   150
9122
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
   151
class _session_hooks_control(_hooks_control): # XXX repoapi: remove me when
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
   152
                                              # session stop being connection
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   153
    """hook control context manager for session
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   154
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   155
    Necessary to handle some unholy transaction scope logic."""
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   156
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   157
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   158
    def __init__(self, session, mode, *categories):
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   159
        self.session = session
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   160
        super_init = super(_session_hooks_control, self).__init__
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9466
diff changeset
   161
        super_init(session._cnx, mode, *categories)
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   162
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   163
    def __exit__(self, exctype, exc, traceback):
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   164
        super_exit = super(_session_hooks_control, self).__exit__
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   165
        ret = super_exit(exctype, exc, traceback)
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   166
        if self.cnx.ctx_count == 0:
9120
fa513ac7a2a5 [session] privatise get_cnx and close_cnx
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9113
diff changeset
   167
            self.session._close_cnx(self.cnx)
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   168
        return ret
7350
c2452cd57026 [session] enhance session's transaction storage handling to fix cases where commit/rollback is done while in the context of hooks_control/security_enabled managers. Closes #1412648: commit or rollback during postcreate reset hooks control state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7349
diff changeset
   169
8841
f62fb831cfe6 [session] make security_enabled API private
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8840
diff changeset
   170
@deprecated('[3.17] use <object>.security_enabled instead')
f62fb831cfe6 [session] make security_enabled API private
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8840
diff changeset
   171
def security_enabled(obj, *args, **kwargs):
f62fb831cfe6 [session] make security_enabled API private
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8840
diff changeset
   172
    return obj.security_enabled(*args, **kwargs)
7350
c2452cd57026 [session] enhance session's transaction storage handling to fix cases where commit/rollback is done while in the context of hooks_control/security_enabled managers. Closes #1412648: commit or rollback during postcreate reset hooks control state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7349
diff changeset
   173
8841
f62fb831cfe6 [session] make security_enabled API private
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8840
diff changeset
   174
class _security_enabled(object):
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
   175
    """context manager to control security w/ session.execute,
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
   176
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
   177
    By default security is disabled on queries executed on the repository
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   178
    side.
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   179
    """
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   180
    def __init__(self, cnx, read=None, write=None):
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   181
        self.cnx = cnx
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   182
        self.read = read
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   183
        self.write = write
8816
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   184
        self.oldread = None
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   185
        self.oldwrite = None
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   186
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   187
    def __enter__(self):
8816
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   188
        if self.read is None:
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   189
            self.oldread = None
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   190
        else:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   191
            self.oldread = self.cnx.read_security
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   192
            self.cnx.read_security = self.read
8816
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   193
        if self.write is None:
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   194
            self.oldwrite = None
fe321c0f6d13 [session] move context manager logic in the security context manager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8815
diff changeset
   195
        else:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   196
            self.oldwrite = self.cnx.write_security
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   197
            self.cnx.write_security = self.write
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   198
        self.cnx.ctx_count += 1
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   199
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   200
    def __exit__(self, exctype, exc, traceback):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   201
        self.cnx.ctx_count -= 1
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   202
        if self.oldread is not None:
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   203
            self.cnx.read_security = self.oldread
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   204
        if self.oldwrite is not None:
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   205
            self.cnx.write_security = self.oldwrite
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   206
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   207
class _session_security_enabled(_security_enabled):
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   208
    """hook security context manager for session
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   209
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   210
    Necessary To handle some unholy transaction scope logic."""
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   211
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   212
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   213
    def __init__(self, session, read=None, write=None):
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   214
        self.session = session
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   215
        super_init = super(_session_security_enabled, self).__init__
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9466
diff changeset
   216
        super_init(session._cnx, read=read, write=write)
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   217
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   218
    def __exit__(self, exctype, exc, traceback):
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   219
        super_exit = super(_session_security_enabled, self).__exit__
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   220
        ret = super_exit(exctype, exc, traceback)
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   221
        if self.cnx.ctx_count == 0:
9120
fa513ac7a2a5 [session] privatise get_cnx and close_cnx
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9113
diff changeset
   222
            self.session._close_cnx(self.cnx)
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
   223
        return ret
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   224
8765
9e9029ba2d4e [session] Move hook control constants out of the class
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8764
diff changeset
   225
HOOKS_ALLOW_ALL = object()
9e9029ba2d4e [session] Move hook control constants out of the class
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8764
diff changeset
   226
HOOKS_DENY_ALL = object()
8767
a75670ef2d87 [session] move security constant out of the class
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8766
diff changeset
   227
DEFAULT_SECURITY = object() # evaluated to true by design
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   228
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   229
class SessionClosedError(RuntimeError):
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   230
    pass
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   231
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   232
class CnxSetTracker(object):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   233
    """Keep track of which connection use which cnxset.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   234
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   235
    There should be one of these objects per session (including internal sessions).
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   236
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   237
    Session objects are responsible for creating their CnxSetTracker object.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   238
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   239
    Connections should use the :meth:`record` and :meth:`forget` to inform the
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   240
    tracker of cnxsets they have acquired.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   241
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   242
    .. automethod:: cubicweb.server.session.CnxSetTracker.record
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   243
    .. automethod:: cubicweb.server.session.CnxSetTracker.forget
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   244
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   245
    Sessions use the :meth:`close` and :meth:`wait` methods when closing.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   246
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   247
    .. automethod:: cubicweb.server.session.CnxSetTracker.close
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   248
    .. automethod:: cubicweb.server.session.CnxSetTracker.wait
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   249
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   250
    This object itself is threadsafe. It also requires caller to acquired its
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   251
    lock in some situation.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   252
    """
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   253
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   254
    def __init__(self):
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   255
        self._active = True
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   256
        self._condition = threading.Condition()
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   257
        self._record = {}
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   258
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   259
    def __enter__(self):
9221
e9a3a22f98b7 Use return in CnxSetTracker context manager methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 9194
diff changeset
   260
        return self._condition.__enter__()
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   261
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   262
    def __exit__(self, *args):
9221
e9a3a22f98b7 Use return in CnxSetTracker context manager methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 9194
diff changeset
   263
        return self._condition.__exit__(*args)
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   264
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   265
    def record(self, cnxid, cnxset):
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   266
        """Inform the tracker that a cnxid has acquired a cnxset
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   267
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   268
        This method is to be used by Connection objects.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   269
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   270
        This method fails when:
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   271
        - The cnxid already has a recorded cnxset.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   272
        - The tracker is not active anymore.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   273
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   274
        Notes about the caller:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   275
        (1) It is responsible for retrieving a cnxset.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   276
        (2) It must be prepared to release the cnxset if the
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   277
            `cnxsettracker.forget` call fails.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   278
        (3) It should acquire the tracker lock until the very end of the operation.
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   279
        (4) However it must only lock the CnxSetTracker object after having
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   280
            retrieved the cnxset to prevent deadlock.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   281
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   282
        A typical usage look like::
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   283
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   284
        cnxset = repo._get_cnxset() # (1)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   285
        try:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   286
            with cnxset_tracker: # (3) and (4)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   287
                cnxset_tracker.record(caller.id, cnxset)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   288
                # (3') operation ends when caller is in expected state only
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   289
                caller.cnxset = cnxset
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   290
        except Exception:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   291
            repo._free_cnxset(cnxset) # (2)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   292
            raise
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   293
        """
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   294
        # dubious since the caller is supposed to have acquired it anyway.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   295
        with self._condition:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   296
            if not self._active:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   297
                raise SessionClosedError('Closed')
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   298
            old = self._record.get(cnxid)
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   299
            if old is not None:
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   300
                raise ValueError('connection "%s" already has a cnx_set (%r)'
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   301
                                 % (cnxid, old))
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   302
            self._record[cnxid] = cnxset
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   303
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   304
    def forget(self, cnxid, cnxset):
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   305
        """Inform the tracker that a cnxid have release a cnxset
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   306
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   307
        This methode is to be used by Connection object.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   308
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   309
        This method fails when:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   310
        - The cnxset for the cnxid does not match the recorded one.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   311
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   312
        Notes about the caller:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   313
        (1) It is responsible for releasing the cnxset.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   314
        (2) It should acquire the tracker lock during the operation to ensure
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   315
            the internal tracker state is always accurate regarding its own state.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   316
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   317
        A typical usage look like::
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   318
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   319
        cnxset = caller.cnxset
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   320
        try:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   321
            with cnxset_tracker:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   322
                # (2) you can not have caller.cnxset out of sync with
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   323
                #     cnxset_tracker state while unlocked
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   324
                caller.cnxset = None
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   325
                cnxset_tracker.forget(caller.id, cnxset)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   326
        finally:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   327
            cnxset = repo._free_cnxset(cnxset) # (1)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   328
        """
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   329
        with self._condition:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   330
            old = self._record.get(cnxid, None)
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   331
            if old is not cnxset:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   332
                raise ValueError('recorded cnxset for "%s" mismatch: %r != %r'
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   333
                                 % (cnxid, old, cnxset))
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   334
            self._record.pop(cnxid)
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   335
            self._condition.notify_all()
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   336
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   337
    def close(self):
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   338
        """Marks the tracker as inactive.
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   339
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   340
        This method is to be used by Session objects.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   341
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   342
        An inactive tracker does not accept new records anymore.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   343
        """
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   344
        with self._condition:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   345
            self._active = False
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   346
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   347
    def wait(self, timeout=10):
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   348
        """Wait for all recorded cnxsets to be released
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   349
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   350
        This method is to be used by Session objects.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   351
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   352
        Returns a tuple of connection ids that remain open.
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   353
        """
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   354
        with self._condition:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   355
            if  self._active:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   356
                raise RuntimeError('Cannot wait on active tracker.'
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   357
                                   ' Call tracker.close() first')
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   358
            while self._record and timeout > 0:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   359
                start = time()
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   360
                self._condition.wait(timeout)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   361
                timeout -= time() - start
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   362
            return tuple(self._record)
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   363
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   364
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   365
def _with_cnx_set(func):
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   366
    """decorator for Connection method that ensure they run with a cnxset """
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   367
    @functools.wraps(func)
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   368
    def wrapper(cnx, *args, **kwargs):
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   369
        with cnx.ensure_cnx_set:
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   370
            return func(cnx, *args, **kwargs)
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   371
    return wrapper
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   372
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   373
def _open_only(func):
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   374
    """decorator for Connection method that check it is open"""
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   375
    @functools.wraps(func)
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   376
    def check_open(cnx, *args, **kwargs):
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   377
        if not cnx._open:
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   378
            raise ProgrammingError('Closed Connection: %s'
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   379
                                    % cnx.connectionid)
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   380
        return func(cnx, *args, **kwargs)
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   381
    return check_open
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   382
9630
e7dbc4f06a48 minor cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9629
diff changeset
   383
9073
9574df1cd054 [Connection] inherit from RequestSessionBase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9052
diff changeset
   384
class Connection(RequestSessionBase):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   385
    """Repository Connection
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   386
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   387
    Holds all connection related data
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   388
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   389
    Database connection resources:
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   390
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   391
      :attr:`hooks_in_progress`, boolean flag telling if the executing
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   392
      query is coming from a repoapi connection or is a query from
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   393
      within the repository (e.g. started by hooks)
8805
d91285fe7242 [transaction] initialize dbapi_request in __init__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8790
diff changeset
   394
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   395
      :attr:`cnxset`, the connections set to use to execute queries on sources.
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   396
      If the transaction is read only, the connection set may be freed between
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   397
      actual queries. This allows multiple connections with a reasonably low
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   398
      connection set pool size.  Control mechanism is detailed below.
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   399
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   400
    .. automethod:: cubicweb.server.session.Connection.set_cnxset
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   401
    .. automethod:: cubicweb.server.session.Connection.free_cnxset
8843
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   402
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   403
      :attr:`mode`, string telling the connections set handling mode, may be one
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   404
      of 'read' (connections set may be freed), 'write' (some write was done in
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   405
      the connections set, it can't be freed before end of the transaction),
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   406
      'transaction' (we want to keep the connections set during all the
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   407
      transaction, with or without writing)
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   408
10347
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   409
    Shared data:
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   410
10347
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   411
      :attr:`data` is a dictionary bound to the underlying session,
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   412
      who will be present for the life time of the session. This may
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   413
      be useful for web clients that rely on the server for managing
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   414
      bits of session-scoped data.
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   415
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   416
      :attr:`transaction_data` is a dictionary cleared at the end of
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   417
      the transaction. Hooks and operations may put arbitrary data in
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   418
      there.
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   419
52a976c5d27a [connection] provide some missing documentation bits
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10346
diff changeset
   420
    Internal state:
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   421
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   422
      :attr:`pending_operations`, ordered list of operations to be processed on
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   423
      commit/rollback
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   424
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   425
      :attr:`commit_state`, describing the transaction commit state, may be one
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   426
      of None (not yet committing), 'precommit' (calling precommit event on
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   427
      operations), 'postcommit' (calling postcommit event on operations),
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   428
      'uncommitable' (some :exc:`ValidationError` or :exc:`Unauthorized` error
9267
24d9b86dfa54 spelling: rollbacked -> rolled back
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9240
diff changeset
   429
      has been raised during the transaction and so it must be rolled back).
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   430
8766
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   431
    Hooks controls:
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   432
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   433
      :attr:`hooks_mode`, may be either `HOOKS_ALLOW_ALL` or `HOOKS_DENY_ALL`.
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   434
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   435
      :attr:`enabled_hook_cats`, when :attr:`hooks_mode` is
8766
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   436
      `HOOKS_DENY_ALL`, this set contains hooks categories that are enabled.
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   437
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   438
      :attr:`disabled_hook_cats`, when :attr:`hooks_mode` is
8766
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   439
      `HOOKS_ALLOW_ALL`, this set contains hooks categories that are disabled.
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   440
8768
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   441
    Security level Management:
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   442
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   443
      :attr:`read_security` and :attr:`write_security`, boolean flags telling if
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   444
      read/write security is currently activated.
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   445
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   446
    """
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   447
9085
af6085c9ac69 [connection] mark Connection as "not a request"
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9084
diff changeset
   448
    is_request = False
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   449
    hooks_in_progress = False
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   450
    is_repo_in_memory = True # bw compat
10346
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
   451
    mode = 'read'
9085
af6085c9ac69 [connection] mark Connection as "not a request"
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9084
diff changeset
   452
10359
8e4ba1028f55 [session/cnx] remove `session_handled` logic
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10355
diff changeset
   453
    def __init__(self, session):
9073
9574df1cd054 [Connection] inherit from RequestSessionBase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9052
diff changeset
   454
        # using super(Connection, self) confuse some test hack
9574df1cd054 [Connection] inherit from RequestSessionBase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9052
diff changeset
   455
        RequestSessionBase.__init__(self, session.vreg)
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   456
        #: connection unique id
9108
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   457
        self._open = None
10359
8e4ba1028f55 [session/cnx] remove `session_handled` logic
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10355
diff changeset
   458
        self.connectionid = '%s-%s' % (session.sessionid, uuid4().hex)
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   459
        self.session = session
9493
852f5ac90cd9 [server/session] session.id → session.sessionid
Julien Cristau <julien.cristau@logilab.fr>
parents: 9482
diff changeset
   460
        self.sessionid = session.sessionid
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
   461
        #: reentrance handling
7350
c2452cd57026 [session] enhance session's transaction storage handling to fix cases where commit/rollback is done while in the context of hooks_control/security_enabled managers. Closes #1412648: commit or rollback during postcreate reset hooks control state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7349
diff changeset
   462
        self.ctx_count = 0
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   463
        #: count the number of entry in a context needing a cnxset
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   464
        self._cnxset_count = 0
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   465
        #: Boolean for compat with the older explicite set_cnxset/free_cnx API
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   466
        #: When a call set_cnxset is done, no automatic freeing will be done
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   467
        #: until free_cnx is called.
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   468
        self._auto_free_cnx_set = True
7350
c2452cd57026 [session] enhance session's transaction storage handling to fix cases where commit/rollback is done while in the context of hooks_control/security_enabled managers. Closes #1412648: commit or rollback during postcreate reset hooks control state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7349
diff changeset
   469
8842
63fa6b02b241 [transaction] keep a reference to the repo object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8841
diff changeset
   470
        #: server.Repository object
63fa6b02b241 [transaction] keep a reference to the repo object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8841
diff changeset
   471
        self.repo = session.repo
8845
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
   472
        self.vreg = self.repo.vreg
9086
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
   473
        self._execute = self.repo.querier.execute
8842
63fa6b02b241 [transaction] keep a reference to the repo object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8841
diff changeset
   474
9089
b4c12d2873f6 [connection] Connection.execute touch Session timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9088
diff changeset
   475
        # other session utility
b4c12d2873f6 [connection] Connection.execute touch Session timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9088
diff changeset
   476
        self._session_timestamp = session._timestamp
8842
63fa6b02b241 [transaction] keep a reference to the repo object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8841
diff changeset
   477
8762
6b397a0ba1d6 [transaction] explicit Transaction cnxset attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8761
diff changeset
   478
        #: connection set used to execute queries on sources
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   479
        self._cnxset = None
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   480
        #: CnxSetTracker used to report cnxset usage
10346
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
   481
        self._cnxset_tracker = CnxSetTracker()
9023
67f242261dd3 [connection] give access to is_internal_session boolean
pierre-yves
parents: 9022
diff changeset
   482
        # internal (root) session
10345
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   483
        self.is_internal_session = isinstance(session.user, InternalManager)
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
   484
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   485
        #: dict containing arbitrary data cleared at the end of the transaction
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   486
        self.transaction_data = {}
9078
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   487
        self._session_data = session.data
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   488
        #: ordered list of operations to be processed on commit/rollback
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   489
        self.pending_operations = []
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   490
        #: (None, 'precommit', 'postcommit', 'uncommitable')
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   491
        self.commit_state = None
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   492
8766
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   493
        ### hook control attribute
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   494
        self.hooks_mode = HOOKS_ALLOW_ALL
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   495
        self.disabled_hook_cats = set()
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   496
        self.enabled_hook_cats = set()
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   497
        self.pruned_hooks_cache = {}
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   498
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   499
8768
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   500
        ### security control attributes
8806
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
   501
        self._read_security = DEFAULT_SECURITY # handled by a property
8768
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   502
        self.write_security = DEFAULT_SECURITY
3d105e270abc [transaction] initialize security control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8767
diff changeset
   503
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
   504
        # undo control
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
   505
        config = session.repo.config
10345
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   506
        if config.creating or config.repairing or self.is_internal_session:
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
   507
            self.undo_actions = False
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
   508
        else:
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
   509
            self.undo_actions = config['undo-enabled']
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
   510
8769
1672502ac204 [transaction] move RQLRewriter in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8768
diff changeset
   511
        # RQLRewriter are not thread safe
9090
e33ff287f082 [connection] pass a Connection object to RQLRewriter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9089
diff changeset
   512
        self._rewriter = RQLRewriter(self)
8769
1672502ac204 [transaction] move RQLRewriter in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8768
diff changeset
   513
9088
04ceb4268b3b [connection] Connection now call _set_user to CWUser object linked to itseld
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9087
diff changeset
   514
        # other session utility
04ceb4268b3b [connection] Connection now call _set_user to CWUser object linked to itseld
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9087
diff changeset
   515
        if session.user.login == '__internal_manager__':
04ceb4268b3b [connection] Connection now call _set_user to CWUser object linked to itseld
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9087
diff changeset
   516
            self.user = session.user
9764
e81facdef9b5 [connection] set language on new Connection for the internal manager
Julien Cristau <julien.cristau@logilab.fr>
parents: 9721
diff changeset
   517
            self.set_language(self.user.prefered_language())
9088
04ceb4268b3b [connection] Connection now call _set_user to CWUser object linked to itseld
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9087
diff changeset
   518
        else:
04ceb4268b3b [connection] Connection now call _set_user to CWUser object linked to itseld
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9087
diff changeset
   519
            self._set_user(session.user)
9078
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   520
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   521
    @_open_only
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   522
    def source_defs(self):
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   523
        """Return the definition of sources used by the repository."""
10355
60b8204fcca3 [session] all cnx._session become cnx.session
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10352
diff changeset
   524
        return self.session.repo.source_defs()
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   525
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   526
    @_open_only
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   527
    def get_schema(self):
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   528
        """Return the schema currently used by the repository."""
10355
60b8204fcca3 [session] all cnx._session become cnx.session
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10352
diff changeset
   529
        return self.session.repo.source_defs()
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   530
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   531
    @_open_only
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   532
    def get_option_value(self, option):
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   533
        """Return the value for `option` in the configuration."""
10355
60b8204fcca3 [session] all cnx._session become cnx.session
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10352
diff changeset
   534
        return self.session.repo.get_option_value(option)
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   535
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   536
    # transaction api
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   537
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   538
    @_open_only
10360
1fdbe2ea63d8 [transactions] cleanup after the dbapi removal
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10359
diff changeset
   539
    def undoable_transactions(self, ueid=None, **actionfilters):
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   540
        """Return a list of undoable transaction objects by the connection's
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   541
        user, ordered by descendant transaction time.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   542
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   543
        Managers may filter according to user (eid) who has done the transaction
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   544
        using the `ueid` argument. Others will only see their own transactions.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   545
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   546
        Additional filtering capabilities is provided by using the following
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   547
        named arguments:
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   548
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   549
        * `etype` to get only transactions creating/updating/deleting entities
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   550
          of the given type
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   551
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   552
        * `eid` to get only transactions applied to entity of the given eid
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   553
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   554
        * `action` to get only transactions doing the given action (action in
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   555
          'C', 'U', 'D', 'A', 'R'). If `etype`, action can only be 'C', 'U' or
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   556
          'D'.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   557
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   558
        * `public`: when additional filtering is provided, they are by default
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   559
          only searched in 'public' actions, unless a `public` argument is given
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   560
          and set to false.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   561
        """
10360
1fdbe2ea63d8 [transactions] cleanup after the dbapi removal
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10359
diff changeset
   562
        return self.repo.system_source.undoable_transactions(self, ueid,
1fdbe2ea63d8 [transactions] cleanup after the dbapi removal
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10359
diff changeset
   563
                                                             **actionfilters)
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   564
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   565
    @_open_only
10360
1fdbe2ea63d8 [transactions] cleanup after the dbapi removal
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10359
diff changeset
   566
    def transaction_info(self, txuuid):
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   567
        """Return transaction object for the given uid.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   568
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   569
        raise `NoSuchTransaction` if not found or if session's user is
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   570
        not allowed (eg not in managers group and the transaction
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   571
        doesn't belong to him).
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   572
        """
10360
1fdbe2ea63d8 [transactions] cleanup after the dbapi removal
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10359
diff changeset
   573
        return self.repo.system_source.tx_info(self, txuuid)
10352
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   574
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   575
    @_open_only
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   576
    def transaction_actions(self, txuuid, public=True):
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   577
        """Return an ordered list of actions effectued during that transaction.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   578
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   579
        If public is true, return only 'public' actions, i.e. not ones
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   580
        triggered under the cover by hooks, else return all actions.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   581
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   582
        raise `NoSuchTransaction` if the transaction is not found or
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   583
        if the user is not allowed (eg not in managers group).
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   584
        """
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   585
        return self.repo.system_source.tx_actions(self, txuuid, public)
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   586
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   587
    @_open_only
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   588
    def undo_transaction(self, txuuid):
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   589
        """Undo the given transaction. Return potential restoration errors.
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   590
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   591
        raise `NoSuchTransaction` if not found or if user is not
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   592
        allowed (eg not in managers group).
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   593
        """
bab2befaac9b [session] provide missing apis to Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10351
diff changeset
   594
        return self.repo.system_source.undo_transaction(self, txuuid)
9089
b4c12d2873f6 [connection] Connection.execute touch Session timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9088
diff changeset
   595
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   596
    # life cycle handling ####################################################
9108
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   597
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   598
    def __enter__(self):
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   599
        assert self._open is None # first opening
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   600
        self._open = True
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   601
        return self
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   602
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   603
    def __exit__(self, exctype=None, excvalue=None, tb=None):
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   604
        assert self._open # actually already open
9684
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
   605
        assert self._cnxset_count == 0
9934
e32964e28a45 [session] call rollback in Connection.__exit__
Julien Cristau <julien.cristau@logilab.fr>
parents: 9774
diff changeset
   606
        self.rollback()
9108
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   607
        self._open = False
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   608
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   609
    @contextmanager
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   610
    def running_hooks_ops(self):
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   611
        """this context manager should be called whenever hooks or operations
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   612
        are about to be run (but after hook selection)
9108
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   613
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   614
        It will help the undo logic record pertinent metadata or some
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   615
        hooks to run (or not) depending on who/what issued the query.
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   616
        """
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   617
        prevmode = self.hooks_in_progress
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   618
        self.hooks_in_progress = True
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   619
        yield
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
   620
        self.hooks_in_progress = prevmode
9108
6a4070e2849d [connection] handle and explicitly life cycle on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9107
diff changeset
   621
9078
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   622
    # shared data handling ###################################################
8769
1672502ac204 [transaction] move RQLRewriter in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8768
diff changeset
   623
8779
9b2f68916474 [transaction] rename transaction_data to data
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8778
diff changeset
   624
    @property
9078
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   625
    def data(self):
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   626
        return self._session_data
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   627
9083
fe254c803ed1 [connection] have rql_rewriter accession on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9082
diff changeset
   628
    @property
fe254c803ed1 [connection] have rql_rewriter accession on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9082
diff changeset
   629
    def rql_rewriter(self):
fe254c803ed1 [connection] have rql_rewriter accession on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9082
diff changeset
   630
        return self._rewriter
fe254c803ed1 [connection] have rql_rewriter accession on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9082
diff changeset
   631
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   632
    @_open_only
10171
f4f9bff9cf06 [server] Increase the stacklevel (due to @_open_only decorator)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10074
diff changeset
   633
    @deprecated('[3.19] use session or transaction data', stacklevel=3)
9078
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   634
    def get_shared_data(self, key, default=None, pop=False, txdata=False):
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   635
        """return value associated to `key` in session data"""
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   636
        if txdata:
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   637
            data = self.transaction_data
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   638
        else:
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   639
            data = self._session_data
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   640
        if pop:
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   641
            return data.pop(key, default)
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   642
        else:
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   643
            return data.get(key, default)
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   644
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   645
    @_open_only
10171
f4f9bff9cf06 [server] Increase the stacklevel (due to @_open_only decorator)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10074
diff changeset
   646
    @deprecated('[3.19] use session or transaction data', stacklevel=3)
9078
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   647
    def set_shared_data(self, key, value, txdata=False):
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   648
        """set value associated to `key` in session data"""
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   649
        if txdata:
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   650
            self.transaction_data[key] = value
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   651
        else:
cfefd64c7039 [connection] give access to shared data method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9077
diff changeset
   652
            self._session_data[key] = value
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4834
diff changeset
   653
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   654
    def clear(self):
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   655
        """reset internal data"""
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   656
        self.transaction_data = {}
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   657
        #: ordered list of operations to be processed on commit/rollback
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   658
        self.pending_operations = []
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   659
        #: (None, 'precommit', 'postcommit', 'uncommitable')
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   660
        self.commit_state = None
8766
db80ffb2f71c [transaction] initialize hook control attribute in Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8765
diff changeset
   661
        self.pruned_hooks_cache = {}
9082
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
   662
        self.local_perm_cache.clear()
9090
e33ff287f082 [connection] pass a Connection object to RQLRewriter
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9089
diff changeset
   663
        self.rewriter = RQLRewriter(self)
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   664
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   665
    # Connection Set Management ###############################################
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   666
    @property
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   667
    @_open_only
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   668
    def cnxset(self):
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   669
        return self._cnxset
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   670
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   671
    @cnxset.setter
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   672
    @_open_only
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   673
    def cnxset(self, new_cnxset):
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   674
        with self._cnxset_tracker:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   675
            old_cnxset = self._cnxset
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   676
            if new_cnxset is old_cnxset:
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   677
                return #nothing to do
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   678
            if old_cnxset is not None:
9707
4a23058e4d9f [server/session] add missing rollback when freeing a db connection
Julien Cristau <julien.cristau@logilab.fr>
parents: 9684
diff changeset
   679
                old_cnxset.rollback()
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   680
                self._cnxset = None
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   681
                self.ctx_count -= 1
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   682
                self._cnxset_tracker.forget(self.connectionid, old_cnxset)
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   683
            if new_cnxset is not None:
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   684
                self._cnxset_tracker.record(self.connectionid, new_cnxset)
8809
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   685
                self._cnxset = new_cnxset
9ee4d0c65ad2 [session] use a dedicated class to track cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8808
diff changeset
   686
                self.ctx_count += 1
8764
c4f022a6c7dd [transaction] initialize transaction data and state related attribute.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8763
diff changeset
   687
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   688
    @_open_only
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   689
    def _set_cnxset(self):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   690
        """the connection need a connections set to execute some queries"""
8843
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   691
        if self.cnxset is None:
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   692
            cnxset = self.repo._get_cnxset()
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   693
            try:
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   694
                self.cnxset = cnxset
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   695
            except:
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   696
                self.repo._free_cnxset(cnxset)
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   697
                raise
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   698
        return self.cnxset
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   699
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   700
    @_open_only
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   701
    def _free_cnxset(self, ignoremode=False):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   702
        """the connection is no longer using its connections set, at least for some time"""
8843
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   703
        # cnxset may be none if no operation has been done since last commit
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   704
        # or rollback
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   705
        cnxset = self.cnxset
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   706
        if cnxset is not None and (ignoremode or self.mode == 'read'):
9684
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
   707
            assert self._cnxset_count == 0
8843
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   708
            try:
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   709
                self.cnxset = None
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   710
            finally:
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   711
                cnxset.cnxset_freed()
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   712
                self.repo._free_cnxset(cnxset)
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   713
9404
3e3e9b37e177 fix version number: we still target cw 3.19
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9403
diff changeset
   714
    @deprecated('[3.19] cnxset are automatically managed now.'
9123
c992811edec2 [connection] deprecated free_cnset and set_cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9122
diff changeset
   715
                ' stop using explicit set and free.')
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   716
    def set_cnxset(self):
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   717
        self._auto_free_cnx_set = False
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   718
        return self._set_cnxset()
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   719
9404
3e3e9b37e177 fix version number: we still target cw 3.19
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9403
diff changeset
   720
    @deprecated('[3.19] cnxset are automatically managed now.'
9123
c992811edec2 [connection] deprecated free_cnset and set_cnxset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9122
diff changeset
   721
                ' stop using explicit set and free.')
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   722
    def free_cnxset(self, ignoremode=False):
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   723
        self._auto_free_cnx_set = True
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   724
        return self._free_cnxset(ignoremode=ignoremode)
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   725
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   726
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   727
    @property
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   728
    @contextmanager
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   729
    @_open_only
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   730
    def ensure_cnx_set(self):
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   731
        assert self._cnxset_count >= 0
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   732
        if self._cnxset_count == 0:
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   733
            self._set_cnxset()
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   734
        try:
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   735
            self._cnxset_count += 1
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   736
            yield
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   737
        finally:
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   738
            self._cnxset_count = max(self._cnxset_count - 1, 0)
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   739
            if self._cnxset_count == 0 and self._auto_free_cnx_set:
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   740
                self._free_cnxset()
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
   741
8843
ea05b8545dd8 [session/transaction] handle cnxset repository logic in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8842
diff changeset
   742
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   743
    # Entity cache management #################################################
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   744
    #
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
   745
    # The connection entity cache as held in cnx.transaction_data is removed at the
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   746
    # end of the connection (commit and rollback)
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   747
    #
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   748
    # XXX connection level caching may be a pb with multiple repository
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   749
    # instances, but 1. this is probably not the only one :$ and 2. it may be
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   750
    # an acceptable risk. Anyway we could activate it or not according to a
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   751
    # configuration option
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   752
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   753
    def set_entity_cache(self, entity):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
   754
        """Add `entity` to the connection entity cache"""
9113
af6efc15fc90 [repository] add an ``internal_cnx`` method to replace ``internal_session``
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9112
diff changeset
   755
        # XXX not using _open_only because before at creation time. _set_user
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   756
        # call this function to cache the Connection user.
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   757
        if entity.cw_etype != 'CWUser' and not self._open:
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   758
            raise ProgrammingError('Closed Connection: %s'
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   759
                                    % self.connectionid)
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   760
        ecache = self.transaction_data.setdefault('ecache', {})
8784
07f453bf72e8 [transaction] small simplification in ecache code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8783
diff changeset
   761
        ecache.setdefault(entity.eid, entity)
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   762
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   763
    @_open_only
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   764
    def entity_cache(self, eid):
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   765
        """get cache entity for `eid`"""
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   766
        return self.transaction_data['ecache'][eid]
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   767
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   768
    @_open_only
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   769
    def cached_entities(self):
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   770
        """return the whole entity cache"""
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   771
        return self.transaction_data.get('ecache', {}).values()
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   772
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   773
    @_open_only
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   774
    def drop_entity_cache(self, eid=None):
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   775
        """drop entity from the cache
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   776
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   777
        If eid is None, the whole cache is dropped"""
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   778
        if eid is None:
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   779
            self.transaction_data.pop('ecache', None)
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   780
        else:
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   781
            del self.transaction_data['ecache'][eid]
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   782
9079
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   783
    # relations handling #######################################################
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   784
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   785
    @_open_only
9079
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   786
    def add_relation(self, fromeid, rtype, toeid):
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   787
        """provide direct access to the repository method to add a relation.
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   788
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   789
        This is equivalent to the following rql query:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   790
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   791
          SET X rtype Y WHERE X eid  fromeid, T eid toeid
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   792
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   793
        without read security check but also all the burden of rql execution.
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   794
        You may use this in hooks when you know both eids of the relation you
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   795
        want to add.
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   796
        """
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   797
        self.add_relations([(rtype, [(fromeid,  toeid)])])
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   798
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   799
    @_open_only
9079
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   800
    def add_relations(self, relations):
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   801
        '''set many relation using a shortcut similar to the one in add_relation
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   802
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   803
        relations is a list of 2-uples, the first element of each
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   804
        2-uple is the rtype, and the second is a list of (fromeid,
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   805
        toeid) tuples
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   806
        '''
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   807
        edited_entities = {}
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   808
        relations_dict = {}
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   809
        with self.security_enabled(False, False):
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   810
            for rtype, eids in relations:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   811
                if self.vreg.schema[rtype].inlined:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   812
                    for fromeid, toeid in eids:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   813
                        if fromeid not in edited_entities:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   814
                            entity = self.entity_from_eid(fromeid)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   815
                            edited = EditedEntity(entity)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   816
                            edited_entities[fromeid] = edited
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   817
                        else:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   818
                            edited = edited_entities[fromeid]
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   819
                        edited.edited_attribute(rtype, toeid)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   820
                else:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   821
                    relations_dict[rtype] = eids
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   822
            self.repo.glob_add_relations(self, relations_dict)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   823
            for edited in edited_entities.itervalues():
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   824
                self.repo.glob_update_entity(self, edited)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   825
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   826
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   827
    @_open_only
9079
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   828
    def delete_relation(self, fromeid, rtype, toeid):
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   829
        """provide direct access to the repository method to delete a relation.
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   830
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   831
        This is equivalent to the following rql query:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   832
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   833
          DELETE X rtype Y WHERE X eid  fromeid, T eid toeid
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   834
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   835
        without read security check but also all the burden of rql execution.
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   836
        You may use this in hooks when you know both eids of the relation you
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   837
        want to delete.
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   838
        """
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   839
        with self.security_enabled(False, False):
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   840
            if self.vreg.schema[rtype].inlined:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   841
                entity = self.entity_from_eid(fromeid)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   842
                entity.cw_attr_cache[rtype] = None
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   843
                self.repo.glob_update_entity(self, entity, set((rtype,)))
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   844
            else:
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   845
                self.repo.glob_delete_relation(self, fromeid, rtype, toeid)
f8c8e79218e1 [connection] move relation management method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9078
diff changeset
   846
9077
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   847
    # relations cache handling #################################################
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   848
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   849
    @_open_only
9077
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   850
    def update_rel_cache_add(self, subject, rtype, object, symmetric=False):
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   851
        self._update_entity_rel_cache_add(subject, rtype, 'subject', object)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   852
        if symmetric:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   853
            self._update_entity_rel_cache_add(object, rtype, 'subject', subject)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   854
        else:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   855
            self._update_entity_rel_cache_add(object, rtype, 'object', subject)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   856
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   857
    @_open_only
9077
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   858
    def update_rel_cache_del(self, subject, rtype, object, symmetric=False):
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   859
        self._update_entity_rel_cache_del(subject, rtype, 'subject', object)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   860
        if symmetric:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   861
            self._update_entity_rel_cache_del(object, rtype, 'object', object)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   862
        else:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   863
            self._update_entity_rel_cache_del(object, rtype, 'object', subject)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   864
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   865
    @_open_only
9077
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   866
    def _update_entity_rel_cache_add(self, eid, rtype, role, targeteid):
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   867
        try:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   868
            entity = self.entity_cache(eid)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   869
        except KeyError:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   870
            return
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   871
        rcache = entity.cw_relation_cached(rtype, role)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   872
        if rcache is not None:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   873
            rset, entities = rcache
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   874
            rset = rset.copy()
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   875
            entities = list(entities)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   876
            rset.rows.append([targeteid])
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   877
            if not isinstance(rset.description, list): # else description not set
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   878
                rset.description = list(rset.description)
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
   879
            rset.description.append([self.entity_metas(targeteid)['type']])
9077
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   880
            targetentity = self.entity_from_eid(targeteid)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   881
            if targetentity.cw_rset is None:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   882
                targetentity.cw_rset = rset
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   883
                targetentity.cw_row = rset.rowcount
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   884
                targetentity.cw_col = 0
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   885
            rset.rowcount += 1
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   886
            entities.append(targetentity)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   887
            entity._cw_related_cache['%s_%s' % (rtype, role)] = (
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   888
                rset, tuple(entities))
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   889
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   890
    @_open_only
9077
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   891
    def _update_entity_rel_cache_del(self, eid, rtype, role, targeteid):
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   892
        try:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   893
            entity = self.entity_cache(eid)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   894
        except KeyError:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   895
            return
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   896
        rcache = entity.cw_relation_cached(rtype, role)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   897
        if rcache is not None:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   898
            rset, entities = rcache
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   899
            for idx, row in enumerate(rset.rows):
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   900
                if row[0] == targeteid:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   901
                    break
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   902
            else:
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   903
                # this may occurs if the cache has been filed by a hook
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   904
                # after the database update
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   905
                self.debug('cache inconsistency for %s %s %s %s', eid, rtype,
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   906
                           role, targeteid)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   907
                return
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   908
            rset = rset.copy()
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   909
            entities = list(entities)
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   910
            del rset.rows[idx]
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   911
            if isinstance(rset.description, list): # else description not set
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   912
                del rset.description[idx]
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   913
            del entities[idx]
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   914
            rset.rowcount -= 1
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   915
            entity._cw_related_cache['%s_%s' % (rtype, role)] = (
55a88fbfd39c [connection] move relation cache method to Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9076
diff changeset
   916
                rset, tuple(entities))
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
   917
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
   918
    # Tracking of entities added of removed in the transaction ##################
8785
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   919
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   920
    @_open_only
8785
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   921
    def deleted_in_transaction(self, eid):
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   922
        """return True if the entity of the given eid is being deleted in the
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   923
        current transaction
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   924
        """
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   925
        return eid in self.transaction_data.get('pendingeids', ())
8785
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   926
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   927
    @_open_only
8785
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   928
    def added_in_transaction(self, eid):
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   929
        """return True if the entity of the given eid is being created in the
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   930
        current transaction
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   931
        """
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
   932
        return eid in self.transaction_data.get('neweids', ())
8785
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   933
8786
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   934
    # Operation management ####################################################
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   935
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   936
    @_open_only
8786
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   937
    def add_operation(self, operation, index=None):
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   938
        """add an operation to be executed at the end of the transaction"""
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   939
        if index is None:
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   940
            self.pending_operations.append(operation)
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   941
        else:
c2bc0b804982 [session/transaction] move add operation in session code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8785
diff changeset
   942
            self.pending_operations.insert(index, operation)
8785
8f2786492369 [session/transaction] move entity life utility on transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8784
diff changeset
   943
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   944
    # Hooks control ###########################################################
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   945
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   946
    @_open_only
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   947
    def allow_all_hooks_but(self, *categories):
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   948
        return _hooks_control(self, HOOKS_ALLOW_ALL, *categories)
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   949
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   950
    @_open_only
9026
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   951
    def deny_all_hooks_but(self, *categories):
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   952
        return _hooks_control(self, HOOKS_DENY_ALL, *categories)
84c5b01ebb3e [connection] move hook control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9025
diff changeset
   953
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   954
    @_open_only
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   955
    def disable_hook_categories(self, *categories):
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   956
        """disable the given hook categories:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   957
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   958
        - on HOOKS_DENY_ALL mode, ensure those categories are not enabled
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   959
        - on HOOKS_ALLOW_ALL mode, ensure those categories are disabled
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   960
        """
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   961
        changes = set()
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   962
        self.pruned_hooks_cache.clear()
8789
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   963
        categories = set(categories)
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   964
        if self.hooks_mode is HOOKS_DENY_ALL:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   965
            enabledcats = self.enabled_hook_cats
8789
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   966
            changes = enabledcats & categories
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   967
            enabledcats -= changes # changes is small hence faster
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   968
        else:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   969
            disabledcats = self.disabled_hook_cats
8789
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   970
            changes = categories - disabledcats
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   971
            disabledcats |= changes # changes is small hence faster
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   972
        return tuple(changes)
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   973
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   974
    @_open_only
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   975
    def enable_hook_categories(self, *categories):
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   976
        """enable the given hook categories:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   977
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   978
        - on HOOKS_DENY_ALL mode, ensure those categories are enabled
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   979
        - on HOOKS_ALLOW_ALL mode, ensure those categories are not disabled
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   980
        """
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   981
        changes = set()
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   982
        self.pruned_hooks_cache.clear()
8789
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   983
        categories = set(categories)
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   984
        if self.hooks_mode is HOOKS_DENY_ALL:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   985
            enabledcats = self.enabled_hook_cats
8789
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   986
            changes = categories - enabledcats
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   987
            enabledcats |= changes # changes is small hence faster
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   988
        else:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   989
            disabledcats = self.disabled_hook_cats
8789
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   990
            changes = disabledcats & categories
465a87e6a89a [transaction] use set operation in the hook control code
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8788
diff changeset
   991
            disabledcats -= changes # changes is small hence faster
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   992
        return tuple(changes)
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   993
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
   994
    @_open_only
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   995
    def is_hook_category_activated(self, category):
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   996
        """return a boolean telling if the given category is currently activated
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   997
        or not
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   998
        """
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
   999
        if self.hooks_mode is HOOKS_DENY_ALL:
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1000
            return category in self.enabled_hook_cats
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1001
        return category not in self.disabled_hook_cats
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1002
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1003
    @_open_only
8788
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1004
    def is_hook_activated(self, hook):
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1005
        """return a boolean telling if the given hook class is currently
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1006
        activated or not
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1007
        """
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1008
        return self.is_hook_category_activated(hook.category)
194f1418bc7e [session/transaction] move hook management in transaction itself
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8787
diff changeset
  1009
8806
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1010
    # Security management #####################################################
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
  1011
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1012
    @_open_only
9027
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
  1013
    def security_enabled(self, read=None, write=None):
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
  1014
        return _security_enabled(self, read=read, write=write)
b6b96d61e055 [connection] move security control logic on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9026
diff changeset
  1015
8806
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1016
    @property
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1017
    @_open_only
8806
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1018
    def read_security(self):
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1019
        return self._read_security
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1020
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1021
    @read_security.setter
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1022
    @_open_only
8806
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1023
    def read_security(self, activated):
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1024
        self._read_security = activated
8ca4b323223c [session/transaction] move read_security subtlety in transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8805
diff changeset
  1025
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1026
    # undo support ############################################################
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1027
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1028
    @_open_only
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1029
    def ertype_supports_undo(self, ertype):
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1030
        return self.undo_actions and ertype not in NO_UNDO_TYPES
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1031
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1032
    @_open_only
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1033
    def transaction_uuid(self, set=True):
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
  1034
        uuid = self.transaction_data.get('tx_uuid')
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1035
        if set and uuid is None:
10264
d5403de0792b [server] use unicode wherever appropriate in transaction/undo related methods
Julien Cristau <julien.cristau@logilab.fr>
parents: 10171
diff changeset
  1036
            self.transaction_data['tx_uuid'] = uuid = unicode(uuid4().hex)
9075
8d36838ccb3e [connection] move last part of undo logic in connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9074
diff changeset
  1037
            self.repo.system_source.start_undoable_transaction(self, uuid)
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1038
        return uuid
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1039
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1040
    @_open_only
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1041
    def transaction_inc_action_counter(self):
9024
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
  1042
        num = self.transaction_data.setdefault('tx_action_count', 0) + 1
701b19785f1d [connection] reinstall cnx.data as cnx.transaction_data
pierre-yves
parents: 9023
diff changeset
  1043
        self.transaction_data['tx_action_count'] = num
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1044
        return num
9272
68744f5154c4 [server] fix a number of typos, mostly in docstrings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9267
diff changeset
  1045
8844
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1046
    # db-api like interface ###################################################
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1047
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1048
    @_open_only
8844
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1049
    def source_defs(self):
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1050
        return self.repo.source_defs()
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1051
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1052
    @deprecated('[3.19] use .entity_metas(eid) instead')
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
  1053
    @_with_cnx_set
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1054
    @_open_only
8844
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1055
    def describe(self, eid, asdict=False):
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1056
        """return a tuple (type, sourceuri, extid) for the entity with id <eid>"""
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1057
        etype, extid, source = self.repo.type_and_source_from_eid(eid, self)
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1058
        metas = {'type': etype, 'source': source, 'extid': extid}
8844
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1059
        if asdict:
10228
d8a208f7e3d1 [server/session] Fix typo "meta vs. metas" in describe()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 10059
diff changeset
  1060
            metas['asource'] = metas['source'] # XXX pre 3.19 client compat
d8a208f7e3d1 [server/session] Fix typo "meta vs. metas" in describe()
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 10059
diff changeset
  1061
            return metas
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1062
        return etype, source, extid
8844
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1063
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
  1064
    @_with_cnx_set
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1065
    @_open_only
9469
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1066
    def entity_metas(self, eid):
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1067
        """return a tuple (type, sourceuri, extid) for the entity with id <eid>"""
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1068
        etype, extid, source = self.repo.type_and_source_from_eid(eid, self)
032825bbacab [multi-sources-removal] Drop entities.source column
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9468
diff changeset
  1069
        return {'type': etype, 'source': source, 'extid': extid}
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1070
9086
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1071
    # core method #############################################################
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1072
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
  1073
    @_with_cnx_set
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1074
    @_open_only
10005
7769d0f61810 remove leftover pre 3.9 deprecation warnings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9979
diff changeset
  1075
    def execute(self, rql, kwargs=None, build_descr=True):
9086
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1076
        """db-api like method directly linked to the querier execute method.
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1077
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1078
        See :meth:`cubicweb.dbapi.Cursor.execute` documentation.
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1079
        """
9089
b4c12d2873f6 [connection] Connection.execute touch Session timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9088
diff changeset
  1080
        self._session_timestamp.touch()
9086
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1081
        rset = self._execute(self, rql, kwargs, build_descr)
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1082
        rset.req = self
9089
b4c12d2873f6 [connection] Connection.execute touch Session timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9088
diff changeset
  1083
        self._session_timestamp.touch()
9086
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1084
        return rset
1084843ab2cb [connection] move execute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9085
diff changeset
  1085
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1086
    @_open_only
9091
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1087
    def rollback(self, free_cnxset=True, reset_pool=None):
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1088
        """rollback the current transaction"""
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1089
        if reset_pool is not None:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1090
            warn('[3.13] use free_cnxset argument instead for reset_pool',
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1091
                 DeprecationWarning, stacklevel=2)
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1092
            free_cnxset = reset_pool
9684
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
  1093
        if self._cnxset_count != 0:
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
  1094
            # we are inside ensure_cnx_set, don't lose it
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
  1095
            free_cnxset = False
9091
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1096
        cnxset = self.cnxset
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1097
        if cnxset is None:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1098
            self.clear()
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1099
            self._session_timestamp.touch()
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1100
            self.debug('rollback transaction %s done (no db activity)', self.connectionid)
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1101
            return
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1102
        try:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1103
            # by default, operations are executed with security turned off
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1104
            with self.security_enabled(False, False):
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1105
                while self.pending_operations:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1106
                    try:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1107
                        operation = self.pending_operations.pop(0)
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1108
                        operation.handle_event('rollback_event')
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1109
                    except BaseException:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1110
                        self.critical('rollback error', exc_info=sys.exc_info())
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1111
                        continue
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1112
                cnxset.rollback()
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1113
                self.debug('rollback for transaction %s done', self.connectionid)
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1114
        finally:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1115
            self._session_timestamp.touch()
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1116
            if free_cnxset:
9495
0ae4e6d7ce2f [server/session] use _free_cnxset instead of free_cnxset to avoid warnings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9493
diff changeset
  1117
                self._free_cnxset(ignoremode=True)
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1118
            self.clear()
8844
168cf5ef21f8 [session/transaction] move multiple utility on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8843
diff changeset
  1119
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1120
    @_open_only
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1121
    def commit(self, free_cnxset=True, reset_pool=None):
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1122
        """commit the current session's transaction"""
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1123
        if reset_pool is not None:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1124
            warn('[3.13] use free_cnxset argument instead for reset_pool',
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1125
                 DeprecationWarning, stacklevel=2)
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1126
            free_cnxset = reset_pool
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1127
        if self.cnxset is None:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1128
            assert not self.pending_operations
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1129
            self.clear()
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1130
            self._session_timestamp.touch()
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1131
            self.debug('commit transaction %s done (no db activity)', self.connectionid)
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1132
            return
9684
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
  1133
        if self._cnxset_count != 0:
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
  1134
            # we are inside ensure_cnx_set, don't lose it
a6b084ea4c5b [server/session] make commit/rollback obey ensure_cnx_set
Julien Cristau <julien.cristau@logilab.fr>
parents: 9630
diff changeset
  1135
            free_cnxset = False
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1136
        cstate = self.commit_state
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1137
        if cstate == 'uncommitable':
9403
d81207fb9499 Fix a couple merge errors
Julien Cristau <julien.cristau@logilab.fr>
parents: 9402
diff changeset
  1138
            raise QueryError('transaction must be rolled back')
10059
dab538127d72 [session] don't silently ignore commits
Julien Cristau <julien.cristau@logilab.fr>
parents: 9979
diff changeset
  1139
        if cstate == 'precommit':
dab538127d72 [session] don't silently ignore commits
Julien Cristau <julien.cristau@logilab.fr>
parents: 9979
diff changeset
  1140
            self.warn('calling commit in precommit makes no sense; ignoring commit')
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1141
            return
10059
dab538127d72 [session] don't silently ignore commits
Julien Cristau <julien.cristau@logilab.fr>
parents: 9979
diff changeset
  1142
        if cstate == 'postcommit':
dab538127d72 [session] don't silently ignore commits
Julien Cristau <julien.cristau@logilab.fr>
parents: 9979
diff changeset
  1143
            self.critical('postcommit phase is not allowed to write to the db; ignoring commit')
dab538127d72 [session] don't silently ignore commits
Julien Cristau <julien.cristau@logilab.fr>
parents: 9979
diff changeset
  1144
            return
dab538127d72 [session] don't silently ignore commits
Julien Cristau <julien.cristau@logilab.fr>
parents: 9979
diff changeset
  1145
        assert cstate is None
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1146
        # on rollback, an operation should have the following state
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1147
        # information:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1148
        # - processed by the precommit/commit event or not
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1149
        # - if processed, is it the failed operation
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1150
        debug = server.DEBUG & server.DBG_OPS
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1151
        try:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1152
            # by default, operations are executed with security turned off
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1153
            with self.security_enabled(False, False):
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1154
                processed = []
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1155
                self.commit_state = 'precommit'
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1156
                if debug:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1157
                    print self.commit_state, '*' * 20
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1158
                try:
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1159
                    with self.running_hooks_ops():
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1160
                        while self.pending_operations:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1161
                            operation = self.pending_operations.pop(0)
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1162
                            operation.processed = 'precommit'
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1163
                            processed.append(operation)
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1164
                            if debug:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1165
                                print operation
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1166
                            operation.handle_event('precommit_event')
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1167
                    self.pending_operations[:] = processed
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1168
                    self.debug('precommit transaction %s done', self.connectionid)
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1169
                except BaseException:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1170
                    # if error on [pre]commit:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1171
                    #
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1172
                    # * set .failed = True on the operation causing the failure
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1173
                    # * call revert<event>_event on processed operations
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1174
                    # * call rollback_event on *all* operations
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1175
                    #
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1176
                    # that seems more natural than not calling rollback_event
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1177
                    # for processed operations, and allow generic rollback
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1178
                    # instead of having to implements rollback, revertprecommit
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1179
                    # and revertcommit, that will be enough in mont case.
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1180
                    operation.failed = True
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1181
                    if debug:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1182
                        print self.commit_state, '*' * 20
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1183
                    with self.running_hooks_ops():
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1184
                        for operation in reversed(processed):
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1185
                            if debug:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1186
                                print operation
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1187
                            try:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1188
                                operation.handle_event('revertprecommit_event')
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1189
                            except BaseException:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1190
                                self.critical('error while reverting precommit',
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1191
                                              exc_info=True)
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1192
                    # XXX use slice notation since self.pending_operations is a
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1193
                    # read-only property.
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1194
                    self.pending_operations[:] = processed + self.pending_operations
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1195
                    self.rollback(free_cnxset)
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1196
                    raise
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1197
                self.cnxset.commit()
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1198
                self.commit_state = 'postcommit'
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1199
                if debug:
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1200
                    print self.commit_state, '*' * 20
10351
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1201
                with self.running_hooks_ops():
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1202
                    while self.pending_operations:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1203
                        operation = self.pending_operations.pop(0)
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1204
                        if debug:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1205
                            print operation
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1206
                        operation.processed = 'postcommit'
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1207
                        try:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1208
                            operation.handle_event('postcommit_event')
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1209
                        except BaseException:
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1210
                            self.critical('error while postcommit',
91e63306e277 [connection] replace .running_dbapi_query with .hooks_in_progress
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10347
diff changeset
  1211
                                          exc_info=sys.exc_info())
9092
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1212
                self.debug('postcommit transaction %s done', self.connectionid)
48d488dd3c51 [connection] move the commit method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9091
diff changeset
  1213
                return self.transaction_uuid(set=False)
9091
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1214
        finally:
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1215
            self._session_timestamp.touch()
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1216
            if free_cnxset:
9495
0ae4e6d7ce2f [server/session] use _free_cnxset instead of free_cnxset to avoid warnings
Julien Cristau <julien.cristau@logilab.fr>
parents: 9493
diff changeset
  1217
                self._free_cnxset(ignoremode=True)
9091
4a39f3f1f1d9 [connection] move the rollback method on Connection object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9090
diff changeset
  1218
            self.clear()
8812
52af67a2f0a5 [session/transaction] move most undo support into transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8811
diff changeset
  1219
8845
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1220
    # resource accessors ######################################################
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1221
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
  1222
    @_with_cnx_set
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1223
    @_open_only
9093
e2f88df79efd [connection] move call_service on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9092
diff changeset
  1224
    def call_service(self, regid, **kwargs):
9721
2f08bd4c813b [server/session] remove json dumps around call_service
Julien Cristau <julien.cristau@logilab.fr>
parents: 9707
diff changeset
  1225
        self.debug('calling service %s', regid)
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
  1226
        service = self.vreg['services'].select(regid, self, **kwargs)
9721
2f08bd4c813b [server/session] remove json dumps around call_service
Julien Cristau <julien.cristau@logilab.fr>
parents: 9707
diff changeset
  1227
        return service.call(**kwargs)
9093
e2f88df79efd [connection] move call_service on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9092
diff changeset
  1228
9098
5467fb901931 [connection] transparent cnx_set handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9095
diff changeset
  1229
    @_with_cnx_set
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1230
    @_open_only
8845
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1231
    def system_sql(self, sql, args=None, rollback_on_failure=True):
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1232
        """return a sql cursor on the system database"""
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1233
        if sql.split(None, 1)[0].upper() != 'SELECT':
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1234
            self.mode = 'write'
9463
d62e13eba033 [multi-sources-removal] Simplify ConnectionsSet internal structures and public methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9458
diff changeset
  1235
        source = self.repo.system_source
8845
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1236
        try:
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1237
            return source.doexec(self, sql, args, rollback=rollback_on_failure)
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1238
        except (source.OperationalError, source.InterfaceError):
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1239
            if not rollback_on_failure:
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1240
                raise
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1241
            source.warning("trying to reconnect")
9482
5b97e69f9c29 [server] fix TypeErrors
Julien Cristau <julien.cristau@logilab.fr>
parents: 9479
diff changeset
  1242
            self.cnxset.reconnect()
8845
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1243
            return source.doexec(self, sql, args, rollback=rollback_on_failure)
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1244
9112
c859c7cef346 [connection] enforce that a connection must be open to be used
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9110
diff changeset
  1245
    @_open_only
8845
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1246
    def rtype_eids_rdef(self, rtype, eidfrom, eidto):
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1247
        # use type_and_source_from_eid instead of type_from_eid for optimization
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1248
        # (avoid two extra methods call)
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1249
        subjtype = self.repo.type_and_source_from_eid(eidfrom, self)[0]
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1250
        objtype = self.repo.type_and_source_from_eid(eidto, self)[0]
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1251
        return self.vreg.schema.rschema(rtype).rdefs[(subjtype, objtype)]
667cc27e9d12 [session/transaction] move resource accessors on Transaction
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8844
diff changeset
  1252
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
  1253
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1254
def cnx_attr(attr_name, writable=False):
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1255
    """return a property to forward attribute access to connection.
8782
ee675f0a9612 [session] have a nice helper function to forward access to session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8781
diff changeset
  1256
ee675f0a9612 [session] have a nice helper function to forward access to session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8781
diff changeset
  1257
    This is to be used by session"""
8787
1b3b7284377f [session] allow writable tx_attr and use it for commit_state
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8786
diff changeset
  1258
    args = {}
9404
3e3e9b37e177 fix version number: we still target cw 3.19
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9403
diff changeset
  1259
    @deprecated('[3.19] use a Connection object instead')
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1260
    def attr_from_cnx(session):
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1261
        return getattr(session._cnx, attr_name)
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1262
    args['fget'] = attr_from_cnx
8787
1b3b7284377f [session] allow writable tx_attr and use it for commit_state
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8786
diff changeset
  1263
    if writable:
9404
3e3e9b37e177 fix version number: we still target cw 3.19
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9403
diff changeset
  1264
        @deprecated('[3.19] use a Connection object instead')
8787
1b3b7284377f [session] allow writable tx_attr and use it for commit_state
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8786
diff changeset
  1265
        def write_attr(session, value):
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1266
            return setattr(session._cnx, attr_name, value)
8787
1b3b7284377f [session] allow writable tx_attr and use it for commit_state
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8786
diff changeset
  1267
        args['fset'] = write_attr
1b3b7284377f [session] allow writable tx_attr and use it for commit_state
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8786
diff changeset
  1268
    return property(**args)
8782
ee675f0a9612 [session] have a nice helper function to forward access to session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8781
diff changeset
  1269
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1270
def cnx_meth(meth_name):
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1271
    """return a function forwarding calls to connection.
8783
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
  1272
c024365ac8ac [session/transaction] move entity cache management on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8782
diff changeset
  1273
    This is to be used by session"""
9404
3e3e9b37e177 fix version number: we still target cw 3.19
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9403
diff changeset
  1274
    @deprecated('[3.19] use a Connection object instead')
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1275
    def meth_from_cnx(session, *args, **kwargs):
9084
e8e4dfc97670 [server/session] ensure appobject obtained from the session are linked to the session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9083
diff changeset
  1276
        result = getattr(session._cnx, meth_name)(*args, **kwargs)
e8e4dfc97670 [server/session] ensure appobject obtained from the session are linked to the session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9083
diff changeset
  1277
        if getattr(result, '_cw', None) is not None:
e8e4dfc97670 [server/session] ensure appobject obtained from the session are linked to the session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9083
diff changeset
  1278
            result._cw = session
e8e4dfc97670 [server/session] ensure appobject obtained from the session are linked to the session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9083
diff changeset
  1279
        return result
9402
2c48c091b6a2 merge 3.18.0 in 3.19 branch
Julien Cristau <julien.cristau@logilab.fr>
parents: 9123 9396
diff changeset
  1280
    meth_from_cnx.__doc__ = getattr(Connection, meth_name).__doc__
9020
cb87e831c183 rename server.session.transaction into server.session.connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9016
diff changeset
  1281
    return meth_from_cnx
7350
c2452cd57026 [session] enhance session's transaction storage handling to fix cases where commit/rollback is done while in the context of hooks_control/security_enabled managers. Closes #1412648: commit or rollback during postcreate reset hooks control state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7349
diff changeset
  1282
9081
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1283
class Timestamp(object):
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1284
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1285
    def __init__(self):
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1286
        self.value = time()
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1287
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1288
    def touch(self):
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1289
        self.value = time()
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1290
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1291
    def __float__(self):
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1292
        return float(self.value)
7350
c2452cd57026 [session] enhance session's transaction storage handling to fix cases where commit/rollback is done while in the context of hooks_control/security_enabled managers. Closes #1412648: commit or rollback during postcreate reset hooks control state
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7349
diff changeset
  1293
4834
b718626a0e60 move hooks activation control on session object, so we can have a per transaction control. Added a new `hooks_control` context manager for usual modification of hooks activation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4767
diff changeset
  1294
10346
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1295
class Session(object):
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
  1296
    """Repository user session
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
  1297
9143
1890e0df68fa [book] fix sphinx documentation generation (closes #2991997)
Julien Cristau <julien.cristau@logilab.fr>
parents: 8999
diff changeset
  1298
    This ties all together:
8760
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
  1299
     * session id,
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
  1300
     * user,
17994bf95d6a [doc] update Session documentation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8694
diff changeset
  1301
     * other session data.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1302
    """
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
  1303
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1304
    def __init__(self, user, repo, cnxprops=None, _id=None):
9122
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
  1305
        self.sessionid = _id or make_uid(unormalize(user.login).encode('UTF8'))
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
  1306
        self.user = user # XXX repoapi: deprecated and store only a login.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1307
        self.repo = repo
10346
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1308
        self.vreg = repo.vreg
9081
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1309
        self._timestamp = Timestamp()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1310
        self.data = {}
10346
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1311
        self.closed = False
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1312
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1313
    def close(self):
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1314
        self.closed = True
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1315
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1316
    def __enter__(self):
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1317
        return self
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1318
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1319
    def __exit__(self, *args):
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1320
        pass
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
  1321
4703
4e803c30b7db [session] user.login is usually an unicode string, so implements __unicode__ instead of __str__
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4533
diff changeset
  1322
    def __unicode__(self):
8669
62213a34726e [db-api/configuration] simplify db-api and configuration so that all the connection information is in the repository url, closes #2521848
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8626
diff changeset
  1323
        return '<session %s (%s 0x%x)>' % (
9493
852f5ac90cd9 [server/session] session.id → session.sessionid
Julien Cristau <julien.cristau@logilab.fr>
parents: 9482
diff changeset
  1324
            unicode(self.user.login), self.sessionid, id(self))
10346
b926ff4ef4a8 [repoapi,session] remove all session-as-cnx backward compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10345
diff changeset
  1325
9081
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1326
    @property
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1327
    def timestamp(self):
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1328
        return float(self._timestamp)
2604
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
  1329
9049
9d62d53b49df [server/session] allow access to session id using sessionid
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9048
diff changeset
  1330
    @property
9630
e7dbc4f06a48 minor cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9629
diff changeset
  1331
    @deprecated('[3.19] session.id is deprecated, use session.sessionid')
9122
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
  1332
    def id(self):
1d109fb9c67c [session] deprecate all Connection related method on session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9121
diff changeset
  1333
        return self.sessionid
2604
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
  1334
9050
635862b48485 [server/session] add a login property
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9049
diff changeset
  1335
    @property
635862b48485 [server/session] add a login property
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9049
diff changeset
  1336
    def login(self):
635862b48485 [server/session] add a login property
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9049
diff changeset
  1337
        return self.user.login
8777
4e72b78ea5aa [session] split session creation from default session assignation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8776
diff changeset
  1338
9110
ed8b383d94fd [session] add a new_cnx factory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9109
diff changeset
  1339
    def new_cnx(self):
ed8b383d94fd [session] add a new_cnx factory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9109
diff changeset
  1340
        """Return a new Connection object linked to the session
8777
4e72b78ea5aa [session] split session creation from default session assignation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8776
diff changeset
  1341
9110
ed8b383d94fd [session] add a new_cnx factory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9109
diff changeset
  1342
        The returned Connection will *not* be managed by the Session.
ed8b383d94fd [session] add a new_cnx factory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9109
diff changeset
  1343
        """
ed8b383d94fd [session] add a new_cnx factory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9109
diff changeset
  1344
        return Connection(self)
ed8b383d94fd [session] add a new_cnx factory
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9109
diff changeset
  1345
9404
3e3e9b37e177 fix version number: we still target cw 3.19
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9403
diff changeset
  1346
    @deprecated('[3.19] use a Connection object instead')
8585
3f60f416dddb [dbapi] provide get_option_value over DBAPIRequest (closes #2515522)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8529
diff changeset
  1347
    def get_option_value(self, option, foreid=None):
9458
e2dfdd313dfe [multi-sources-removal] Drop foreid argument of repo.get_option_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9404
diff changeset
  1348
        if foreid is not None:
e2dfdd313dfe [multi-sources-removal] Drop foreid argument of repo.get_option_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9404
diff changeset
  1349
            warn('[3.19] foreid argument is deprecated', DeprecationWarning,
e2dfdd313dfe [multi-sources-removal] Drop foreid argument of repo.get_option_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9404
diff changeset
  1350
                 stacklevel=2)
e2dfdd313dfe [multi-sources-removal] Drop foreid argument of repo.get_option_value
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9404
diff changeset
  1351
        return self.repo.get_option_value(option)
5813
0b250d72fcfa [transaction w/ separated web/repo processes] the dbapi should explicitly specify a transaction id to avoid confusion when web server / repository run in separated processes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5802
diff changeset
  1352
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
  1353
    def _touch(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
  1354
        """update latest session usage timestamp and reset mode to read"""
9081
7c9a6dc4ee5d [session] use a rich object for timestamp
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9079
diff changeset
  1355
        self._timestamp.touch()
9082
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1356
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1357
    local_perm_cache = cnx_attr('local_perm_cache')
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1358
    @local_perm_cache.setter
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1359
    def local_perm_cache(self, value):
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1360
        #base class assign an empty dict:-(
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1361
        assert value == {}
a2c6d908edeb [connection] move local_perm_cache management on Connection
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9081
diff changeset
  1362
        pass
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1363
2855
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
  1364
    # deprecated ###############################################################
1d9be3dffa94 [repo] more deprecation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2840
diff changeset
  1365
9048
8481fc6aa6dd [server/session] Implement anonymous_session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9047
diff changeset
  1366
    @property
8481fc6aa6dd [server/session] Implement anonymous_session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9047
diff changeset
  1367
    def anonymous_session(self):
9979
9ccdb3751fbe [server] fix anonymous_user predicate in tests
Julien Cristau <julien.cristau@logilab.fr>
parents: 9934
diff changeset
  1368
        # XXX for now, anonymous_user only exists in webconfig (and testconfig).
9048
8481fc6aa6dd [server/session] Implement anonymous_session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9047
diff changeset
  1369
        # It will only be present inside all-in-one instance.
8481fc6aa6dd [server/session] Implement anonymous_session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9047
diff changeset
  1370
        # there is plan to move it down to global config.
9979
9ccdb3751fbe [server] fix anonymous_user predicate in tests
Julien Cristau <julien.cristau@logilab.fr>
parents: 9934
diff changeset
  1371
        if not hasattr(self.repo.config, 'anonymous_user'):
9ccdb3751fbe [server] fix anonymous_user predicate in tests
Julien Cristau <julien.cristau@logilab.fr>
parents: 9934
diff changeset
  1372
            # not a web or test config, no anonymous user
9ccdb3751fbe [server] fix anonymous_user predicate in tests
Julien Cristau <julien.cristau@logilab.fr>
parents: 9934
diff changeset
  1373
            return False
9ccdb3751fbe [server] fix anonymous_user predicate in tests
Julien Cristau <julien.cristau@logilab.fr>
parents: 9934
diff changeset
  1374
        return self.user.login == self.repo.config.anonymous_user()[0]
9048
8481fc6aa6dd [server/session] Implement anonymous_session
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9047
diff changeset
  1375
7502
e7190f7e850e [session] deprecates schema_rproperty in favor of more optimized rtype_eids_rdef which return the rdef (so reusable to gather other data)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7500
diff changeset
  1376
    @deprecated('[3.13] use getattr(session.rtype_eids_rdef(rtype, eidfrom, eidto), prop)')
e7190f7e850e [session] deprecates schema_rproperty in favor of more optimized rtype_eids_rdef which return the rdef (so reusable to gather other data)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7500
diff changeset
  1377
    def schema_rproperty(self, rtype, eidfrom, eidto, rprop):
e7190f7e850e [session] deprecates schema_rproperty in favor of more optimized rtype_eids_rdef which return the rdef (so reusable to gather other data)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7500
diff changeset
  1378
        return getattr(self.rtype_eids_rdef(rtype, eidfrom, eidto), rprop)
e7190f7e850e [session] deprecates schema_rproperty in favor of more optimized rtype_eids_rdef which return the rdef (so reusable to gather other data)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7500
diff changeset
  1379
7083
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7054
diff changeset
  1380
    # these are overridden by set_log_methods below
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7054
diff changeset
  1381
    # only defining here to prevent pylint from complaining
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7054
diff changeset
  1382
    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
b8e35cde46e9 help pylint by explicitely defining some attributes
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 7054
diff changeset
  1383
8765
9e9029ba2d4e [session] Move hook control constants out of the class
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8764
diff changeset
  1384
9e9029ba2d4e [session] Move hook control constants out of the class
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8764
diff changeset
  1385
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1386
class InternalManager(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1387
    """a manager user with all access rights used internally for task such as
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1388
    bootstrapping the repository or creating regular users according to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1389
    repository content
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1390
    """
10345
ef54ea75a642 [server] drop repo.internal_session and InternalSession
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
  1391
9479
f13fbab0c718 [server] Allow setting an InternalManager's preferred language
Julien Cristau <julien.cristau@logilab.fr>
parents: 9478
diff changeset
  1392
    def __init__(self, lang='en'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1393
        self.eid = -1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1394
        self.login = u'__internal_manager__'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1395
        self.properties = {}
9087
dd26b4f95f90 [server/session] better faking of user for InternalManager
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9086
diff changeset
  1396
        self.groups = set(['managers'])
9479
f13fbab0c718 [server] Allow setting an InternalManager's preferred language
Julien Cristau <julien.cristau@logilab.fr>
parents: 9478
diff changeset
  1397
        self.lang = lang
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1398
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1399
    def matching_groups(self, groups):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1400
        return 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1401
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1402
    def is_in_group(self, group):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1403
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1404
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1405
    def owns(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1406
        return True
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
  1407
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1408
    def property_value(self, key):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1409
        if key == 'ui.language':
9479
f13fbab0c718 [server] Allow setting an InternalManager's preferred language
Julien Cristau <julien.cristau@logilab.fr>
parents: 9478
diff changeset
  1410
            return self.lang
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1411
        return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1412
8563
d28ccecb7bf5 mock ``CWUser.prefered_language()`` on InternalManager objects.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8562
diff changeset
  1413
    def prefered_language(self, language=None):
d28ccecb7bf5 mock ``CWUser.prefered_language()`` on InternalManager objects.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8562
diff changeset
  1414
        # mock CWUser.prefered_language, mainly for testing purpose
d28ccecb7bf5 mock ``CWUser.prefered_language()`` on InternalManager objects.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8562
diff changeset
  1415
        return self.property_value('ui.language')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1416
8579
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1417
    # CWUser compat for notification ###########################################
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1418
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1419
    def name(self):
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1420
        return 'cubicweb'
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1421
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1422
    class _IEmailable:
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1423
        @staticmethod
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1424
        def get_email():
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1425
            return ''
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1426
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1427
    def cw_adapt_to(self, iface):
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1428
        if iface == 'IEmailable':
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1429
            return self._IEmailable
c4673bc11053 [req / session] drop is_internal_session (buggy) compat on base request by implementing necessary methods on internal manager
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8563
diff changeset
  1430
        return None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1431
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1432
from logging import getLogger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1433
from cubicweb import set_log_methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
  1434
set_log_methods(Session, getLogger('cubicweb.session'))
9021
d8806996ac01 [connection] add logging method on connection
pierre-yves
parents: 9020
diff changeset
  1435
set_log_methods(Connection, getLogger('cubicweb.session'))