From 45a303eb25afc1c311a441089e6043a1028224b0 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 7 Jun 2009 20:07:18 +0100 Subject: [PATCH] make global lock work (do nothing) if hands table doesn't exist --- pyfpdb/fpdb.py | 7 +++-- pyfpdb/fpdb_db.py | 59 +++++++++++++++++++++++++------------------ pyfpdb/fpdb_simple.py | 47 +++++++++++++++++++--------------- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index 645ddef5..8d514b90 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -181,7 +181,7 @@ class fpdb: def dia_load_profile(self, widget, data=None): """Dialogue to select a file to load a profile from""" - if self.obtain_global_lock(): + if self.obtain_global_lock() == 0: # returns 0 if successful try: chooser = gtk.FileChooserDialog(title="Please select a profile file to load", action=gtk.FILE_CHOOSER_ACTION_OPEN, @@ -201,7 +201,7 @@ class fpdb: def dia_recreate_tables(self, widget, data=None): """Dialogue that asks user to confirm that he wants to delete and recreate the tables""" - if self.obtain_global_lock(): + if self.obtain_global_lock() in (0,2): # returns 0 if successful, 2 if Hands table does not exist lock_released = False try: @@ -406,7 +406,7 @@ class fpdb: self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password']) - return fpdb_simple.get_global_lock(self.fdb_lock) + return self.fdb_lock.get_global_lock() #end def obtain_global_lock def quit(self, widget): @@ -455,7 +455,6 @@ class fpdb: ps_tab=new_ps_thread.get_vbox() self.add_and_display_tab(ps_tab, "Positional Stats") - def tab_main_help(self, widget, data=None): """Displays a tab with the main fpdb help screen""" #print "start of tab_main_help" diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index ad599b13..dd7f5afe 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -17,6 +17,8 @@ import os import re +import sys + import fpdb_simple import FpdbSQLQueries @@ -96,7 +98,7 @@ class fpdb_db: try: self.cursor.execute("SELECT * FROM Settings") settings=self.cursor.fetchone() - if settings[0]!=119: + if settings[0]!=118: print "outdated or too new database version - please recreate tables" self.wrongDbVersion=True except:# _mysql_exceptions.ProgrammingError: @@ -201,14 +203,10 @@ class fpdb_db: #end def get_db_info def fillDefaultData(self): - self.cursor.execute("INSERT INTO Settings VALUES (119);") + self.cursor.execute("INSERT INTO Settings VALUES (118);") self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');") self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');") self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Everleaf', 'USD');") - self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Carbon', 'USD');") - self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'OnGame', 'USD');") - self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'UltimateBet', 'USD');") - self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Betfair', 'USD');") self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);") #end def fillDefaultData @@ -222,22 +220,33 @@ class fpdb_db: print "Finished recreating tables" #end def recreate_tables - def getSqlPlayerIDs(names, site_id): - result = [] - notfound = [] - self.cursor.execute("SELECT name,id FROM Players WHERE name='%s'" % "' OR name='".join(names)) - tmp = dict(self.cursor.fetchall()) - for n in names: - if n not in tmp: - notfound.append(n) - else: - result.append(tmp[n]) - if notfound: - cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", (notfound)) - cursor.execute("SELECT id FROM Players WHERE name='%s'" % "' OR name='".join(notfound)) - tmp = cursor.fetchall() - for n in tmp: - result.append(n[0]) - - #We proabably want to cache this - return result + # Currently uses an exclusive lock on the Hands table as a global lock + # Return values are Unix style, 0 for success, positive integers for errors + # 1 = generic error + # 2 = hands table does not exist (error message is suppressed) + def get_global_lock(self): + if self.backend == self.MYSQL_INNODB: + try: + self.cursor.execute( "lock tables Hands write" ) + except: + # Table 'fpdb.hands' doesn't exist + if str(sys.exc_value).find(".hands' doesn't exist") >= 0: + return(2) + print "Error! failed to obtain global lock. Close all programs accessing " \ + + "database (including fpdb) and try again (%s)." \ + % ( str(sys.exc_value).rstrip('\n'), ) + return(1) + elif self.backend == self.PGSQL: + try: + self.cursor.execute( "lock table Hands in exclusive mode nowait" ) + #print "... after lock table, status =", self.cursor.statusmessage + except: + # relation "hands" does not exist + if str(sys.exc_value).find('relation "hands" does not exist') >= 0: + return(2) + print "Error! failed to obtain global lock. Close all programs accessing " \ + + "database (including fpdb) and try again (%s)." \ + % ( str(sys.exc_value).rstrip('\n'), ) + return(1) + return(0) +#end class fpdb_db diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index 2241feab..58eb9881 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -16,6 +16,10 @@ #agpl-3.0.txt in the docs folder of the package. #This file contains simple functions for fpdb + +#Aiming to eventually remove this module, functions will move to, eg: +#fpdb_db db create/re-create/management/etc +#Hands or related files for saving hands to db, etc import datetime import time @@ -28,6 +32,7 @@ PS = 1 FTP = 2 # TODO: these constants are also used in fpdb_save_to_db and others, is there a way to do like C #define, and #include ? +# answer - yes. These are defined in fpdb_db so are accessible through that class. MYSQL_INNODB = 2 PGSQL = 3 SQLITE = 4 @@ -367,27 +372,6 @@ def analyzeDB(fdb): fdb.db.commit() #end def analyzeDB -def get_global_lock(fdb): - if fdb.backend == MYSQL_INNODB: - try: - fdb.cursor.execute( "lock tables Hands write" ) - except: - print "Error! failed to obtain global lock. Close all programs accessing " \ - + "database (including fpdb) and try again (%s)." \ - % ( str(sys.exc_value).rstrip('\n'), ) - return(False) - elif fdb.backend == PGSQL: - try: - fdb.cursor.execute( "lock table Hands in exclusive mode nowait" ) - #print "... after lock table, status =", fdb.cursor.statusmessage - except: - print "Error! failed to obtain global lock. Close all programs accessing " \ - + "database (including fpdb) and try again (%s)." \ - % ( str(sys.exc_value).rstrip('\n'), ) - return(False) - return(True) - - class DuplicateError(Exception): def __init__(self, value): self.value = value @@ -1390,6 +1374,27 @@ def recognisePlayerIDs(cursor, names, site_id): #end def recognisePlayerIDs +# Here's a version that would work if it wasn't for the fact that it needs to have the output in the same order as input +# this version could also be improved upon using list comprehensions, etc + +#def recognisePlayerIDs(cursor, names, site_id): +# result = [] +# notfound = [] +# cursor.execute("SELECT name,id FROM Players WHERE name='%s'" % "' OR name='".join(names)) +# tmp = dict(cursor.fetchall()) +# for n in names: +# if n not in tmp: +# notfound.append(n) +# else: +# result.append(tmp[n]) +# if notfound: +# cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", (notfound)) +# cursor.execute("SELECT id FROM Players WHERE name='%s'" % "' OR name='".join(notfound)) +# tmp = cursor.fetchall() +# for n in tmp: +# result.append(n[0]) +# +# return result #recognises the name in the given line and returns its array position in the given array def recognisePlayerNo(line, names, atype):