252 |
252 |
253 @property |
253 @property |
254 def anonymous_session(self): |
254 def anonymous_session(self): |
255 return not self.cnx or self.cnx.anonymous_connection |
255 return not self.cnx or self.cnx.anonymous_connection |
256 |
256 |
|
257 def __repr__(self): |
|
258 return '<DBAPISession %r>' % self.sessionid |
257 |
259 |
258 class DBAPIRequest(RequestSessionBase): |
260 class DBAPIRequest(RequestSessionBase): |
259 |
261 |
260 def __init__(self, vreg, session=None): |
262 def __init__(self, vreg, session=None): |
261 super(DBAPIRequest, self).__init__(vreg) |
263 super(DBAPIRequest, self).__init__(vreg) |
290 user = self.cnx.user(self, {'lang': self.lang}) |
292 user = self.cnx.user(self, {'lang': self.lang}) |
291 if user is not None: |
293 if user is not None: |
292 self.user = user |
294 self.user = user |
293 self.set_entity_cache(user) |
295 self.set_entity_cache(user) |
294 |
296 |
295 def execute(self, *args, **kwargs): |
297 def execute(self, *args, **kwargs): # pylint: disable=E0202 |
296 """overriden when session is set. By default raise authentication error |
298 """overriden when session is set. By default raise authentication error |
297 so authentication is requested. |
299 so authentication is requested. |
298 """ |
300 """ |
299 raise AuthenticationError() |
301 raise AuthenticationError() |
300 |
302 |
301 def set_default_language(self, vreg): |
303 def set_default_language(self, vreg): |
302 try: |
304 try: |
303 self.lang = vreg.property_value('ui.language') |
305 self.lang = vreg.property_value('ui.language') |
304 except: # property may not be registered |
306 except Exception: # property may not be registered |
305 self.lang = 'en' |
307 self.lang = 'en' |
306 # use req.__ to translate a message without registering it to the catalog |
308 # use req.__ to translate a message without registering it to the catalog |
307 try: |
309 try: |
308 gettext, pgettext = self.translations[self.lang] |
310 gettext, pgettext = self.translations[self.lang] |
309 self._ = self.__ = gettext |
311 self._ = self.__ = gettext |
310 self.pgettext = pgettext |
312 self.pgettext = pgettext |
311 except KeyError: |
313 except KeyError: |
312 # this occurs usually during test execution |
314 # this occurs usually during test execution |
313 self._ = self.__ = unicode |
315 self._ = self.__ = unicode |
314 self.pgettext = lambda x, y: y |
316 self.pgettext = lambda x, y: unicode(y) |
315 self.debug('request default language: %s', self.lang) |
317 self.debug('request default language: %s', self.lang) |
316 |
318 |
317 # entities cache management ############################################### |
319 # entities cache management ############################################### |
318 |
320 |
319 def entity_cache(self, eid): |
321 def entity_cache(self, eid): |
345 DeprecationWarning, stacklevel=2) |
347 DeprecationWarning, stacklevel=2) |
346 return self.cnx.set_shared_data(key, value, txdata) |
348 return self.cnx.set_shared_data(key, value, txdata) |
347 |
349 |
348 # server session compat layer ############################################# |
350 # server session compat layer ############################################# |
349 |
351 |
350 def describe(self, eid): |
352 def describe(self, eid, asdict=False): |
351 """return a tuple (type, sourceuri, extid) for the entity with id <eid>""" |
353 """return a tuple (type, sourceuri, extid) for the entity with id <eid>""" |
352 return self.cnx.describe(eid) |
354 return self.cnx.describe(eid, asdict) |
353 |
355 |
354 def source_defs(self): |
356 def source_defs(self): |
355 """return the definition of sources used by the repository.""" |
357 """return the definition of sources used by the repository.""" |
356 return self.cnx.source_defs() |
358 return self.cnx.source_defs() |
357 |
359 |
481 return rset |
483 return rset |
482 |
484 |
483 def check_not_closed(func): |
485 def check_not_closed(func): |
484 def decorator(self, *args, **kwargs): |
486 def decorator(self, *args, **kwargs): |
485 if self._closed is not None: |
487 if self._closed is not None: |
486 raise ProgrammingError('Closed connection') |
488 raise ProgrammingError('Closed connection %s' % self.sessionid) |
487 return func(self, *args, **kwargs) |
489 return func(self, *args, **kwargs) |
488 return decorator |
490 return decorator |
489 |
491 |
490 class Connection(object): |
492 class Connection(object): |
491 """DB-API 2.0 compatible Connection object for CubicWeb |
493 """DB-API 2.0 compatible Connection object for CubicWeb |
530 def __del__(self): |
532 def __del__(self): |
531 """close the remote connection if necessary""" |
533 """close the remote connection if necessary""" |
532 if self._closed is None and self._close_on_del: |
534 if self._closed is None and self._close_on_del: |
533 try: |
535 try: |
534 self.close() |
536 self.close() |
535 except: |
537 except Exception: |
536 pass |
538 pass |
537 |
539 |
538 # connection initialization methods ######################################## |
540 # connection initialization methods ######################################## |
539 |
541 |
540 def load_appobjects(self, cubes=_MARKER, subpath=None, expand=True): |
542 def load_appobjects(self, cubes=_MARKER, subpath=None, expand=True): |
619 """raise `BadConnectionId` if the connection is no more valid, else |
621 """raise `BadConnectionId` if the connection is no more valid, else |
620 return its latest activity timestamp. |
622 return its latest activity timestamp. |
621 """ |
623 """ |
622 return self._repo.check_session(self.sessionid) |
624 return self._repo.check_session(self.sessionid) |
623 |
625 |
624 def _txid(self, cursor=None): # XXX could now handle various isolation level! |
626 def _txid(self, cursor=None): # pylint: disable=E0202 |
|
627 # XXX could now handle various isolation level! |
625 # return a dict as bw compat trick |
628 # return a dict as bw compat trick |
626 return {'txid': currentThread().getName()} |
629 return {'txid': currentThread().getName()} |
627 |
630 |
628 # session data methods ##################################################### |
631 # session data methods ##################################################### |
629 |
632 |
673 dereferenced and the option value retrieved from it. |
676 dereferenced and the option value retrieved from it. |
674 """ |
677 """ |
675 return self._repo.get_option_value(option, foreid) |
678 return self._repo.get_option_value(option, foreid) |
676 |
679 |
677 @check_not_closed |
680 @check_not_closed |
678 def describe(self, eid): |
681 def describe(self, eid, asdict=False): |
679 return self._repo.describe(self.sessionid, eid, **self._txid()) |
682 metas = self._repo.describe(self.sessionid, eid, **self._txid()) |
|
683 if len(metas) == 3: # backward compat |
|
684 metas = list(metas) |
|
685 metas.append(metas[1]) |
|
686 if asdict: |
|
687 return dict(zip(('type', 'source', 'extid', 'asource'), metas)) |
|
688 # XXX :-1 for cw compat, use asdict=True for full information |
|
689 return metas[:-1] |
680 |
690 |
681 # db-api like interface #################################################### |
691 # db-api like interface #################################################### |
682 |
692 |
683 @check_not_closed |
693 @check_not_closed |
684 def commit(self): |
694 def commit(self): |