equal
deleted
inserted
replaced
27 from logging import getLogger |
27 from logging import getLogger |
28 |
28 |
29 from six import text_type |
29 from six import text_type |
30 |
30 |
31 from logilab.common.deprecation import deprecated |
31 from logilab.common.deprecation import deprecated |
32 from logilab.common.textutils import unormalize |
|
33 from logilab.common.registry import objectify_predicate |
32 from logilab.common.registry import objectify_predicate |
34 |
33 |
35 from cubicweb import QueryError, ProgrammingError, schema, server |
34 from cubicweb import QueryError, ProgrammingError, schema, server |
36 from cubicweb import set_log_methods |
35 from cubicweb import set_log_methods |
37 from cubicweb.req import RequestSessionBase |
36 from cubicweb.req import RequestSessionBase |
38 from cubicweb.utils import make_uid |
|
39 from cubicweb.rqlrewrite import RQLRewriter |
37 from cubicweb.rqlrewrite import RQLRewriter |
40 from cubicweb.server.edition import EditedEntity |
38 from cubicweb.server.edition import EditedEntity |
41 |
39 |
42 |
40 |
43 NO_UNDO_TYPES = schema.SCHEMA_TYPES.copy() |
41 NO_UNDO_TYPES = schema.SCHEMA_TYPES.copy() |
174 def _open_only(func): |
172 def _open_only(func): |
175 """decorator for Connection method that check it is open""" |
173 """decorator for Connection method that check it is open""" |
176 @functools.wraps(func) |
174 @functools.wraps(func) |
177 def check_open(cnx, *args, **kwargs): |
175 def check_open(cnx, *args, **kwargs): |
178 if not cnx._open: |
176 if not cnx._open: |
179 raise ProgrammingError('Closed Connection: %s' |
177 raise ProgrammingError('Closed Connection: %s' % cnx) |
180 % cnx.connectionid) |
|
181 return func(cnx, *args, **kwargs) |
178 return func(cnx, *args, **kwargs) |
182 return check_open |
179 return check_open |
183 |
180 |
184 |
181 |
185 class Connection(RequestSessionBase): |
182 class Connection(RequestSessionBase): |
245 |
242 |
246 def __init__(self, session): |
243 def __init__(self, session): |
247 super(Connection, self).__init__(session.repo.vreg) |
244 super(Connection, self).__init__(session.repo.vreg) |
248 #: connection unique id |
245 #: connection unique id |
249 self._open = None |
246 self._open = None |
250 self.connectionid = '%s-%s' % (session.sessionid, uuid4().hex) |
|
251 self.session = session |
247 self.session = session |
252 self.sessionid = session.sessionid |
|
253 |
248 |
254 #: server.Repository object |
249 #: server.Repository object |
255 self.repo = session.repo |
250 self.repo = session.repo |
256 self.vreg = self.repo.vreg |
251 self.vreg = self.repo.vreg |
257 self._execute = self.repo.querier.execute |
252 self._execute = self.repo.querier.execute |
476 def set_entity_cache(self, entity): |
471 def set_entity_cache(self, entity): |
477 """Add `entity` to the connection entity cache""" |
472 """Add `entity` to the connection entity cache""" |
478 # XXX not using _open_only because before at creation time. _set_user |
473 # XXX not using _open_only because before at creation time. _set_user |
479 # call this function to cache the Connection user. |
474 # call this function to cache the Connection user. |
480 if entity.cw_etype != 'CWUser' and not self._open: |
475 if entity.cw_etype != 'CWUser' and not self._open: |
481 raise ProgrammingError('Closed Connection: %s' % self.connectionid) |
476 raise ProgrammingError('Closed Connection: %s' % self) |
482 ecache = self.transaction_data.setdefault('ecache', {}) |
477 ecache = self.transaction_data.setdefault('ecache', {}) |
483 ecache.setdefault(entity.eid, entity) |
478 ecache.setdefault(entity.eid, entity) |
484 |
479 |
485 @_open_only |
480 @_open_only |
486 def entity_cache(self, eid): |
481 def entity_cache(self, eid): |
776 operation.handle_event('rollback_event') |
771 operation.handle_event('rollback_event') |
777 except BaseException: |
772 except BaseException: |
778 self.critical('rollback error', exc_info=sys.exc_info()) |
773 self.critical('rollback error', exc_info=sys.exc_info()) |
779 continue |
774 continue |
780 cnxset.rollback() |
775 cnxset.rollback() |
781 self.debug('rollback for transaction %s done', self.connectionid) |
776 self.debug('rollback for transaction %s done', self) |
782 finally: |
777 finally: |
783 self.clear() |
778 self.clear() |
784 |
779 |
785 @_open_only |
780 @_open_only |
786 def commit(self, free_cnxset=None, reset_pool=None): |
781 def commit(self, free_cnxset=None, reset_pool=None): |
822 processed.append(operation) |
817 processed.append(operation) |
823 if debug: |
818 if debug: |
824 print(operation) |
819 print(operation) |
825 operation.handle_event('precommit_event') |
820 operation.handle_event('precommit_event') |
826 self.pending_operations[:] = processed |
821 self.pending_operations[:] = processed |
827 self.debug('precommit transaction %s done', self.connectionid) |
822 self.debug('precommit transaction %s done', self) |
828 except BaseException: |
823 except BaseException: |
829 # if error on [pre]commit: |
824 # if error on [pre]commit: |
830 # |
825 # |
831 # * set .failed = True on the operation causing the failure |
826 # * set .failed = True on the operation causing the failure |
832 # * call revert<event>_event on processed operations |
827 # * call revert<event>_event on processed operations |
866 try: |
861 try: |
867 operation.handle_event('postcommit_event') |
862 operation.handle_event('postcommit_event') |
868 except BaseException: |
863 except BaseException: |
869 self.critical('error while postcommit', |
864 self.critical('error while postcommit', |
870 exc_info=sys.exc_info()) |
865 exc_info=sys.exc_info()) |
871 self.debug('postcommit transaction %s done', self.connectionid) |
866 self.debug('postcommit transaction %s done', self) |
872 return self.transaction_uuid(set=False) |
867 return self.transaction_uuid(set=False) |
873 finally: |
868 finally: |
874 self.clear() |
869 self.clear() |
875 |
870 |
876 # resource accessors ###################################################### |
871 # resource accessors ###################################################### |
928 * user, |
923 * user, |
929 * other session data. |
924 * other session data. |
930 """ |
925 """ |
931 |
926 |
932 def __init__(self, user, repo, _id=None): |
927 def __init__(self, user, repo, _id=None): |
933 self.sessionid = _id or make_uid(unormalize(user.login)) |
|
934 self.user = user # XXX repoapi: deprecated and store only a login. |
928 self.user = user # XXX repoapi: deprecated and store only a login. |
935 self.repo = repo |
929 self.repo = repo |
936 self.data = {} |
930 self.data = {} |
937 |
931 |
938 def __unicode__(self): |
932 def __unicode__(self): |
939 return '<session %s (%s 0x%x)>' % ( |
933 return '<session %s (0x%x)>' % ( |
940 unicode(self.user.login), self.sessionid, id(self)) |
934 unicode(self.user.login), id(self)) |
941 |
|
942 @property |
|
943 @deprecated('[3.19] session.id is deprecated, use session.sessionid') |
|
944 def id(self): |
|
945 return self.sessionid |
|
946 |
935 |
947 @property |
936 @property |
948 def login(self): |
937 def login(self): |
949 return self.user.login |
938 return self.user.login |
950 |
939 |