server/session.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 16 Sep 2009 14:24:31 +0200
branch3.5
changeset 3240 8604a15995d1
parent 3198 d2f48d30e73e
child 3275 5247789df541
permissions -rw-r--r--
refactor so that rql rewriter may be used outside the server. Enhance it to be usable for RRQLExpression as well
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""Repository users' and internal' sessions.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1880
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1880
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
import sys
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
import threading
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
from time import time
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
2613
5e19c2bb370e R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2466
diff changeset
    14
from logilab.common.deprecation import deprecated
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 985
diff changeset
    15
from rql.nodes import VariableRef, Function, ETYPE_PYOBJ_MAP, etype_from_pyobj
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
from yams import BASE_TYPES
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    18
from cubicweb import RequestSessionMixIn, Binary, UnknownEid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
from cubicweb.dbapi import ConnectionProperties
940
15dcdc863965 fix imports : common.utils -> utils
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 746
diff changeset
    20
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
    21
from cubicweb.rqlrewrite import RQLRewriter
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
1016
26387b836099 use datetime instead of mx.DateTime
sylvain.thenault@logilab.fr
parents: 985
diff changeset
    23
ETYPE_PYOBJ_MAP[Binary] = 'Bytes'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
def is_final(rqlst, variable, args):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
    # try to find if this is a final var or not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
    for select in rqlst.children:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
        for sol in select.solutions:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
            etype = variable.get_type(sol, args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
            if etype is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
            if etype in BASE_TYPES:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
                return True
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    34
            return False
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
def _make_description(selected, args, solution):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
    """return a description for a result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
    description = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    for term in selected:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
        description.append(term.get_type(solution, args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
    return description
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
class Session(RequestSessionMixIn):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    """tie session id, user, connections pool and other session data all
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
    together
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
    """
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    48
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
    def __init__(self, user, repo, cnxprops=None, _id=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        super(Session, self).__init__(repo.vreg)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        self.id = _id or make_uid(user.login.encode('UTF8'))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        cnxprops = cnxprops or ConnectionProperties('inmemory')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
        self.user = user
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
        self.repo = repo
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        self.cnxtype = cnxprops.cnxtype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
        self.creation = time()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        self.timestamp = self.creation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
        self.is_internal_session = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        self.is_super_session = False
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
    60
        self.default_mode = 'read'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        # short cut to querier .execute method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        self._execute = repo.querier.execute
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        # shared data, used to communicate extra information between the client
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        # and the rql server
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
        self.data = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
        # i18n initialization
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
        self.set_language(cnxprops.lang)
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
    68
        # internals
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        self._threaddata = threading.local()
1880
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
    70
        self._threads_in_transaction = set()
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
    71
        self._closed = False
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    72
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
    73
    def __str__(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
    74
        return '<%ssession %s (%s 0x%x)>' % (self.cnxtype, self.user.login,
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
    75
                                             self.id, id(self))
2604
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    76
2630
b3f997bc8c26 R [session] property for quick access to repo.schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2623
diff changeset
    77
    @property
b3f997bc8c26 R [session] property for quick access to repo.schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2623
diff changeset
    78
    def schema(self):
b3f997bc8c26 R [session] property for quick access to repo.schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2623
diff changeset
    79
        return self.repo.schema
b3f997bc8c26 R [session] property for quick access to repo.schema
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2623
diff changeset
    80
3112
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    81
    def hijack_user(self, user):
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    82
        """return a fake request/session using specified user"""
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    83
        session = Session(user, self.repo)
3161
005f745315b0 [notification] should get actual session here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3112
diff changeset
    84
        session._threaddata = self.actual_session()._threaddata
3112
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    85
        return session
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    86
3197
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
    87
    def _super_call(self, __cb, *args, **kwargs):
2604
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    88
        if self.is_super_session:
3197
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
    89
            __cb(self, *args, **kwargs)
2604
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    90
            return
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    91
        self.is_super_session = True
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    92
        try:
3197
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
    93
            __cb(self, *args, **kwargs)
2604
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    94
        finally:
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    95
            self.is_super_session = False
6b55a2a81fd8 [R repo session] add_relation method use in hooks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2603
diff changeset
    96
3112
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    97
    def add_relation(self, fromeid, rtype, toeid):
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    98
        """provide direct access to the repository method to add a relation.
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
    99
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   100
        This is equivalent to the following rql query:
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   101
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   102
          SET X rtype Y WHERE X eid  fromeid, T eid toeid
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   103
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   104
        without read security check but also all the burden of rql execution.
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   105
        You may use this in hooks when you know both eids of the relation you
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   106
        want to add.
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   107
        """
3197
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   108
        if self.vreg.schema[rtype].inlined:
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   109
            entity = self.entity_from_eid(fromeid)
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   110
            entity[rtype] = toeid
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   111
            self._super_call(self.repo.glob_update_entity,
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   112
                             entity, set((rtype,)))
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   113
        else:
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   114
            self._super_call(self.repo.glob_add_relation,
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   115
                             fromeid, rtype, toeid)
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   116
3112
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   117
    def delete_relation(self, fromeid, rtype, toeid):
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   118
        """provide direct access to the repository method to delete a relation.
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   119
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   120
        This is equivalent to the following rql query:
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   121
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   122
          DELETE X rtype Y WHERE X eid  fromeid, T eid toeid
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   123
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   124
        without read security check but also all the burden of rql execution.
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   125
        You may use this in hooks when you know both eids of the relation you
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   126
        want to delete.
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   127
        """
3197
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   128
        if self.vreg.schema[rtype].inlined:
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   129
            entity = self.entity_from_eid(fromeid)
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   130
            entity[rtype] = None
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   131
            self._super_call(self.repo.glob_update_entity,
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   132
                             entity, set((rtype,)))
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   133
        else:
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   134
            self._super_call(self.repo.glob_delete_relation,
b27d19c0db1c [repo] take care of inlined relation in session.[add|delete]_relation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3196
diff changeset
   135
                             fromeid, rtype, toeid)
3112
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   136
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   137
    # relations cache handling #################################################
873202e181bb enhance notification mecanism: recipients may return user entities, which will be used to create a fake session so one can check security during notification if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3074
diff changeset
   138
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   139
    def update_rel_cache_add(self, subject, rtype, object, symetric=False):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   140
        self._update_entity_rel_cache_add(subject, rtype, 'subject', object)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   141
        if symetric:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   142
            self._update_entity_rel_cache_add(object, rtype, 'subject', subject)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   143
        else:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   144
            self._update_entity_rel_cache_add(object, rtype, 'object', subject)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   145
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   146
    def update_rel_cache_del(self, subject, rtype, object, symetric=False):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   147
        self._update_entity_rel_cache_del(subject, rtype, 'subject', object)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   148
        if symetric:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   149
            self._update_entity_rel_cache_del(object, rtype, 'object', object)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   150
        else:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   151
            self._update_entity_rel_cache_del(object, rtype, 'object', subject)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   152
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   153
    def _rel_cache(self, eid, rtype, role):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   154
        try:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   155
            entity = self.entity_cache(eid)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   156
        except KeyError:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   157
            return
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   158
        return entity.relation_cached(rtype, role)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   159
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   160
    def _update_entity_rel_cache_add(self, eid, rtype, role, targeteid):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   161
        rcache = self._rel_cache(eid, rtype, role)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   162
        if rcache is not None:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   163
            rset, entities = rcache
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   164
            rset.rows.append([targeteid])
2781
4e1ad9d6a3e7 [session cache] always append to description, turn it into a list if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2764
diff changeset
   165
            if not isinstance(rset.description, list): # else description not set
4e1ad9d6a3e7 [session cache] always append to description, turn it into a list if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2764
diff changeset
   166
                rset.description = list(rset.description)
4e1ad9d6a3e7 [session cache] always append to description, turn it into a list if necessary
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2764
diff changeset
   167
            rset.description.append([self.describe(targeteid)[0]])
3196
77936fa67ae6 [repo] set entity.rset & co when needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3161
diff changeset
   168
            targetentity = self.entity_from_eid(targeteid)
77936fa67ae6 [repo] set entity.rset & co when needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3161
diff changeset
   169
            if targetentity.rset is None:
77936fa67ae6 [repo] set entity.rset & co when needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3161
diff changeset
   170
                targetentity.rset = rset
77936fa67ae6 [repo] set entity.rset & co when needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3161
diff changeset
   171
                targetentity.row = rset.rowcount
77936fa67ae6 [repo] set entity.rset & co when needed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3161
diff changeset
   172
                targetentity.col = 0
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   173
            rset.rowcount += 1
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   174
            entities.append(targetentity)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   175
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   176
    def _update_entity_rel_cache_del(self, eid, rtype, role, targeteid):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   177
        rcache = self._rel_cache(eid, rtype, role)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   178
        if rcache is not None:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   179
            rset, entities = rcache
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   180
            for idx, row in enumerate(rset.rows):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   181
                if row[0] == targeteid:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   182
                    break
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   183
            else:
3074
141cfaac6b97 don't fail when trying to update relation cache for relation deletion, this may occurs regularly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2874
diff changeset
   184
                # this may occurs if the cache has been filed by a hook
141cfaac6b97 don't fail when trying to update relation cache for relation deletion, this may occurs regularly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2874
diff changeset
   185
                # after the database update
141cfaac6b97 don't fail when trying to update relation cache for relation deletion, this may occurs regularly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2874
diff changeset
   186
                self.debug('cache inconsistency for %s %s %s %s', eid, rtype,
141cfaac6b97 don't fail when trying to update relation cache for relation deletion, this may occurs regularly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2874
diff changeset
   187
                           role, targeteid)
141cfaac6b97 don't fail when trying to update relation cache for relation deletion, this may occurs regularly
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2874
diff changeset
   188
                return
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   189
            del rset.rows[idx]
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   190
            if isinstance(rset.description, list): # else description not set
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   191
                del rset.description[idx]
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   192
            del entities[idx]
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   193
            rset.rowcount -= 1
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   194
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   195
    # resource accessors ######################################################
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   197
    def actual_session(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   198
        """return the original parent session if any, else self"""
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   199
        return self
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   200
2623
e1f34b77290b oops, should have been in a earlier commit (give rollback_on_failure to doexec)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2616
diff changeset
   201
    def system_sql(self, sql, args=None, rollback_on_failure=True):
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   202
        """return a sql cursor on the system database"""
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   203
        if not sql.split(None, 1)[0].upper() == 'SELECT':
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   204
            self.mode = 'write'
2623
e1f34b77290b oops, should have been in a earlier commit (give rollback_on_failure to doexec)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2616
diff changeset
   205
        return self.pool.source('system').doexec(self, sql, args,
e1f34b77290b oops, should have been in a earlier commit (give rollback_on_failure to doexec)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2616
diff changeset
   206
                                                 rollback=rollback_on_failure)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   207
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
    def set_language(self, language):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        """i18n configuration for translation"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        vreg = self.vreg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        language = language or self.user.property_value('ui.language')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
            self._ = self.__ = vreg.config.translations[language]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
            language = vreg.property_value('ui.language')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
                self._ = self.__ = vreg.config.translations[language]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
                self._ = self.__ = unicode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        self.lang = language
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   221
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
    def change_property(self, prop, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        assert prop == 'lang' # this is the only one changeable property for now
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
        self.set_language(value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   226
    # connection management ###################################################
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   228
    def keep_pool_mode(self, mode):
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   229
        """set pool_mode, e.g. how the session will keep its pool:
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   230
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   231
        * if mode == 'write', the pool is freed after each ready query, but kept
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   232
          until the transaction's end (eg commit or rollback) when a write query
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   233
          is detected (eg INSERT/SET/DELETE queries)
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   234
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   235
        * if mode == 'transaction', the pool is only freed after the
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   236
          transaction's end
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   237
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   238
        notice that a repository has a limited set of pools, and a session has to
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   239
        wait for a free pool to run any rql query (unless it already has a pool
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   240
        set).
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   241
        """
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   242
        assert mode in ('transaction', 'write')
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   243
        if mode == 'transaction':
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   244
            self.default_mode = 'transaction'
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   245
        else: # mode == 'write'
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   246
            self.default_mode = 'read'
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   247
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   248
    def get_mode(self):
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   249
        return getattr(self._threaddata, 'mode', self.default_mode)
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   250
    def set_mode(self, value):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   251
        self._threaddata.mode = value
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   252
    mode = property(get_mode, set_mode,
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   253
                    doc='transaction mode (read/write/transaction), resetted to'
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   254
                    ' default_mode on commit / rollback')
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   255
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   256
    def get_commit_state(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   257
        return getattr(self._threaddata, 'commit_state', None)
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   258
    def set_commit_state(self, value):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   259
        self._threaddata.commit_state = value
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   260
    commit_state = property(get_commit_state, set_commit_state)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   261
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   262
    @property
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   263
    def pool(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   264
        """connections pool, set according to transaction mode for each query"""
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   265
        return getattr(self._threaddata, 'pool', None)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   266
2764
55579275a091 [session pool] dont check closed session when calling set_pool from super_session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2680
diff changeset
   267
    def set_pool(self, checkclosed=True):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        """the session need a pool to execute some queries"""
2764
55579275a091 [session pool] dont check closed session when calling set_pool from super_session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2680
diff changeset
   269
        if checkclosed and self._closed:
1880
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   270
            raise Exception('try to set pool on a closed session')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
        if self.pool is None:
2054
277e8d3b1154 fix potential race-condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   272
            # get pool first to avoid race-condition
2306
95da5d9f0870 give session to doexec so it's able to rollback the connection on unexpected error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2200
diff changeset
   273
            self._threaddata.pool = pool = self.repo._get_pool()
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   274
            try:
2306
95da5d9f0870 give session to doexec so it's able to rollback the connection on unexpected error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2200
diff changeset
   275
                pool.pool_set()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
            except:
2054
277e8d3b1154 fix potential race-condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   277
                self._threaddata.pool = None
2306
95da5d9f0870 give session to doexec so it's able to rollback the connection on unexpected error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2200
diff changeset
   278
                self.repo._free_pool(pool)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
                raise
1880
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   280
            self._threads_in_transaction.add(threading.currentThread())
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        return self._threaddata.pool
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   282
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   283
    def reset_pool(self, ignoremode=False):
2319
654decb099e3 typo, no error if thread isn't in running set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2306
diff changeset
   284
        """the session is no longer using its pool, at least for some time"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
        # pool may be none if no operation has been done since last commit
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
        # or rollback
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   287
        if self.pool is not None and (ignoremode or self.mode == 'read'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
            # even in read mode, we must release the current transaction
2055
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2054
diff changeset
   289
            pool = self.pool
2319
654decb099e3 typo, no error if thread isn't in running set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2306
diff changeset
   290
            try:
654decb099e3 typo, no error if thread isn't in running set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2306
diff changeset
   291
                self._threads_in_transaction.remove(threading.currentThread())
654decb099e3 typo, no error if thread isn't in running set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2306
diff changeset
   292
            except KeyError:
654decb099e3 typo, no error if thread isn't in running set
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2306
diff changeset
   293
                pass
2063
fe4278b50388 fix [re]set_pool prototype
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2055
diff changeset
   294
            pool.pool_reset()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
            self._threaddata.pool = None
2054
277e8d3b1154 fix potential race-condition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   296
            # free pool once everything is done to avoid race-condition
2055
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2054
diff changeset
   297
            self.repo._free_pool(pool)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   298
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   299
    def _touch(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   300
        """update latest session usage timestamp and reset mode to read"""
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   301
        self.timestamp = time()
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   302
        self.local_perm_cache.clear()
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   303
        self._threaddata.mode = self.default_mode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
    # shared data handling ###################################################
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   306
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
    def get_shared_data(self, key, default=None, pop=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
        """return value associated to `key` in session data"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
        if pop:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
            return self.data.pop(key, default)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
            return self.data.get(key, default)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   313
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
    def set_shared_data(self, key, value, querydata=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        """set value associated to `key` in session data"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
        if querydata:
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   317
            self.transaction_data[key] = value
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
            self.data[key] = value
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   320
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
    # request interface #######################################################
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   322
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
    def set_entity_cache(self, entity):
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   324
        # XXX session level caching may be a pb with multiple repository
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   325
        #     instances, but 1. this is probably not the only one :$ and 2. it
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   326
        #     may be an acceptable risk. Anyway we could activate it or not
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   327
        #     according to a configuration option
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   328
        try:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   329
            self.transaction_data['ecache'].setdefault(entity.eid, entity)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   330
        except KeyError:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   331
            self.transaction_data['ecache'] = ecache = {}
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   332
            ecache[entity.eid] = entity
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
    def entity_cache(self, eid):
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   335
        try:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   336
            return self.transaction_data['ecache'][eid]
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   337
        except:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   338
            raise
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   339
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   340
    def cached_entities(self):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   341
        return self.transaction_data.get('ecache', {}).values()
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   342
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   343
    def drop_entity_cache(self, eid=None):
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   344
        if eid is None:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   345
            self.transaction_data.pop('ecache', None)
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   346
        else:
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   347
            del self.transaction_data['ecache'][eid]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
    def base_url(self):
2466
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   350
        url = self.repo.config['base-url']
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   351
        if not url:
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   352
            try:
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   353
                url = self.repo.config.default_base_url()
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   354
            except AttributeError: # default_base_url() might not be available
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   355
                self.warning('missing base-url definition in server config')
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   356
                url = u''
c4ccfd38a542 [server] take a chance to grab base-url from all-in-one config if not specified explicitly
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2319
diff changeset
   357
        return url
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   358
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    def from_controller(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
        """return the id (string) of the controller issuing the request (no
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
        sense here, always return 'view')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
        return 'view'
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   364
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
    def source_defs(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
        return self.repo.source_defs()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
    def describe(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        """return a tuple (type, sourceuri, extid) for the entity with id <eid>"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
        return self.repo.type_and_source_from_eid(eid, self)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   371
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   372
    # db-api like interface ###################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
    def source_from_eid(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
        """return the source where the entity with id <eid> is located"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
        return self.repo.source_from_eid(eid, self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
    def decorate_rset(self, rset, propagate=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
        rset.vreg = self.vreg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
        rset.req = propagate and self or self.actual_session()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
    def super_session(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
            csession = self._threaddata.childsession
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        except AttributeError:
2874
acdd8d8c2cff [session] use isinstance instead of testing value of is_super_session since we hack it in the add_relation method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2781
diff changeset
   388
            if isinstance(self, (ChildSession, InternalSession)):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
                csession = self
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
                csession = ChildSession(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
            self._threaddata.childsession = csession
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
        # need shared pool set
2764
55579275a091 [session pool] dont check closed session when calling set_pool from super_session
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2680
diff changeset
   394
        self.set_pool(checkclosed=False)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
        return csession
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   396
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2630
diff changeset
   397
    def unsafe_execute(self, rql, kwargs=None, eid_key=None, build_descr=True,
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
                       propagate=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
        """like .execute but with security checking disabled (this method is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
        internal to the server, it's not part of the db-api)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
        if `propagate` is true, the super_session will be attached to the result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
        set instead of the parent session, hence further query done through
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
        entities fetched from this result set will bypass security as well
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
        return self.super_session.execute(rql, kwargs, eid_key, build_descr,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
                                          propagate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
    def cursor(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   411
        """return a rql cursor"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   412
        return self
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   413
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   414
    def execute(self, rql, kwargs=None, eid_key=None, build_descr=True,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   415
                propagate=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   416
        """db-api like method directly linked to the querier execute method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
        Becare that unlike actual cursor.execute, `build_descr` default to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
        false
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   421
        rset = self._execute(self, rql, kwargs, eid_key, build_descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
        return self.decorate_rset(rset, propagate)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   423
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   424
    def commit(self, reset_pool=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        """commit the current session's transaction"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
        if self.pool is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   427
            assert not self.pending_operations
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   428
            self.transaction_data.clear()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
            self._touch()
2200
25bb65dc4559 test fixes, all server tests ok, except unittest_migractions (due to inter-tests-side-effects...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2190
diff changeset
   430
            self.debug('commit session %s done (no db activity)', self.id)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
        if self.commit_state:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
        # on rollback, an operation should have the following state
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
        # information:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        # - processed by the precommit/commit event or not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        # - if processed, is it the failed operation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   438
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   439
            for trstate in ('precommit', 'commit'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
                processed = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
                self.commit_state = trstate
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
                    while self.pending_operations:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
                        operation = self.pending_operations.pop(0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
                        operation.processed = trstate
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
                        processed.append(operation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
                        operation.handle_event('%s_event' % trstate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
                    self.pending_operations[:] = processed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
                    self.debug('%s session %s done', trstate, self.id)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   450
                except:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
                    self.exception('error while %sing', trstate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
                    operation.failed = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
                    for operation in processed:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
                        operation.handle_event('revert%s_event' % trstate)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
                    self.rollback(reset_pool)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   456
                    raise
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   457
            self.pool.commit()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   458
        finally:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
            self._touch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   460
            self.commit_state = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   461
            self.pending_operations[:] = []
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   462
            self.transaction_data.clear()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   463
            if reset_pool:
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   464
                self.reset_pool(ignoremode=True)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   465
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
    def rollback(self, reset_pool=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
        """rollback the current session's transaction"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
        if self.pool is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
            assert not self.pending_operations
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   470
            self.transaction_data.clear()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
            self._touch()
2200
25bb65dc4559 test fixes, all server tests ok, except unittest_migractions (due to inter-tests-side-effects...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2190
diff changeset
   472
            self.debug('rollback session %s done (no db activity)', self.id)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
            while self.pending_operations:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
                try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
                    operation = self.pending_operations.pop(0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
                    operation.handle_event('rollback_event')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
                except:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
                    self.critical('rollback error', exc_info=sys.exc_info())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
            self.pool.rollback()
2188
3a57c8173290 * deprecate session.entity method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   483
            self.debug('rollback for session %s done', self.id)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
        finally:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
            self._touch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
            self.pending_operations[:] = []
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   487
            self.transaction_data.clear()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   488
            if reset_pool:
2570
80a996bb536d [repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2319
diff changeset
   489
                self.reset_pool(ignoremode=True)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   490
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   491
    def close(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
        """do not close pool on session close, since they are shared now"""
1880
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   493
        self._closed = True
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   494
        # copy since _threads_in_transaction maybe modified while waiting
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   495
        for thread in self._threads_in_transaction.copy():
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   496
            if thread is threading.currentThread():
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   497
                continue
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   498
            self.info('waiting for thread %s', thread)
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   499
            # do this loop/break instead of a simple join(10) in case thread is
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   500
            # the main thread (in which case it will be removed from
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   501
            # self._threads_in_transaction but still be alive...)
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   502
            for i in xrange(10):
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   503
                thread.join(1)
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   504
                if not (thread.isAlive() and
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   505
                        thread in self._threads_in_transaction):
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   506
                    break
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   507
            else:
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   508
                self.error('thread %s still alive after 10 seconds, will close '
293fe4b49e28 two in one: #343320: Logging out while deleting a CWUser blocks the cw server / #342692: ensure transaction state when Ctrl-C or other stop signal is received
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1660
diff changeset
   509
                           'session anyway', thread)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   510
        self.rollback()
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   511
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   512
    # transaction data/operations management ##################################
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   513
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   514
    @property
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   515
    def transaction_data(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   516
        try:
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   517
            return self._threaddata.transaction_data
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   518
        except AttributeError:
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   519
            self._threaddata.transaction_data = {}
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   520
            return self._threaddata.transaction_data
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   521
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   522
    @property
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   523
    def pending_operations(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   524
        try:
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   525
            return self._threaddata.pending_operations
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   526
        except AttributeError:
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   527
            self._threaddata.pending_operations = []
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   528
            return self._threaddata.pending_operations
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   529
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   530
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   531
    def add_operation(self, operation, index=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
        """add an observer"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
        assert self.commit_state != 'commit'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   534
        if index is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
            self.pending_operations.insert(index, operation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   536
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   537
            self.pending_operations.append(operation)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   538
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   539
    # querier helpers #########################################################
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   540
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   541
    @property
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   542
    def rql_rewriter(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   543
        try:
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   544
            return self._threaddata._rewriter
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   545
        except AttributeError:
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
   546
            self._threaddata._rewriter = RQLRewriter(self)
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   547
            return self._threaddata._rewriter
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   548
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   549
    def build_description(self, rqlst, args, result):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   550
        """build a description for a given result"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   551
        if len(rqlst.children) == 1 and len(rqlst.children[0].solutions) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
            # easy, all lines are identical
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
            selected = rqlst.children[0].selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   554
            solution = rqlst.children[0].solutions[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   555
            description = _make_description(selected, args, solution)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   556
            return [tuple(description)] * len(result)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
        # hard, delegate the work :o)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
        return self.manual_build_descr(rqlst, args, result)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   560
    def manual_build_descr(self, rqlst, args, result):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   561
        """build a description for a given result by analysing each row
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   562
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
        XXX could probably be done more efficiently during execution of query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
        # not so easy, looks for variable which changes from one solution
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
        # to another
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
        unstables = rqlst.get_variable_variables()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
        basedescription = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
        todetermine = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
        selected = rqlst.children[0].selection # sample selection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
        for i, term in enumerate(selected):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   572
            if isinstance(term, Function) and term.descr().rtype is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
                basedescription.append(term.get_type(term.descr().rtype, args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   574
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   575
            for vref in term.get_nodes(VariableRef):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   576
                if vref.name in unstables:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   577
                    basedescription.append(None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
                    todetermine.append( (i, is_final(rqlst, vref.variable, args)) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   581
                # sample etype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
                etype = rqlst.children[0].solutions[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
                basedescription.append(term.get_type(etype, args))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
        if not todetermine:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   585
            return [tuple(basedescription)] * len(result)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   586
        return self._build_descr(result, basedescription, todetermine)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   587
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   588
    def _build_descr(self, result, basedescription, todetermine):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   589
        description = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   590
        etype_from_eid = self.describe
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   591
        for row in result:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
            row_descr = basedescription
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   593
            for index, isfinal in todetermine:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   594
                value = row[index]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   595
                if value is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
                    # None value inserted by an outer join, no type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
                    row_descr[index] = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   598
                    continue
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   599
                if isfinal:
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   600
                    row_descr[index] = etype_from_pyobj(value)
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   601
                else:
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   602
                    try:
1169
52058e8a3af9 somewhat handle corrupted database when manually building a database
sylvain.thenault@logilab.fr
parents: 974
diff changeset
   603
                        row_descr[index] = etype_from_eid(value)[0]
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   604
                    except UnknownEid:
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   605
                        self.critical('wrong eid %s in repository, should check database' % value)
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   606
                        row_descr[index] = row[index] = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   607
            description.append(tuple(row_descr))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   608
        return description
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   609
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   610
    @deprecated("use vreg['etypes'].etype_class(etype)")
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   611
    def etype_class(self, etype):
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   612
        """return an entity class for the given entity type"""
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   613
        return self.vreg['etypes'].etype_class(etype)
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   614
2613
5e19c2bb370e R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2466
diff changeset
   615
    @deprecated('use direct access to session.transaction_data')
2182
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   616
    def query_data(self, key, default=None, setdefault=False, pop=False):
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   617
        if setdefault:
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   618
            assert not pop
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   619
            return self.transaction_data.setdefault(key, default)
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   620
        if pop:
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   621
            return self.transaction_data.pop(key, default)
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   622
        else:
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   623
            return self.transaction_data.get(key, default)
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   624
2613
5e19c2bb370e R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2466
diff changeset
   625
    @deprecated('use entity_from_eid(eid, etype=None)')
2182
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   626
    def entity(self, eid):
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   627
        """return a result set for the given eid"""
2680
66472d85d548 [R] use req.entity_from_eid
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   628
        return self.entity_from_eid(eid)
2182
488099333160 mark session.entity method as obsolete
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2100
diff changeset
   629
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   630
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   631
class ChildSession(Session):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   632
    """child (or internal) session are used to hijack the security system
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   633
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   634
    cnxtype = 'inmemory'
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   635
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   636
    def __init__(self, parent_session):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   637
        self.id = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   638
        self.is_internal_session = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   639
        self.is_super_session = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   640
        # session which has created this one
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   641
        self.parent_session = parent_session
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   642
        self.user = InternalManager()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   643
        self.repo = parent_session.repo
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   644
        self.vreg = parent_session.vreg
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   645
        self.data = parent_session.data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   646
        self.encoding = parent_session.encoding
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   647
        self.lang = parent_session.lang
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   648
        self._ = self.__ = parent_session._
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   649
        # short cut to querier .execute method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   650
        self._execute = self.repo.querier.execute
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   651
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   652
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   653
    def super_session(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   654
        return self
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   655
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   656
    def get_mode(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   657
        return self.parent_session.mode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   658
    def set_mode(self, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   659
        self.parent_session.set_mode(value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   660
    mode = property(get_mode, set_mode)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   661
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   662
    def get_commit_state(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   663
        return self.parent_session.commit_state
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   664
    def set_commit_state(self, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   665
        self.parent_session.set_commit_state(value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   666
    commit_state = property(get_commit_state, set_commit_state)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   667
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   668
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   669
    def pool(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   670
        return self.parent_session.pool
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   671
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   672
    def pending_operations(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   673
        return self.parent_session.pending_operations
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   674
    @property
2100
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   675
    def transaction_data(self):
89b825cdec74 simplify transaction data api, reorganize code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2063
diff changeset
   676
        return self.parent_session.transaction_data
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   677
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   678
    def set_pool(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   679
        """the session need a pool to execute some queries"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   680
        self.parent_session.set_pool()
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   681
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   682
    def reset_pool(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   683
        """the session has no longer using its pool, at least for some time
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   684
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   685
        self.parent_session.reset_pool()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   686
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   687
    def actual_session(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   688
        """return the original parent session if any, else self"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   689
        return self.parent_session
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   690
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   691
    def commit(self, reset_pool=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   692
        """commit the current session's transaction"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   693
        self.parent_session.commit(reset_pool)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   694
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   695
    def rollback(self, reset_pool=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   696
        """rollback the current session's transaction"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   697
        self.parent_session.rollback(reset_pool)
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   698
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   699
    def close(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   700
        """do not close pool on session close, since they are shared now"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   701
        self.rollback()
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   702
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   703
    def user_data(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   704
        """returns a dictionnary with this user's information"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   705
        return self.parent_session.user_data()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   706
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   707
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   708
class InternalSession(Session):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   709
    """special session created internaly by the repository"""
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   710
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   711
    def __init__(self, repo, cnxprops=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   712
        super(InternalSession, self).__init__(_IMANAGER, repo, cnxprops,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   713
                                              _id='internal')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   714
        self.cnxtype = 'inmemory'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   715
        self.is_internal_session = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   716
        self.is_super_session = True
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   717
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   718
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   719
    def super_session(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   720
        return self
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   721
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   722
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   723
class InternalManager(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   724
    """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
   725
    bootstrapping the repository or creating regular users according to
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   726
    repository content
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   727
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   728
    def __init__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   729
        self.eid = -1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   730
        self.login = u'__internal_manager__'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   731
        self.properties = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   732
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   733
    def matching_groups(self, groups):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   734
        return 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   735
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   736
    def is_in_group(self, group):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   737
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   738
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   739
    def owns(self, eid):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   740
        return True
1660
d1030dd9730b delete-trailing-whitespaces, missing import
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   741
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   742
    def has_permission(self, pname, contexteid=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   743
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   744
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   745
    def property_value(self, key):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   746
        if key == 'ui.language':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   747
            return 'en'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   748
        return None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   749
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
   750
_IMANAGER = InternalManager()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   751
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   752
from logging import getLogger
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   753
from cubicweb import set_log_methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   754
set_log_methods(Session, getLogger('cubicweb.session'))