579 # commit session at this point in case write operation has been done |
579 # commit session at this point in case write operation has been done |
580 # during `session_open` hooks |
580 # during `session_open` hooks |
581 session.commit() |
581 session.commit() |
582 return session.id |
582 return session.id |
583 |
583 |
584 def execute(self, sessionid, rqlstring, args=None, build_descr=True): |
584 def execute(self, sessionid, rqlstring, args=None, build_descr=True, |
|
585 txid=None): |
585 """execute a RQL query |
586 """execute a RQL query |
586 |
587 |
587 * rqlstring should be an unicode string or a plain ascii string |
588 * rqlstring should be an unicode string or a plain ascii string |
588 * args the optional parameters used in the query |
589 * args the optional parameters used in the query |
589 * build_descr is a flag indicating if the description should be |
590 * build_descr is a flag indicating if the description should be |
590 built on select queries |
591 built on select queries |
591 """ |
592 """ |
592 session = self._get_session(sessionid, setpool=True) |
593 session = self._get_session(sessionid, setpool=True, txid=txid) |
593 try: |
594 try: |
594 try: |
595 try: |
595 rset = self.querier.execute(session, rqlstring, args, |
596 rset = self.querier.execute(session, rqlstring, args, |
596 build_descr) |
597 build_descr) |
597 # NOTE: the web front will (re)build it when needed |
598 # NOTE: the web front will (re)build it when needed |
615 self.exception('unexpected error while executing %s with %s', rqlstring, args) |
616 self.exception('unexpected error while executing %s with %s', rqlstring, args) |
616 raise |
617 raise |
617 finally: |
618 finally: |
618 session.reset_pool() |
619 session.reset_pool() |
619 |
620 |
620 def describe(self, sessionid, eid): |
621 def describe(self, sessionid, eid, txid=None): |
621 """return a tuple (type, source, extid) for the entity with id <eid>""" |
622 """return a tuple (type, source, extid) for the entity with id <eid>""" |
622 session = self._get_session(sessionid, setpool=True) |
623 session = self._get_session(sessionid, setpool=True, txid=txid) |
623 try: |
624 try: |
624 return self.type_and_source_from_eid(eid, session) |
625 return self.type_and_source_from_eid(eid, session) |
625 finally: |
626 finally: |
626 session.reset_pool() |
627 session.reset_pool() |
627 |
628 |
643 repository side. |
644 repository side. |
644 """ |
645 """ |
645 session = self._get_session(sessionid, setpool=False) |
646 session = self._get_session(sessionid, setpool=False) |
646 session.set_shared_data(key, value, querydata) |
647 session.set_shared_data(key, value, querydata) |
647 |
648 |
648 def commit(self, sessionid): |
649 def commit(self, sessionid, txid=None): |
649 """commit transaction for the session with the given id""" |
650 """commit transaction for the session with the given id""" |
650 self.debug('begin commit for session %s', sessionid) |
651 self.debug('begin commit for session %s', sessionid) |
651 try: |
652 try: |
652 return self._get_session(sessionid).commit() |
653 session = self._get_session(sessionid) |
|
654 session.set_tx_data(txid) |
|
655 return session.commit() |
653 except (ValidationError, Unauthorized): |
656 except (ValidationError, Unauthorized): |
654 raise |
657 raise |
655 except: |
658 except: |
656 self.exception('unexpected error') |
659 self.exception('unexpected error') |
657 raise |
660 raise |
658 |
661 |
659 def rollback(self, sessionid): |
662 def rollback(self, sessionid, txid=None): |
660 """commit transaction for the session with the given id""" |
663 """commit transaction for the session with the given id""" |
661 self.debug('begin rollback for session %s', sessionid) |
664 self.debug('begin rollback for session %s', sessionid) |
662 try: |
665 try: |
663 self._get_session(sessionid).rollback() |
666 session = self._get_session(sessionid) |
|
667 session.set_tx_data(txid) |
|
668 session.rollback() |
664 except: |
669 except: |
665 self.exception('unexpected error') |
670 self.exception('unexpected error') |
666 raise |
671 raise |
667 |
672 |
668 def close(self, sessionid, checkshuttingdown=True): |
673 def close(self, sessionid, txid=None, checkshuttingdown=True): |
669 """close the session with the given id""" |
674 """close the session with the given id""" |
670 session = self._get_session(sessionid, setpool=True, |
675 session = self._get_session(sessionid, setpool=True, txid=txid, |
671 checkshuttingdown=checkshuttingdown) |
676 checkshuttingdown=checkshuttingdown) |
672 # operation uncommited before close are rollbacked before hook is called |
677 # operation uncommited before close are rollbacked before hook is called |
673 session.rollback() |
678 session.rollback(reset_pool=False) |
674 self.hm.call_hooks('session_close', session) |
679 self.hm.call_hooks('session_close', session) |
675 # commit session at this point in case write operation has been done |
680 # commit session at this point in case write operation has been done |
676 # during `session_close` hooks |
681 # during `session_close` hooks |
677 session.commit() |
682 session.commit() |
678 session.close() |
683 session.close() |
699 """ |
704 """ |
700 session = self._get_session(sessionid, setpool=False) |
705 session = self._get_session(sessionid, setpool=False) |
701 for prop, value in props.items(): |
706 for prop, value in props.items(): |
702 session.change_property(prop, value) |
707 session.change_property(prop, value) |
703 |
708 |
704 def undoable_transactions(self, sessionid, ueid=None, **actionfilters): |
709 def undoable_transactions(self, sessionid, ueid=None, txid=None, |
|
710 **actionfilters): |
705 """See :class:`cubicweb.dbapi.Connection.undoable_transactions`""" |
711 """See :class:`cubicweb.dbapi.Connection.undoable_transactions`""" |
706 session = self._get_session(sessionid, setpool=True) |
712 session = self._get_session(sessionid, setpool=True, txid=txid) |
707 try: |
713 try: |
708 return self.system_source.undoable_transactions(session, ueid, |
714 return self.system_source.undoable_transactions(session, ueid, |
709 **actionfilters) |
715 **actionfilters) |
710 finally: |
716 finally: |
711 session.reset_pool() |
717 session.reset_pool() |
712 |
718 |
713 def transaction_info(self, sessionid, txuuid): |
719 def transaction_info(self, sessionid, txuuid, txid=None): |
714 """See :class:`cubicweb.dbapi.Connection.transaction_info`""" |
720 """See :class:`cubicweb.dbapi.Connection.transaction_info`""" |
715 session = self._get_session(sessionid, setpool=True) |
721 session = self._get_session(sessionid, setpool=True, txid=txid) |
716 try: |
722 try: |
717 return self.system_source.tx_info(session, txuuid) |
723 return self.system_source.tx_info(session, txuuid) |
718 finally: |
724 finally: |
719 session.reset_pool() |
725 session.reset_pool() |
720 |
726 |
721 def transaction_actions(self, sessionid, txuuid, public=True): |
727 def transaction_actions(self, sessionid, txuuid, public=True, txid=None): |
722 """See :class:`cubicweb.dbapi.Connection.transaction_actions`""" |
728 """See :class:`cubicweb.dbapi.Connection.transaction_actions`""" |
723 session = self._get_session(sessionid, setpool=True) |
729 session = self._get_session(sessionid, setpool=True, txid=txid) |
724 try: |
730 try: |
725 return self.system_source.tx_actions(session, txuuid, public) |
731 return self.system_source.tx_actions(session, txuuid, public) |
726 finally: |
732 finally: |
727 session.reset_pool() |
733 session.reset_pool() |
728 |
734 |
729 def undo_transaction(self, sessionid, txuuid): |
735 def undo_transaction(self, sessionid, txuuid, txid=None): |
730 """See :class:`cubicweb.dbapi.Connection.undo_transaction`""" |
736 """See :class:`cubicweb.dbapi.Connection.undo_transaction`""" |
731 session = self._get_session(sessionid, setpool=True) |
737 session = self._get_session(sessionid, setpool=True, txid=txid) |
732 try: |
738 try: |
733 return self.system_source.undo_transaction(session, txuuid) |
739 return self.system_source.undo_transaction(session, txuuid) |
734 finally: |
740 finally: |
735 session.reset_pool() |
741 session.reset_pool() |
736 |
742 |
789 """ |
795 """ |
790 session = InternalSession(self, cnxprops) |
796 session = InternalSession(self, cnxprops) |
791 session.set_pool() |
797 session.set_pool() |
792 return session |
798 return session |
793 |
799 |
794 def _get_session(self, sessionid, setpool=False, checkshuttingdown=True): |
800 def _get_session(self, sessionid, setpool=False, txid=None, |
|
801 checkshuttingdown=True): |
795 """return the user associated to the given session identifier""" |
802 """return the user associated to the given session identifier""" |
796 if checkshuttingdown and self._shutting_down: |
803 if checkshuttingdown and self._shutting_down: |
797 raise Exception('Repository is shutting down') |
804 raise Exception('Repository is shutting down') |
798 try: |
805 try: |
799 session = self._sessions[sessionid] |
806 session = self._sessions[sessionid] |
800 except KeyError: |
807 except KeyError: |
801 raise BadConnectionId('No such session %s' % sessionid) |
808 raise BadConnectionId('No such session %s' % sessionid) |
802 if setpool: |
809 if setpool: |
|
810 session.set_tx_data(txid) # must be done before set_pool |
803 session.set_pool() |
811 session.set_pool() |
804 return session |
812 return session |
805 |
813 |
806 # data sources handling ################################################### |
814 # data sources handling ################################################### |
807 # * correspondance between eid and (type, source) |
815 # * correspondance between eid and (type, source) |