--- a/server/sources/native.py Tue Jun 01 17:06:41 2010 +0200
+++ b/server/sources/native.py Thu Jun 03 10:17:44 2010 +0200
@@ -256,6 +256,7 @@
# we need a lock to protect eid attribution function (XXX, really?
# explain)
self._eid_creation_lock = Lock()
+ self._eid_creation_cnx = self.get_connection()
# (etype, attr) / storage mapping
self._storages = {}
# entity types that may be used by other multi-sources instances
@@ -271,6 +272,9 @@
def pool_reset(cnx):
cnx.close()
self.pool_reset = pool_reset
+ if self.dbdriver == 'sqlite':
+ self._create_eid = None
+ self.create_eid = self._create_eid_sqlite
@property
def _sqlcnx(self):
@@ -711,7 +715,7 @@
return None
def make_temp_table_name(self, table):
- try: # XXX remove this once
+ try: # XXX remove this once
return self.dbhelper.temporary_table_name(table)
except AttributeError:
import warnings
@@ -729,7 +733,7 @@
sql = self.dbhelper.sql_temporary_table(table, schema, False)
self.doexec(session, sql)
- def create_eid(self, session):
+ def _create_eid_sqlite(self, session):
self._eid_creation_lock.acquire()
try:
for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'):
@@ -738,6 +742,51 @@
finally:
self._eid_creation_lock.release()
+
+ def create_eid(self, session):
+ self.debug('create eid')
+ # lock needed to prevent 'Connection is busy with results for another command (0)' errors with SQLServer
+ self._eid_creation_lock.acquire()
+ try:
+ return self._create_eid()
+ finally:
+ self._eid_creation_lock.release()
+
+ def _create_eid(self):
+ # internal function doing the eid creation without locking.
+ # needed for the recursive handling of disconnections (otherwise we
+ # deadlock on self._eid_creation_lock
+ if self._eid_creation_cnx is None:
+ self._eid_creation_cnx = self.get_connection()
+ cnx = self._eid_creation_cnx
+ cursor = cnx.cursor()
+ try:
+ for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'):
+ cursor.execute(sql)
+ eid = cursor.fetchone()[0]
+ except (self.OperationalError, self.InterfaceError):
+ # FIXME: better detection of deconnection pb
+ self.warning("trying to reconnect create eid connection")
+ self._eid_creation_cnx = None
+ return self._create_eid()
+ except (self.DbapiError,), exc:
+ # We get this one with pyodbc and SQL Server when connection was reset
+ if exc.args[0] == '08S01':
+ self.warning("trying to reconnect create eid connection")
+ self._eid_creation_cnx = None
+ return self._create_eid()
+ else:
+ raise
+ except: # WTF?
+ cnx.rollback()
+ self._eid_creation_cnx = None
+ self.exception('create eid failed in an unforeseen way on SQL statement %s', sql)
+ raise
+ else:
+ cnx.commit()
+ return eid
+
+
def add_info(self, session, entity, source, extid, complete):
"""add type and source info for an eid into the system table"""
# begin by inserting eid/type/source/extid into the entities table