From be7705226dd26afafd43aa3ea6e91fbc97988adf Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Thu, 12 Aug 2010 22:16:27 +0100 Subject: [PATCH] improve handling of missing / unavailable db errors --- pyfpdb/Database.py | 26 +++++++++++++++++--------- pyfpdb/fpdb.pyw | 14 ++++++++------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 92c30bea..64bdec12 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -265,7 +265,7 @@ class Database: #ISOLATION_LEVEL_SERIALIZABLE = 2 - if self.backend == self.SQLITE and self.database == ':memory:' and self.wrongDbVersion: + if self.backend == self.SQLITE and self.database == ':memory:' and self.wrongDbVersion and self.is_connected(): log.info("sqlite/:memory: - creating") self.recreate_tables() self.wrongDbVersion = False @@ -289,7 +289,8 @@ class Database: self.saveActions = False if self.import_options['saveActions'] == False else True - self.connection.rollback() # make sure any locks taken so far are released + if self.is_connected(): + self.connection.rollback() # make sure any locks taken so far are released #end def __init__ def dumpDatabase(self): @@ -342,7 +343,6 @@ class Database: self.db_server = db_params['db-server'] self.database = db_params['db-databaseName'] self.host = db_params['db-host'] - self.__connected = True def connect(self, backend=None, host=None, database=None, user=None, password=None, create=False): @@ -363,6 +363,7 @@ class Database: MySQLdb = pool.manage(MySQLdb, pool_size=5) try: self.connection = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True) + self.__connected = True #TODO: Add port option except MySQLdb.Error, ex: if ex.args[0] == 1045: @@ -384,20 +385,21 @@ class Database: # flat out wrong # sqlcoder: This database only connect failed in my windows setup?? # Modifed it to try the 4 parameter style if the first connect fails - does this work everywhere? - connected = False + self.__connected = False if self.host == "localhost" or self.host == "127.0.0.1": try: self.connection = psycopg2.connect(database = database) - connected = True + self.__connected = True except: # direct connection failed so try user/pass/... version pass - if not connected: + if not self.is_connected(): try: self.connection = psycopg2.connect(host = host, user = user, password = password, database = database) + self.__connected = True except Exception, ex: if 'Connection refused' in ex.args[0]: # meaning eg. db not running @@ -426,6 +428,7 @@ class Database: log.info("Connecting to SQLite: %(database)s" % {'database':self.db_path}) if os.path.exists(database) or create: self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES ) + self.__connected = True sqlite3.register_converter("bool", lambda x: bool(int(x))) sqlite3.register_adapter(bool, lambda x: "1" if x else "0") self.connection.create_function("floor", 1, math.floor) @@ -443,9 +446,10 @@ class Database: else: raise FpdbError("unrecognised database backend:"+str(backend)) - self.cursor = self.connection.cursor() - self.cursor.execute(self.sql.query['set tx level']) - self.check_version(database=database, create=create) + if self.is_connected(): + self.cursor = self.connection.cursor() + self.cursor.execute(self.sql.query['set tx level']) + self.check_version(database=database, create=create) def check_version(self, database, create): @@ -499,6 +503,10 @@ class Database: self.connection.rollback() def connected(self): + """ now deprecated, use is_connected() instead """ + return self.__connected + + def is_connected(self): return self.__connected def get_cursor(self): diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index ec731572..7ec549f7 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -105,7 +105,7 @@ except: import GuiPrefs import GuiLogView -#import GuiDatabase +import GuiDatabase import GuiBulkImport import GuiImapFetcher import GuiRingPlayerStats @@ -838,7 +838,7 @@ class fpdb: ('hudConfigurator', None, '_HUD Configurator', 'H', 'HUD Configurator', self.diaHudConfigurator), ('graphs', None, '_Graphs', 'G', 'Graphs', self.tabGraphViewer), ('ringplayerstats', None, 'Ring _Player Stats (tabulated view)', 'P', 'Ring Player Stats (tabulated view)', self.tab_ring_player_stats), - ('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view, mysql only)', 'T', 'Tourney Player Stats (tabulated view, mysql only)', self.tab_tourney_player_stats), + ('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view)', 'T', 'Tourney Player Stats (tabulated view, mysql only)', self.tab_tourney_player_stats), ('tourneyviewer', None, 'Tourney _Viewer', None, 'Tourney Viewer)', self.tab_tourney_viewer_stats), ('posnstats', None, 'P_ositional Stats (tabulated view, not on sqlite)', 'O', 'Positional Stats (tabulated view)', self.tab_positional_stats), ('sessionstats', None, 'Session Stats', None, 'Session Stats', self.tab_session_stats), @@ -894,7 +894,7 @@ class fpdb: self.settings.update(self.config.get_import_parameters()) self.settings.update(self.config.get_default_paths()) - if self.db is not None and self.db.connected: + if self.db is not None and self.db.is_connected(): self.db.disconnect() self.sql = SQL.Sql(db_server = self.settings['db-server']) @@ -917,6 +917,8 @@ class fpdb: if err_msg is not None: self.db = None self.warning_box(err_msg) + if self.db is not None and not self.db.is_connected(): + self.db = None # except FpdbMySQLFailedError: # self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR") @@ -957,7 +959,7 @@ class fpdb: self.main_vbox.pack_end(self.status_bar, False, True, 0) self.status_bar.show() - if self.db is not None and self.db.connected: + if self.db is not None and self.db.is_connected(): self.status_bar.set_text("Status: Connected to %s database named %s on host %s" % (self.db.get_backend_name(),self.db.database, self.db.host)) # rollback to make sure any locks are cleared: @@ -991,12 +993,12 @@ class fpdb: if self.db!=None: if self.db.backend==self.db.MYSQL_INNODB: try: - if self.db is not None and self.db.connected(): + if self.db is not None and self.db.is_connected(): self.db.disconnect() except _mysql_exceptions.OperationalError: # oh, damn, we're already disconnected pass else: - if self.db is not None and self.db.connected(): + if self.db is not None and self.db.is_connected(): self.db.disconnect() else: pass