270 self.get_connection = lambda: ConnectionWrapper(self) |
270 self.get_connection = lambda: ConnectionWrapper(self) |
271 self.check_connection = lambda cnx: cnx |
271 self.check_connection = lambda cnx: cnx |
272 def pool_reset(cnx): |
272 def pool_reset(cnx): |
273 cnx.close() |
273 cnx.close() |
274 self.pool_reset = pool_reset |
274 self.pool_reset = pool_reset |
275 self.create_eid = self.__create_eid_sqlite |
275 if self.dbdriver == 'sqlite': |
|
276 self._create_eid = None |
|
277 self.create_eid = self._create_eid_sqlite |
276 |
278 |
277 @property |
279 @property |
278 def _sqlcnx(self): |
280 def _sqlcnx(self): |
279 # XXX: sqlite connections can only be used in the same thread, so |
281 # XXX: sqlite connections can only be used in the same thread, so |
280 # create a new one each time necessary. If it appears to be time |
282 # create a new one each time necessary. If it appears to be time |
711 except: |
713 except: |
712 pass |
714 pass |
713 return None |
715 return None |
714 |
716 |
715 def make_temp_table_name(self, table): |
717 def make_temp_table_name(self, table): |
716 try: # XXX remove this once |
718 try: # XXX remove this once |
717 return self.dbhelper.temporary_table_name(table) |
719 return self.dbhelper.temporary_table_name(table) |
718 except AttributeError: |
720 except AttributeError: |
719 import warnings |
721 import warnings |
720 warnings.warn('Please hg up logilab.database') |
722 warnings.warn('Please hg up logilab.database') |
721 return table |
723 return table |
729 # running with an ldap source, and table will be deleted manually any way |
731 # running with an ldap source, and table will be deleted manually any way |
730 # on commit |
732 # on commit |
731 sql = self.dbhelper.sql_temporary_table(table, schema, False) |
733 sql = self.dbhelper.sql_temporary_table(table, schema, False) |
732 self.doexec(session, sql) |
734 self.doexec(session, sql) |
733 |
735 |
734 def __create_eid_sqlite(self, session): |
736 def _create_eid_sqlite(self, session): |
735 self._eid_creation_lock.acquire() |
737 self._eid_creation_lock.acquire() |
736 try: |
738 try: |
737 for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'): |
739 for sql in self.dbhelper.sqls_increment_sequence('entities_id_seq'): |
738 cursor = self.doexec(session, sql) |
740 cursor = self.doexec(session, sql) |
739 return cursor.fetchone()[0] |
741 return cursor.fetchone()[0] |
742 |
744 |
743 |
745 |
744 def create_eid(self, session): |
746 def create_eid(self, session): |
745 self.debug('create eid') |
747 self.debug('create eid') |
746 # lock needed to prevent 'Connection is busy with results for another command (0)' errors with SQLServer |
748 # lock needed to prevent 'Connection is busy with results for another command (0)' errors with SQLServer |
747 self._eid_creation_lock.acquire() |
749 self._eid_creation_lock.acquire() |
748 try: |
750 try: |
749 return self.__create_eid() |
751 return self._create_eid() |
750 finally: |
752 finally: |
751 self._eid_creation_lock.release() |
753 self._eid_creation_lock.release() |
752 |
754 |
753 def __create_eid(self): |
755 def _create_eid(self): |
754 # internal function doing the eid creation without locking. |
756 # internal function doing the eid creation without locking. |
755 # needed for the recursive handling of disconnections (otherwise we |
757 # needed for the recursive handling of disconnections (otherwise we |
756 # deadlock on self._eid_creation_lock |
758 # deadlock on self._eid_creation_lock |
757 if self._eid_creation_cnx is None: |
759 if self._eid_creation_cnx is None: |
758 self._eid_creation_cnx = self.get_connection() |
760 self._eid_creation_cnx = self.get_connection() |
759 cnx = self._eid_creation_cnx |
761 cnx = self._eid_creation_cnx |
760 cursor = cnx.cursor() |
762 cursor = cnx.cursor() |
764 eid = cursor.fetchone()[0] |
766 eid = cursor.fetchone()[0] |
765 except (self.OperationalError, self.InterfaceError): |
767 except (self.OperationalError, self.InterfaceError): |
766 # FIXME: better detection of deconnection pb |
768 # FIXME: better detection of deconnection pb |
767 self.warning("trying to reconnect create eid connection") |
769 self.warning("trying to reconnect create eid connection") |
768 self._eid_creation_cnx = None |
770 self._eid_creation_cnx = None |
769 return self.__create_eid() |
771 return self._create_eid() |
770 except (self.DbapiError,), exc: |
772 except (self.DbapiError,), exc: |
771 # We get this one with pyodbc and SQL Server when connection was reset |
773 # We get this one with pyodbc and SQL Server when connection was reset |
772 if exc.args[0] == '08S01': |
774 if exc.args[0] == '08S01': |
773 self.warning("trying to reconnect create eid connection") |
775 self.warning("trying to reconnect create eid connection") |
774 self._eid_creation_cnx = None |
776 self._eid_creation_cnx = None |
775 return self.__create_eid() |
777 return self._create_eid() |
776 else: |
778 else: |
777 raise |
779 raise |
778 except: # WTF? |
780 except: # WTF? |
779 cnx.rollback() |
781 cnx.rollback() |
780 self._eid_creation_cnx = None |
782 self._eid_creation_cnx = None |
781 self.exception('create eid failed in an unforeseen way on SQL statement %s', sql) |
783 self.exception('create eid failed in an unforeseen way on SQL statement %s', sql) |
782 raise |
784 raise |
783 else: |
785 else: |
784 cnx.commit() |
786 cnx.commit() |
785 return eid |
787 return eid |
786 |
788 |
787 |
789 |
788 def add_info(self, session, entity, source, extid, complete): |
790 def add_info(self, session, entity, source, extid, complete): |
789 """add type and source info for an eid into the system table""" |
791 """add type and source info for an eid into the system table""" |
790 # begin by inserting eid/type/source/extid into the entities table |
792 # begin by inserting eid/type/source/extid into the entities table |
791 if extid is not None: |
793 if extid is not None: |