551 self.cache_miss += 1 |
551 self.cache_miss += 1 |
552 sql, qargs, cbs = self._rql_sqlgen.generate(union, args, varmap) |
552 sql, qargs, cbs = self._rql_sqlgen.generate(union, args, varmap) |
553 self._cache[cachekey] = sql, qargs, cbs |
553 self._cache[cachekey] = sql, qargs, cbs |
554 args = self.merge_args(args, qargs) |
554 args = self.merge_args(args, qargs) |
555 assert isinstance(sql, basestring), repr(sql) |
555 assert isinstance(sql, basestring), repr(sql) |
556 try: |
556 cursor = self.doexec(cnx, sql, args) |
557 cursor = self.doexec(cnx, sql, args) |
|
558 except (self.OperationalError, self.InterfaceError): |
|
559 if cnx.mode == 'write': |
|
560 # do not attempt to reconnect if there has been some write |
|
561 # during the transaction |
|
562 raise |
|
563 # FIXME: better detection of deconnection pb |
|
564 self.warning("trying to reconnect") |
|
565 cnx.cnxset.reconnect() |
|
566 cursor = self.doexec(cnx, sql, args) |
|
567 except self.DbapiError as exc: |
|
568 # We get this one with pyodbc and SQL Server when connection was reset |
|
569 if exc.args[0] == '08S01' and cnx.mode != 'write': |
|
570 self.warning("trying to reconnect") |
|
571 cnx.cnxset.reconnect() |
|
572 cursor = self.doexec(cnx, sql, args) |
|
573 else: |
|
574 raise |
|
575 results = self.process_result(cursor, cnx, cbs) |
557 results = self.process_result(cursor, cnx, cbs) |
576 assert dbg_results(results) |
558 assert dbg_results(results) |
577 return results |
559 return results |
578 |
560 |
579 @contextmanager |
561 @contextmanager |
827 cursor = LogCursor(cnx.cnxset.cu) |
809 cursor = LogCursor(cnx.cnxset.cu) |
828 self.dbhelper.drop_index(cursor, table, column, unique) |
810 self.dbhelper.drop_index(cursor, table, column, unique) |
829 |
811 |
830 # system source interface ################################################# |
812 # system source interface ################################################# |
831 |
813 |
832 def _eid_type_source(self, cnx, eid, sql, _retry=True): |
814 def _eid_type_source(self, cnx, eid, sql): |
833 try: |
815 try: |
834 res = self.doexec(cnx, sql).fetchone() |
816 res = self.doexec(cnx, sql).fetchone() |
835 if res is not None: |
817 if res is not None: |
836 return res |
818 return res |
837 except (self.OperationalError, self.InterfaceError): |
|
838 if cnx.mode == 'read' and _retry: |
|
839 self.warning("trying to reconnect (eid_type_source())") |
|
840 cnx.cnxset.reconnect() |
|
841 return self._eid_type_source(cnx, eid, sql, _retry=False) |
|
842 except Exception: |
819 except Exception: |
843 assert cnx.cnxset, 'connection has no connections set' |
|
844 self.exception('failed to query entities table for eid %s', eid) |
820 self.exception('failed to query entities table for eid %s', eid) |
845 raise UnknownEid(eid) |
821 raise UnknownEid(eid) |
846 |
822 |
847 def eid_type_source(self, cnx, eid): # pylint: disable=E0202 |
823 def eid_type_source(self, cnx, eid): # pylint: disable=E0202 |
848 """return a tuple (type, source, extid) for the entity with id <eid>""" |
824 """return a tuple (type, source, extid) for the entity with id <eid>""" |
1054 """See :class:`cubicweb.repoapi.Connection.undo_transaction` |
1030 """See :class:`cubicweb.repoapi.Connection.undo_transaction` |
1055 |
1031 |
1056 important note: while undoing of a transaction, only hooks in the |
1032 important note: while undoing of a transaction, only hooks in the |
1057 'integrity', 'activeintegrity' and 'undo' categories are called. |
1033 'integrity', 'activeintegrity' and 'undo' categories are called. |
1058 """ |
1034 """ |
1059 # set mode so connections set isn't released subsquently until commit/rollback |
|
1060 cnx.mode = 'write' |
|
1061 errors = [] |
1035 errors = [] |
1062 cnx.transaction_data['undoing_uuid'] = txuuid |
1036 cnx.transaction_data['undoing_uuid'] = txuuid |
1063 with cnx.deny_all_hooks_but('integrity', 'activeintegrity', 'undo'): |
1037 with cnx.deny_all_hooks_but('integrity', 'activeintegrity', 'undo'): |
1064 with cnx.security_enabled(read=False): |
1038 with cnx.security_enabled(read=False): |
1065 for action in reversed(self.tx_actions(cnx, txuuid, False)): |
1039 for action in reversed(self.tx_actions(cnx, txuuid, False)): |