diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 72083819..ac2ea49e 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -188,14 +188,7 @@ class Database: log.info("Creating Database instance, sql = %s" % sql) self.config = c self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql - self.fdb.do_connect(c) - self.connection = self.fdb.db - - db_params = c.get_db_parameters() - self.import_options = c.get_import_parameters() - self.type = db_params['db-type'] - self.backend = db_params['db-backend'] - self.db_server = db_params['db-server'] + self.do_connect(c) if self.backend == self.PGSQL: from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE @@ -206,14 +199,14 @@ class Database: # where possible avoid creating new SQL instance by using the global one passed in if sql is None: - self.sql = SQL.Sql(type = self.type, db_server = db_params['db-server']) + self.sql = SQL.Sql(type = self.type, db_server = self.db_server) else: self.sql = sql - if self.backend == self.SQLITE and db_params['db-databaseName'] == ':memory:' and self.fdb.wrongDbVersion: + if self.backend == self.SQLITE and self.database == ':memory:' and self.wrongDbVersion: log.info("sqlite/:memory: - creating") self.recreate_tables() - self.fdb.wrongDbVersion = False + self.wrongDbVersion = False self.pcache = None # PlayerId cache self.cachemiss = 0 # Delete me later - using to count player cache misses @@ -245,6 +238,16 @@ class Database: def do_connect(self, c): self.fdb.do_connect(c) + self.connection = self.fdb.db + self.wrongDbVersion = self.fdb.wrongDbVersion + + db_params = c.get_db_parameters() + self.import_options = c.get_import_parameters() + self.type = db_params['db-type'] + self.backend = db_params['db-backend'] + self.db_server = db_params['db-server'] + self.database = db_params['db-databaseName'] + self.host = db_params['db-host'] def commit(self): self.fdb.db.commit() diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index ac036cbf..6ad242bb 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -32,19 +32,20 @@ import FpdbSQLQueries class Filters(threading.Thread): def __init__(self, db, config, qdict, display = {}, debug=True): - self.debug=debug + # config and qdict are now redundant + self.debug = debug #print "start of GraphViewer constructor" - self.db=db - self.cursor=db.cursor - self.sql=qdict - self.conf = config + self.db = db + self.cursor = db.cursor + self.sql = db.sql + self.conf = db.config self.display = display self.sites = {} self.games = {} self.limits = {} self.seats = {} - self.groups = {} + self.groups = {} self.siteid = {} self.heroes = {} self.boxes = {} @@ -451,6 +452,9 @@ class Filters(threading.Thread): hbox.pack_start(vbox3, False, False, 0) found = {'nl':False, 'fl':False, 'ring':False, 'tour':False} for i, line in enumerate(result): + if "UseType" in self.display: + if line[0] != self.display["UseType"]: + continue hbox = gtk.HBox(False, 0) if i <= len(result)/2: vbox2.pack_start(hbox, False, False, 0) diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index f5beadcf..f91c9870 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -53,20 +53,26 @@ class GuiGraphViewer (threading.Thread): self.db = Database.Database(self.conf, sql=self.sql) - filters_display = { "Heroes" : True, - "Sites" : True, - "Games" : True, - "Limits" : True, - "Seats" : False, - "Dates" : True, - "Button1" : True, - "Button2" : True + filters_display = { "Heroes" : True, + "Sites" : True, + "Games" : True, + "Limits" : True, + "LimitSep" : True, + "LimitType" : True, + "Type" : False, + "UseType" : 'ring', + "Seats" : False, + "SeatSep" : False, + "Dates" : True, + "Groups" : False, + "Button1" : True, + "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) - self.filters.registerButton1Name("Refresh Graph") + self.filters.registerButton1Name("Refresh _Graph") self.filters.registerButton1Callback(self.generateGraph) - self.filters.registerButton2Name("Export to File") + self.filters.registerButton2Name("_Export to File") self.filters.registerButton2Callback(self.exportGraph) self.mainHBox = gtk.HBox(False, 0) @@ -146,10 +152,8 @@ class GuiGraphViewer (threading.Thread): raise def generateGraph(self, widget, data): - print "generateGraph: start" try: self.clearGraphData() - print "after cleardata" sitenos = [] playerids = [] @@ -158,15 +162,18 @@ class GuiGraphViewer (threading.Thread): heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() limits = self.filters.getLimits() - print "got filter data" + for i in ('show', 'none'): + if i in limits: + limits.remove(i) # Which sites are selected? for site in sites: if sites[site] == True: sitenos.append(siteids[site]) - self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],)) - result = self.db.cursor.fetchall() + c = self.db.get_cursor() + c.execute(self.sql.query['getPlayerId'], (heroes[site],)) + result = c.fetchall() if len(result) == 1: - playerids.append(result[0][0]) + playerids.append( int(result[0][0]) ) if not sitenos: #Should probably pop up here. @@ -182,12 +189,10 @@ class GuiGraphViewer (threading.Thread): return #Set graph properties - print "add_subplot" self.ax = self.fig.add_subplot(111) #Get graph data from DB starttime = time() - print "get line: playerids =", playerids, "sitenos =", sitenos, "limits =", limits line = self.getRingProfitGraph(playerids, sitenos, limits) print "Graph generated in: %s" %(time() - starttime) @@ -234,12 +239,31 @@ class GuiGraphViewer (threading.Thread): # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) nametest = str(tuple(names)) sitetest = str(tuple(sites)) - limittest = str(tuple(limits)) - nametest = nametest.replace("L", "") - nametest = nametest.replace(",)",")") - sitetest = sitetest.replace(",)",")") - limittest = limittest.replace("L", "") - limittest = limittest.replace(",)",")") + #nametest = nametest.replace("L", "") + + lims = [int(x) for x in limits if x.isdigit()] + nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl'] + limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in " + # and ( (limit and bb in()) or (nolimit and bb in ()) ) + if lims: + blindtest = str(tuple(lims)) + blindtest = blindtest.replace("L", "") + blindtest = blindtest.replace(",)",")") + limittest = limittest + blindtest + ' ) ' + else: + limittest = limittest + '(-1) ) ' + limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in " + if nolims: + blindtest = str(tuple(nolims)) + blindtest = blindtest.replace("L", "") + blindtest = blindtest.replace(",)",")") + limittest = limittest + blindtest + ' ) )' + else: + limittest = limittest + '(-1) ) )' + if type == 'ring': + limittest = limittest + " and gt.type = 'ring' " + elif type == 'tour': + limittest = limittest + " and gt.type = 'tour' " #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("", nametest) @@ -247,6 +271,7 @@ class GuiGraphViewer (threading.Thread): tmp = tmp.replace("", start_date) tmp = tmp.replace("", end_date) tmp = tmp.replace("", limittest) + tmp = tmp.replace(",)", ")") #print "DEBUG: sql query:" #print tmp @@ -255,10 +280,10 @@ class GuiGraphViewer (threading.Thread): winnings = self.db.cursor.fetchall() self.db.rollback() - if(winnings == ()): + if winnings == (): return None - y=map(lambda x:float(x[3]), winnings) + y = map(lambda x:float(x[1]), winnings) line = cumsum(y) return line/100 #end of def getRingProfitGraph diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 12df7aa4..629f682e 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -2455,16 +2455,16 @@ class Sql: # self.query['playerStatsByPosition'] = """ """ self.query['getRingProfitAllHandsPlayerIdSite'] = """ - SELECT hp.handId, hp.totalProfit, hp.totalProfit, hp.totalProfit + SELECT hp.handId, hp.totalProfit FROM HandsPlayers hp - INNER JOIN Players pl ON (hp.playerId = pl.id) - INNER JOIN Hands h ON (h.id = hp.handId) - INNER JOIN Gametypes g ON (h.gametypeId = g.id) - where pl.id in + INNER JOIN Players pl ON (pl.id = hp.playerId) + INNER JOIN Hands h ON (h.id = hp.handId) + INNER JOIN Gametypes gt ON (gt.id = h.gametypeId) + WHERE pl.id in AND pl.siteId in AND h.handStart > '' AND h.handStart < '' - AND g.bigBlind in + AND hp.tourneysPlayersId IS NULL GROUP BY h.handStart, hp.handId, hp.totalProfit ORDER BY h.handStart""" diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index 6d58f733..18bc65d9 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -44,6 +44,7 @@ else: print "Python " + sys.version[0:3] + '...\n' +import traceback import threading import Options import string @@ -64,7 +65,6 @@ import gtk import interlocks -import fpdb_simple import GuiBulkImport import GuiPlayerStats import GuiPositionalStats @@ -76,7 +76,7 @@ import SQL import Database import FpdbSQLQueries import Configuration -import Exceptions +from Exceptions import * VERSION = "0.11" @@ -234,13 +234,13 @@ class fpdb: dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables") diastring = "Please confirm that you want to (re-)create the tables. If there already are tables in the database " \ - +self.db.fdb.database+" on "+self.db.fdb.host+" they will be deleted." + +self.db.database+" on "+self.db.host+" they will be deleted." dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted response = dia_confirm.run() dia_confirm.destroy() if response == gtk.RESPONSE_YES: - #if self.db.fdb.backend == self.fdb_lock.fdb.MYSQL_INNODB: + #if self.db.backend == self.fdb_lock.fdb.MYSQL_INNODB: # mysql requires locks on all tables or none - easier to release this lock # than lock all the other tables # ToDo: lock all other tables so that lock doesn't have to be released @@ -455,17 +455,23 @@ class fpdb: self.sql = SQL.Sql(type = self.settings['db-type'], db_server = self.settings['db-server']) try: self.db = Database.Database(self.config, sql = self.sql) - except Exceptions.FpdbMySQLFailedError: + except FpdbMySQLFailedError: self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR") exit() except FpdbError: - print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']) + #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']) + self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR") + err = traceback.extract_tb(sys.exc_info()[2])[-1] + print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]) sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])) except: - print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']) + #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']) + self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR") + err = traceback.extract_tb(sys.exc_info()[2])[-1] + print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]) sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])) - if self.db.fdb.wrongDbVersion: + if self.db.wrongDbVersion: diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) label = gtk.Label("An invalid DB version or missing tables have been detected.") @@ -484,14 +490,14 @@ class fpdb: diaDbVersionWarning.destroy() if self.status_bar == None: - self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.fdb.database, self.db.fdb.host)) + self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.database, self.db.host)) self.main_vbox.pack_end(self.status_bar, False, True, 0) self.status_bar.show() else: - self.status_bar.set_text("Status: Connected to %s database named %s on host %s" % (self.db.get_backend_name(),self.db.fdb.database, self.db.fdb.host)) + 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)) # Database connected to successfully, load queries to pass on to other classes - self.db.connection.rollback() + self.db.rollback() self.validate_config() diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index 17fecc2c..986c747f 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -111,7 +111,7 @@ class fpdb_db: password = password, database = database) except: - msg = "PostgreSQL connection to database (%s) user (%s) failed." % (database, user) + msg = "PostgreSQL connection to database (%s) user (%s) failed. Are you sure the DB is running?" % (database, user) print msg raise FpdbError(msg) elif backend == fpdb_db.SQLITE: