--- a/server/session.py Wed Jun 10 23:29:37 2009 +0200
+++ b/server/session.py Thu Jun 11 19:04:20 2009 +0200
@@ -11,6 +11,7 @@
import threading
from time import time
+from logilab.common.deprecation import obsolete
from rql.nodes import VariableRef, Function, ETYPE_PYOBJ_MAP, etype_from_pyobj
from yams import BASE_TYPES
@@ -65,54 +66,35 @@
self.data = {}
# i18n initialization
self.set_language(cnxprops.lang)
+ # internals
self._threaddata = threading.local()
self._threads_in_transaction = set()
self._closed = False
- def get_mode(self):
- return getattr(self._threaddata, 'mode', 'read')
- def set_mode(self, value):
- self._threaddata.mode = value
- # transaction mode (read/write), resetted to read on commit / rollback
- mode = property(get_mode, set_mode)
+ def __str__(self):
+ return '<%ssession %s (%s 0x%x)>' % (self.cnxtype, self.user.login,
+ self.id, id(self))
+ # resource accessors ######################################################
- def get_commit_state(self):
- return getattr(self._threaddata, 'commit_state', None)
- def set_commit_state(self, value):
- self._threaddata.commit_state = value
- commit_state = property(get_commit_state, set_commit_state)
-
- # set according to transaction mode for each query
- @property
- def pool(self):
- return getattr(self._threaddata, 'pool', None)
+ def actual_session(self):
+ """return the original parent session if any, else self"""
+ return self
- # pending transaction operations
- @property
- def pending_operations(self):
- try:
- return self._threaddata.pending_operations
- except AttributeError:
- self._threaddata.pending_operations = []
- return self._threaddata.pending_operations
+ def etype_class(self, etype):
+ """return an entity class for the given entity type"""
+ return self.vreg.etype_class(etype)
+
+ def entity(self, eid):
+ """return a result set for the given eid"""
+ return self.eid_rset(eid).get_entity(0, 0)
- # rql rewriter
- @property
- def rql_rewriter(self):
- try:
- return self._threaddata._rewriter
- except AttributeError:
- self._threaddata._rewriter = RQLRewriter(self.repo.querier, self)
- return self._threaddata._rewriter
-
- # transaction queries data
- @property
- def _query_data(self):
- try:
- return self._threaddata._query_data
- except AttributeError:
- self._threaddata._query_data = {}
- return self._threaddata._query_data
+ def system_sql(self, sql, args=None):
+ """return a sql cursor on the system database"""
+ if not sql.split(None, 1)[0].upper() == 'SELECT':
+ self.mode = 'write'
+ cursor = self.pool['system']
+ self.pool.source('system').doexec(cursor, sql, args)
+ return cursor
def set_language(self, language):
"""i18n configuration for translation"""
@@ -132,24 +114,26 @@
assert prop == 'lang' # this is the only one changeable property for now
self.set_language(value)
- def __str__(self):
- return '<%ssession %s (%s 0x%x)>' % (self.cnxtype, self.user.login,
- self.id, id(self))
+ # connection management ###################################################
- def etype_class(self, etype):
- """return an entity class for the given entity type"""
- return self.vreg.etype_class(etype)
+ def get_mode(self):
+ return getattr(self._threaddata, 'mode', 'read')
+ def set_mode(self, value):
+ self._threaddata.mode = value
+ mode = property(get_mode, set_mode,
+ doc='transaction mode (read/write), resetted to read on '
+ 'commit / rollback')
- def entity(self, eid):
- """return a result set for the given eid"""
- return self.eid_rset(eid).get_entity(0, 0)
+ def get_commit_state(self):
+ return getattr(self._threaddata, 'commit_state', None)
+ def set_commit_state(self, value):
+ self._threaddata.commit_state = value
+ commit_state = property(get_commit_state, set_commit_state)
- def _touch(self):
- """update latest session usage timestamp and reset mode to read
- """
- self.timestamp = time()
- self.local_perm_cache.clear()
- self._threaddata.mode = 'read'
+ @property
+ def pool(self):
+ """connections pool, set according to transaction mode for each query"""
+ return getattr(self._threaddata, 'pool', None)
def set_pool(self):
"""the session need a pool to execute some queries"""
@@ -168,8 +152,7 @@
return self._threaddata.pool
def reset_pool(self):
- """the session has no longer using its pool, at least for some time
- """
+ """the session has no longer using its pool, at least for some time"""
# pool may be none if no operation has been done since last commit
# or rollback
if self.pool is not None and self.mode == 'read':
@@ -181,17 +164,11 @@
# free pool once everything is done to avoid race-condition
self.repo._free_pool(pool)
- def system_sql(self, sql, args=None):
- """return a sql cursor on the system database"""
- if not sql.split(None, 1)[0].upper() == 'SELECT':
- self.mode = 'write'
- cursor = self.pool['system']
- self.pool.source('system').doexec(cursor, sql, args)
- return cursor
-
- def actual_session(self):
- """return the original parent session if any, else self"""
- return self
+ def _touch(self):
+ """update latest session usage timestamp and reset mode to read"""
+ self.timestamp = time()
+ self.local_perm_cache.clear()
+ self._threaddata.mode = 'read'
# shared data handling ###################################################
@@ -205,7 +182,7 @@
def set_shared_data(self, key, value, querydata=False):
"""set value associated to `key` in session data"""
if querydata:
- self.set_query_data(key, value)
+ self.transaction_data[key] = value
else:
self.data[key] = value
@@ -291,7 +268,7 @@
"""commit the current session's transaction"""
if self.pool is None:
assert not self.pending_operations
- self._query_data.clear()
+ self.transaction_data.clear()
self._touch()
return
if self.commit_state:
@@ -324,7 +301,7 @@
self._touch()
self.commit_state = None
self.pending_operations[:] = []
- self._query_data.clear()
+ self.transaction_data.clear()
if reset_pool:
self.reset_pool()
@@ -332,7 +309,7 @@
"""rollback the current session's transaction"""
if self.pool is None:
assert not self.pending_operations
- self._query_data.clear()
+ self.transaction_data.clear()
self._touch()
return
try:
@@ -347,7 +324,7 @@
finally:
self._touch()
self.pending_operations[:] = []
- self._query_data.clear()
+ self.transaction_data.clear()
if reset_pool:
self.reset_pool()
@@ -374,20 +351,32 @@
# transaction data/operations management ##################################
- def add_query_data(self, key, value):
- self._query_data.setdefault(key, []).append(value)
+ @property
+ def transaction_data(self):
+ try:
+ return self._threaddata.transaction_data
+ except AttributeError:
+ self._threaddata.transaction_data = {}
+ return self._threaddata.transaction_data
- def set_query_data(self, key, value):
- self._query_data[key] = value
-
+ @obsolete('use direct access to session.transaction_data')
def query_data(self, key, default=None, setdefault=False, pop=False):
if setdefault:
assert not pop
- return self._query_data.setdefault(key, default)
+ return self.transaction_data.setdefault(key, default)
if pop:
- return self._query_data.pop(key, default)
+ return self.transaction_data.pop(key, default)
else:
- return self._query_data.get(key, default)
+ return self.transaction_data.get(key, default)
+
+ @property
+ def pending_operations(self):
+ try:
+ return self._threaddata.pending_operations
+ except AttributeError:
+ self._threaddata.pending_operations = []
+ return self._threaddata.pending_operations
+
def add_operation(self, operation, index=None):
"""add an observer"""
@@ -399,6 +388,14 @@
# querier helpers #########################################################
+ @property
+ def rql_rewriter(self):
+ try:
+ return self._threaddata._rewriter
+ except AttributeError:
+ self._threaddata._rewriter = RQLRewriter(self.repo.querier, self)
+ return self._threaddata._rewriter
+
def build_description(self, rqlst, args, result):
"""build a description for a given result"""
if len(rqlst.children) == 1 and len(rqlst.children[0].solutions) == 1:
@@ -505,8 +502,8 @@
def pending_operations(self):
return self.parent_session.pending_operations
@property
- def _query_data(self):
- return self.parent_session._query_data
+ def transaction_data(self):
+ return self.parent_session.transaction_data
def set_pool(self):
"""the session need a pool to execute some queries"""