server/sources/native.py
changeset 10366 38c7598b5c61
parent 10365 21461f80f348
child 10411 4ee15441f2eb
equal deleted inserted replaced
10365:21461f80f348 10366:38c7598b5c61
   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)):