equal
deleted
inserted
replaced
18 """DB-API 2.0 compliant module |
18 """DB-API 2.0 compliant module |
19 |
19 |
20 Take a look at http://www.python.org/peps/pep-0249.html |
20 Take a look at http://www.python.org/peps/pep-0249.html |
21 |
21 |
22 (most parts of this document are reported here in docstrings) |
22 (most parts of this document are reported here in docstrings) |
23 |
|
24 """ |
23 """ |
|
24 |
25 __docformat__ = "restructuredtext en" |
25 __docformat__ = "restructuredtext en" |
26 |
26 |
|
27 from threading import currentThread |
27 from logging import getLogger |
28 from logging import getLogger |
28 from time import time, clock |
29 from time import time, clock |
29 from itertools import count |
30 from itertools import count |
30 from warnings import warn |
31 from warnings import warn |
31 from os.path import join |
32 from os.path import join |
401 |
402 |
402 def close(self): |
403 def close(self): |
403 """no effect""" |
404 """no effect""" |
404 pass |
405 pass |
405 |
406 |
|
407 def _txid(self): |
|
408 return self.connection._txid(self) |
|
409 |
406 def execute(self, rql, args=None, eid_key=None, build_descr=True): |
410 def execute(self, rql, args=None, eid_key=None, build_descr=True): |
407 """execute a rql query, return resulting rows and their description in |
411 """execute a rql query, return resulting rows and their description in |
408 a :class:`~cubicweb.rset.ResultSet` object |
412 a :class:`~cubicweb.rset.ResultSet` object |
409 |
413 |
410 * `rql` should be an Unicode string or a plain ASCII string, containing |
414 * `rql` should be an Unicode string or a plain ASCII string, containing |
436 """ |
440 """ |
437 if eid_key is not None: |
441 if eid_key is not None: |
438 warn('[3.8] eid_key is deprecated, you can safely remove this argument', |
442 warn('[3.8] eid_key is deprecated, you can safely remove this argument', |
439 DeprecationWarning, stacklevel=2) |
443 DeprecationWarning, stacklevel=2) |
440 # XXX use named argument for build_descr in case repo is < 3.8 |
444 # XXX use named argument for build_descr in case repo is < 3.8 |
441 rset = self._repo.execute(self._sessid, rql, args, build_descr=build_descr) |
445 rset = self._repo.execute(self._sessid, rql, args, |
|
446 build_descr=build_descr, txid=self._txid()) |
442 rset.req = self.req |
447 rset.req = self.req |
443 return rset |
448 return rset |
444 |
449 |
445 |
450 |
446 class LogCursor(Cursor): |
451 class LogCursor(Cursor): |
490 if exc_type is None: |
495 if exc_type is None: |
491 self.commit() |
496 self.commit() |
492 else: |
497 else: |
493 self.rollback() |
498 self.rollback() |
494 return False #propagate the exception |
499 return False #propagate the exception |
|
500 |
|
501 def _txid(self, cursor=None): # XXX could now handle various isolation level! |
|
502 return currentThread().getName() |
495 |
503 |
496 def request(self): |
504 def request(self): |
497 return DBAPIRequest(self.vreg, DBAPISession(self)) |
505 return DBAPIRequest(self.vreg, DBAPISession(self)) |
498 |
506 |
499 def check(self): |
507 def check(self): |
626 pass |
634 pass |
627 |
635 |
628 def describe(self, eid): |
636 def describe(self, eid): |
629 if self._closed is not None: |
637 if self._closed is not None: |
630 raise ProgrammingError('Closed connection') |
638 raise ProgrammingError('Closed connection') |
631 return self._repo.describe(self.sessionid, eid) |
639 return self._repo.describe(self.sessionid, eid, txid=self._txid()) |
632 |
640 |
633 def close(self): |
641 def close(self): |
634 """Close the connection now (rather than whenever __del__ is called). |
642 """Close the connection now (rather than whenever __del__ is called). |
635 |
643 |
636 The connection will be unusable from this point forward; an Error (or |
644 The connection will be unusable from this point forward; an Error (or |
639 connection. Note that closing a connection without committing the |
647 connection. Note that closing a connection without committing the |
640 changes first will cause an implicit rollback to be performed. |
648 changes first will cause an implicit rollback to be performed. |
641 """ |
649 """ |
642 if self._closed: |
650 if self._closed: |
643 raise ProgrammingError('Connection is already closed') |
651 raise ProgrammingError('Connection is already closed') |
644 self._repo.close(self.sessionid) |
652 self._repo.close(self.sessionid, txid=self._txid()) |
645 del self._repo # necessary for proper garbage collection |
653 del self._repo # necessary for proper garbage collection |
646 self._closed = 1 |
654 self._closed = 1 |
647 |
655 |
648 def commit(self): |
656 def commit(self): |
649 """Commit pending transaction for this connection to the repository. |
657 """Commit pending transaction for this connection to the repository. |
653 |
661 |
654 If the transaction is undoable, a transaction id will be returned. |
662 If the transaction is undoable, a transaction id will be returned. |
655 """ |
663 """ |
656 if not self._closed is None: |
664 if not self._closed is None: |
657 raise ProgrammingError('Connection is already closed') |
665 raise ProgrammingError('Connection is already closed') |
658 return self._repo.commit(self.sessionid) |
666 return self._repo.commit(self.sessionid, txid=self._txid()) |
659 |
667 |
660 def rollback(self): |
668 def rollback(self): |
661 """This method is optional since not all databases provide transaction |
669 """This method is optional since not all databases provide transaction |
662 support. |
670 support. |
663 |
671 |
666 a connection without committing the changes first will cause an implicit |
674 a connection without committing the changes first will cause an implicit |
667 rollback to be performed. |
675 rollback to be performed. |
668 """ |
676 """ |
669 if not self._closed is None: |
677 if not self._closed is None: |
670 raise ProgrammingError('Connection is already closed') |
678 raise ProgrammingError('Connection is already closed') |
671 self._repo.rollback(self.sessionid) |
679 self._repo.rollback(self.sessionid, txid=self._txid()) |
672 |
680 |
673 def cursor(self, req=None): |
681 def cursor(self, req=None): |
674 """Return a new Cursor Object using the connection. |
682 """Return a new Cursor Object using the connection. |
675 |
683 |
676 On pyro connection, you should get cursor after calling if |
684 On pyro connection, you should get cursor after calling if |
707 * `public`: when additional filtering is provided, their are by default |
715 * `public`: when additional filtering is provided, their are by default |
708 only searched in 'public' actions, unless a `public` argument is given |
716 only searched in 'public' actions, unless a `public` argument is given |
709 and set to false. |
717 and set to false. |
710 """ |
718 """ |
711 txinfos = self._repo.undoable_transactions(self.sessionid, ueid, |
719 txinfos = self._repo.undoable_transactions(self.sessionid, ueid, |
|
720 txid=self._txid(), |
712 **actionfilters) |
721 **actionfilters) |
713 if req is None: |
722 if req is None: |
714 req = self.request() |
723 req = self.request() |
715 for txinfo in txinfos: |
724 for txinfo in txinfos: |
716 txinfo.req = req |
725 txinfo.req = req |
721 |
730 |
722 raise `NoSuchTransaction` if not found or if session's user is not |
731 raise `NoSuchTransaction` if not found or if session's user is not |
723 allowed (eg not in managers group and the transaction doesn't belong to |
732 allowed (eg not in managers group and the transaction doesn't belong to |
724 him). |
733 him). |
725 """ |
734 """ |
726 txinfo = self._repo.transaction_info(self.sessionid, txuuid) |
735 txinfo = self._repo.transaction_info(self.sessionid, txuuid, |
|
736 txid=self._txid()) |
727 if req is None: |
737 if req is None: |
728 req = self.request() |
738 req = self.request() |
729 txinfo.req = req |
739 txinfo.req = req |
730 return txinfo |
740 return txinfo |
731 |
741 |
737 |
747 |
738 raise `NoSuchTransaction` if the transaction is not found or if |
748 raise `NoSuchTransaction` if the transaction is not found or if |
739 session's user is not allowed (eg not in managers group and the |
749 session's user is not allowed (eg not in managers group and the |
740 transaction doesn't belong to him). |
750 transaction doesn't belong to him). |
741 """ |
751 """ |
742 return self._repo.transaction_actions(self.sessionid, txuuid, public) |
752 return self._repo.transaction_actions(self.sessionid, txuuid, public, |
|
753 txid=self._txid()) |
743 |
754 |
744 def undo_transaction(self, txuuid): |
755 def undo_transaction(self, txuuid): |
745 """Undo the given transaction. Return potential restoration errors. |
756 """Undo the given transaction. Return potential restoration errors. |
746 |
757 |
747 raise `NoSuchTransaction` if not found or if session's user is not |
758 raise `NoSuchTransaction` if not found or if session's user is not |
748 allowed (eg not in managers group and the transaction doesn't belong to |
759 allowed (eg not in managers group and the transaction doesn't belong to |
749 him). |
760 him). |
750 """ |
761 """ |
751 return self._repo.undo_transaction(self.sessionid, txuuid) |
762 return self._repo.undo_transaction(self.sessionid, txuuid, |
|
763 txid=self._txid()) |