Merge branch 'master' of git://git.assembla.com/fpdb-sql

This commit is contained in:
Ray 2009-08-05 19:28:16 -04:00
commit 095d1ee3dc
6 changed files with 2786 additions and 2524 deletions

View File

@ -184,6 +184,7 @@ class Database:
self.pcache = None # PlayerId cache self.pcache = None # PlayerId cache
self.cachemiss = 0 # Delete me later - using to count player cache misses self.cachemiss = 0 # Delete me later - using to count player cache misses
self.cachehit = 0 # Delete me later - using to count player cache hits
# config while trying out new hudcache mechanism # config while trying out new hudcache mechanism
self.use_date_in_hudcache = True self.use_date_in_hudcache = True
@ -451,7 +452,7 @@ class Database:
def get_player_id(self, config, site, player_name): def get_player_id(self, config, site, player_name):
c = self.connection.cursor() c = self.connection.cursor()
c.execute(self.sql.query['get_player_id'], {'player': player_name, 'site': site}) c.execute(self.sql.query['get_player_id'], (player_name, site))
row = c.fetchone() row = c.fetchone()
if row: if row:
return row[0] return row[0]
@ -812,9 +813,11 @@ class Database:
self.fillDefaultData() self.fillDefaultData()
self.commit() self.commit()
except: except:
print "Error creating tables: ", str(sys.exc_value) #print "Error creating tables: ", str(sys.exc_value)
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error creating tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
self.rollback() self.rollback()
raise fpdb_simple.FpdbError( "Error creating tables " + str(sys.exc_value) ) raise
#end def disconnect #end def disconnect
def drop_tables(self): def drop_tables(self):
@ -844,8 +847,9 @@ class Database:
self.commit() self.commit()
except: except:
print "Error dropping tables: " + str(sys.exc_value) print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
raise fpdb_simple.FpdbError( "Error dropping tables " + str(sys.exc_value) ) self.rollback()
raise
#end def drop_tables #end def drop_tables
def createAllIndexes(self): def createAllIndexes(self):
@ -916,6 +920,9 @@ class Database:
c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')") c.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')") c.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')")
c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')") c.execute("INSERT INTO Sites (name,currency) VALUES ('Win2day', 'USD')")
if self.backend == self.SQLITE:
c.execute("INSERT INTO TourneyTypes VALUES (NULL, 1, 0, 0, 0, 0);")
else:
c.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);") c.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
#c.execute("""INSERT INTO TourneyTypes #c.execute("""INSERT INTO TourneyTypes
# (siteId,buyin,fee,knockout,rebuyOrAddon) VALUES # (siteId,buyin,fee,knockout,rebuyOrAddon) VALUES
@ -976,21 +983,26 @@ class Database:
for player in pnames: for player in pnames:
result[player] = self.pcache[player] result[player] = self.pcache[player]
# NOTE: Using the LambdaDict does the same thing as:
#if player in self.pcache:
# #print "DEBUG: cachehit"
# pass
#else:
# self.pcache[player] = self.insertPlayer(player, siteid)
#result[player] = self.pcache[player]
return result return result
def insertPlayer(self, name, site_id): def insertPlayer(self, name, site_id):
self.cachemiss += 1
result = None result = None
c = self.get_cursor() c = self.get_cursor()
c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
tmp=c.fetchall() tmp=c.fetchall()
if (len(tmp)==0): #new player if (len(tmp)==0): #new player
c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (name, site_id)) c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (name, site_id))
#Get last id might be faster here.
c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
tmp=c.fetchall() tmp=c.fetchall()
#print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
print "DEBUG: cache misses: %s" %self.cachemiss
return tmp[0][0] return tmp[0][0]
@ -1788,6 +1800,8 @@ if __name__=="__main__":
print "database connection object = ", db_connection.connection print "database connection object = ", db_connection.connection
print "database type = ", db_connection.type print "database type = ", db_connection.type
db_connection.recreate_tables()
h = db_connection.get_last_hand() h = db_connection.get_last_hand()
print "last hand = ", h print "last hand = ", h

View File

@ -36,7 +36,7 @@ import Configuration
class GuiBulkImport(): class GuiBulkImport():
# CONFIGURATION - update these as preferred: # CONFIGURATION - update these as preferred:
allowThreads = False # set to True to try out the threads field allowThreads = True # set to True to try out the threads field
# not used # not used
def import_dir(self): def import_dir(self):
@ -71,12 +71,19 @@ class GuiBulkImport():
self.importer.setHandsInDB(self.n_hands_in_db) self.importer.setHandsInDB(self.n_hands_in_db)
cb_model = self.cb_dropindexes.get_model() cb_model = self.cb_dropindexes.get_model()
cb_index = self.cb_dropindexes.get_active() cb_index = self.cb_dropindexes.get_active()
cb_hmodel = self.cb_drophudcache.get_model()
cb_hindex = self.cb_drophudcache.get_active()
self.lab_info.set_text("Importing") # doesn't display :-(
if cb_index: if cb_index:
self.importer.setDropIndexes(cb_model[cb_index][0]) self.importer.setDropIndexes(cb_model[cb_index][0])
else: else:
self.importer.setDropIndexes("auto") self.importer.setDropIndexes("auto")
if cb_hindex:
self.importer.setDropHudCache(cb_hmodel[cb_hindex][0])
else:
self.importer.setDropHudCache("auto")
sitename = self.cbfilter.get_model()[self.cbfilter.get_active()][0] sitename = self.cbfilter.get_model()[self.cbfilter.get_active()][0]
self.lab_info.set_text("Importing")
self.importer.addBulkImportImportFileOrDir(self.inputFile, site = sitename) self.importer.addBulkImportImportFileOrDir(self.inputFile, site = sitename)
self.importer.setCallHud(False) self.importer.setCallHud(False)
@ -88,6 +95,13 @@ class GuiBulkImport():
print 'GuiBulkImport.load done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\ print 'GuiBulkImport.load done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\
% (stored, dups, partial, errs, ttime, (stored+0.0) / ttime) % (stored, dups, partial, errs, ttime, (stored+0.0) / ttime)
self.importer.clearFileList() self.importer.clearFileList()
if self.n_hands_in_db == 0 and stored > 0:
self.cb_dropindexes.set_sensitive(True)
self.cb_dropindexes.set_active(0)
self.lab_drop.set_sensitive(True)
self.cb_drophudcache.set_sensitive(True)
self.cb_drophudcache.set_active(0)
self.lab_hdrop.set_sensitive(True)
self.lab_info.set_text("Import finished") self.lab_info.set_text("Import finished")
except: except:
@ -115,7 +129,7 @@ class GuiBulkImport():
self.chooser.show() self.chooser.show()
# Table widget to hold the settings # Table widget to hold the settings
self.table = gtk.Table(rows = 3, columns = 5, homogeneous = False) self.table = gtk.Table(rows = 5, columns = 5, homogeneous = False)
self.vbox.add(self.table) self.vbox.add(self.table)
self.table.show() self.table.show()
@ -130,6 +144,7 @@ class GuiBulkImport():
self.table.attach(self.lab_status, 1, 2, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.lab_status, 1, 2, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_status.show() self.lab_status.show()
self.lab_status.set_justify(gtk.JUSTIFY_RIGHT) self.lab_status.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_status.set_alignment(1.0, 0.5)
# spin button - status # spin button - status
status_adj = gtk.Adjustment(value=100, lower=0, upper=300, step_incr=10, page_incr=1, page_size=0) #not sure what upper value should be! status_adj = gtk.Adjustment(value=100, lower=0, upper=300, step_incr=10, page_incr=1, page_size=0) #not sure what upper value should be!
@ -141,13 +156,15 @@ class GuiBulkImport():
self.lab_threads = gtk.Label("Number of threads:") self.lab_threads = gtk.Label("Number of threads:")
self.table.attach(self.lab_threads, 3, 4, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.lab_threads, 3, 4, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_threads.show() self.lab_threads.show()
if not self.allowThreads:
self.lab_threads.set_sensitive(False) self.lab_threads.set_sensitive(False)
self.lab_threads.set_justify(gtk.JUSTIFY_RIGHT) self.lab_threads.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_threads.set_alignment(1.0, 0.5)
# spin button - threads # spin button - threads
threads_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be! threads_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be!
self.spin_threads = gtk.SpinButton(adjustment=threads_adj, climb_rate=0.0, digits=0) self.spin_threads = gtk.SpinButton(adjustment=threads_adj, climb_rate=0.0, digits=0)
self.table.attach(self.spin_threads, 4, 5, 0, 1, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.spin_threads, 4, 5, 0, 1, xpadding = 10, ypadding = 0, yoptions=gtk.SHRINK)
self.spin_threads.show() self.spin_threads.show()
if not self.allowThreads: if not self.allowThreads:
self.spin_threads.set_sensitive(False) self.spin_threads.set_sensitive(False)
@ -162,6 +179,7 @@ class GuiBulkImport():
self.table.attach(self.lab_hands, 1, 2, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.lab_hands, 1, 2, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_hands.show() self.lab_hands.show()
self.lab_hands.set_justify(gtk.JUSTIFY_RIGHT) self.lab_hands.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_hands.set_alignment(1.0, 0.5)
# spin button - hands to import # spin button - hands to import
hands_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be! hands_adj = gtk.Adjustment(value=0, lower=0, upper=10, step_incr=1, page_incr=1, page_size=0) #not sure what upper value should be!
@ -174,6 +192,7 @@ class GuiBulkImport():
self.table.attach(self.lab_drop, 3, 4, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.lab_drop, 3, 4, 1, 2, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_drop.show() self.lab_drop.show()
self.lab_drop.set_justify(gtk.JUSTIFY_RIGHT) self.lab_drop.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_drop.set_alignment(1.0, 0.5)
# ComboBox - drop indexes # ComboBox - drop indexes
self.cb_dropindexes = gtk.combo_box_new_text() self.cb_dropindexes = gtk.combo_box_new_text()
@ -186,9 +205,10 @@ class GuiBulkImport():
# label - filter # label - filter
self.lab_filter = gtk.Label("Site filter:") self.lab_filter = gtk.Label("Site filter:")
self.table.attach(self.lab_filter, 2, 3, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.lab_filter, 1, 2, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_filter.show() self.lab_filter.show()
self.lab_filter.set_justify(gtk.JUSTIFY_RIGHT) self.lab_filter.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_filter.set_alignment(1.0, 0.5)
# ComboBox - filter # ComboBox - filter
self.cbfilter = gtk.combo_box_new_text() self.cbfilter = gtk.combo_box_new_text()
@ -196,21 +216,42 @@ class GuiBulkImport():
print w print w
self.cbfilter.append_text(w) self.cbfilter.append_text(w)
self.cbfilter.set_active(0) self.cbfilter.set_active(0)
self.table.attach(self.cbfilter, 3, 4, 2, 3, xpadding = 10, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.cbfilter, 2, 3, 2, 3, xpadding = 10, ypadding = 1, yoptions=gtk.SHRINK)
self.cbfilter.show() self.cbfilter.show()
# label - info # label - drop hudcache
self.lab_info = gtk.Label() self.lab_hdrop = gtk.Label("Drop HudCache:")
self.table.attach(self.lab_info, 0, 4, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.lab_hdrop, 3, 4, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_info.show() self.lab_hdrop.show()
self.lab_hdrop.set_justify(gtk.JUSTIFY_RIGHT)
self.lab_hdrop.set_alignment(1.0, 0.5)
# ComboBox - drop hudcache
self.cb_drophudcache = gtk.combo_box_new_text()
self.cb_drophudcache.append_text('auto')
self.cb_drophudcache.append_text("don't drop")
self.cb_drophudcache.append_text('drop')
self.cb_drophudcache.set_active(0)
self.table.attach(self.cb_drophudcache, 4, 5, 2, 3, xpadding = 10, ypadding = 0, yoptions=gtk.SHRINK)
self.cb_drophudcache.show()
# button - Import # button - Import
self.load_button = gtk.Button('Import') # todo: rename variables to import too self.load_button = gtk.Button('Import') # todo: rename variables to import too
self.load_button.connect('clicked', self.load_clicked, self.load_button.connect('clicked', self.load_clicked,
'Import clicked') 'Import clicked')
self.table.attach(self.load_button, 4, 5, 2, 3, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK) self.table.attach(self.load_button, 2, 3, 4, 5, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.load_button.show() self.load_button.show()
# label - spacer (keeps rows 3 & 5 apart)
self.lab_spacer = gtk.Label()
self.table.attach(self.lab_spacer, 3, 5, 3, 4, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_spacer.show()
# label - info
self.lab_info = gtk.Label()
self.table.attach(self.lab_info, 3, 5, 4, 5, xpadding = 0, ypadding = 0, yoptions=gtk.SHRINK)
self.lab_info.show()
# see how many hands are in the db and adjust accordingly # see how many hands are in the db and adjust accordingly
tcursor = self.importer.database.cursor tcursor = self.importer.database.cursor
tcursor.execute("Select count(1) from Hands") tcursor.execute("Select count(1) from Hands")
@ -222,6 +263,9 @@ class GuiBulkImport():
self.cb_dropindexes.set_active(2) self.cb_dropindexes.set_active(2)
self.cb_dropindexes.set_sensitive(False) self.cb_dropindexes.set_sensitive(False)
self.lab_drop.set_sensitive(False) self.lab_drop.set_sensitive(False)
self.cb_drophudcache.set_active(2)
self.cb_drophudcache.set_sensitive(False)
self.lab_hdrop.set_sensitive(False)
def main(argv=None): def main(argv=None):
"""main can also be called in the python interpreter, by supplying the command line as the argument.""" """main can also be called in the python interpreter, by supplying the command line as the argument."""

View File

@ -19,9 +19,15 @@ Set up all of the SQL statements for a given game and database type.
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# NOTES: The sql statements use the placeholder %s for bind variables
# which is then replaced by ? for sqlite. Comments can be included
# within sql statements using C style /* ... */ comments, BUT
# THE COMMENTS MUST NOT INCLUDE %s OR ?.
######################################################################## ########################################################################
# Standard Library modules # Standard Library modules
import re
# pyGTK modules # pyGTK modules
@ -189,11 +195,11 @@ class Sql:
version SMALLINT NOT NULL) version SMALLINT NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)""" self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT NOT NULL)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createSettingsTable'] = """CREATE TABLE Settings self.query['createSettingsTable'] = """CREATE TABLE Settings
(version INTEGER) """ (version INTEGER NOT NULL) """
################################ ################################
@ -290,7 +296,7 @@ class Sql:
name TEXT, name TEXT,
siteId INTEGER, siteId INTEGER,
comment TEXT, comment TEXT,
commentTs BLOB, commentTs REAL,
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)""" FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
@ -318,7 +324,14 @@ class Sql:
ratingTime timestamp without time zone, ratingTime timestamp without time zone,
handCount int)""" handCount int)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createAutoratesTable'] = """ """ self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
id INTEGER PRIMARY KEY,
playerId INT,
gametypeId INT,
description TEXT,
shortDesc TEXT,
ratingTime REAL,
handCount int)"""
################################ ################################
@ -400,12 +413,12 @@ class Sql:
tableName TEXT(20), tableName TEXT(20),
siteHandNo INTEGER, siteHandNo INTEGER,
gametypeId INTEGER, gametypeId INTEGER,
handStart BLOB, handStart REAL,
importTime BLOB, importTime REAL,
seats INTEGER, seats INTEGER,
maxSeats INTEGER, maxSeats INTEGER,
comment TEXT, comment TEXT,
commentTs BLOB, commentTs REAL,
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)""" FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
@ -425,14 +438,19 @@ class Sql:
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId INT NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
buyin INT, buyin INT NOT NULL,
fee INT, fee INT NOT NULL,
knockout INT, knockout INT NOT NULL,
rebuyOrAddon BOOLEAN)""" rebuyOrAddon BOOLEAN NOT NULL)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createTourneyTypesTable'] = """ """ self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id INTEGER PRIMARY KEY,
siteId INT NOT NULL,
buyin INT NOT NULL,
fee INT NOT NULL,
knockout INT NOT NULL,
rebuyOrAddon BOOLEAN NOT NULL)"""
################################ ################################
# Create Tourneys # Create Tourneys
@ -460,15 +478,15 @@ class Sql:
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createTourneysTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
siteId INTEGER, tourneyTypeId INT,
buyin INTEGER, siteTourneyNo INT,
fee INTEGER, entries INT,
knockout INTEGER, prizepool INT,
rebuyOrAddon BOOL, startTime REAL,
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)""" comment TEXT,
commentTs REAL)"""
################################ ################################
# Create HandsPlayers # Create HandsPlayers
################################ ################################
@ -709,7 +727,121 @@ class Sql:
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))""" FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createHandsPlayersTable'] = """ """ self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
id INTEGER PRIMARY KEY,
handId INT NOT NULL,
playerId INT NOT NULL,
startCash INT NOT NULL,
position TEXT,
seatNo INT NOT NULL,
card1 INT NOT NULL, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */
card2 INT NOT NULL,
card3 INT,
card4 INT,
card5 INT,
card6 INT,
card7 INT,
startCards INT,
ante INT,
winnings INT NOT NULL,
rake INT NOT NULL,
totalProfit INT,
comment TEXT,
commentTs REAL,
tourneysPlayersId INT,
tourneyTypeId INT NOT NULL,
wonWhenSeenStreet1 REAL,
wonWhenSeenStreet2 REAL,
wonWhenSeenStreet3 REAL,
wonWhenSeenStreet4 REAL,
wonAtSD REAL,
street0VPI INT,
street0Aggr INT,
street0_3BChance INT,
street0_3BDone INT,
street0_4BChance INT,
street0_4BDone INT,
other3BStreet0 INT,
other4BStreet0 INT,
street1Seen INT,
street2Seen INT,
street3Seen INT,
street4Seen INT,
sawShowdown INT,
street1Aggr INT,
street2Aggr INT,
street3Aggr INT,
street4Aggr INT,
otherRaisedStreet0 INT,
otherRaisedStreet1 INT,
otherRaisedStreet2 INT,
otherRaisedStreet3 INT,
otherRaisedStreet4 INT,
foldToOtherRaisedStreet0 INT,
foldToOtherRaisedStreet1 INT,
foldToOtherRaisedStreet2 INT,
foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT,
stealAttemptChance INT,
stealAttempted INT,
foldBbToStealChance INT,
foldedBbToSteal INT,
foldSbToStealChance INT,
foldedSbToSteal INT,
street1CBChance INT,
street1CBDone INT,
street2CBChance INT,
street2CBDone INT,
street3CBChance INT,
street3CBDone INT,
street4CBChance INT,
street4CBDone INT,
foldToStreet1CBChance INT,
foldToStreet1CBDone INT,
foldToStreet2CBChance INT,
foldToStreet2CBDone INT,
foldToStreet3CBChance INT,
foldToStreet3CBDone INT,
foldToStreet4CBChance INT,
foldToStreet4CBDone INT,
street1CheckCallRaiseChance INT,
street1CheckCallRaiseDone INT,
street2CheckCallRaiseChance INT,
street2CheckCallRaiseDone INT,
street3CheckCallRaiseChance INT,
street3CheckCallRaiseDone INT,
street4CheckCallRaiseChance INT,
street4CheckCallRaiseDone INT,
street0Calls INT,
street1Calls INT,
street2Calls INT,
street3Calls INT,
street4Calls INT,
street0Bets INT,
street1Bets INT,
street2Bets INT,
street3Bets INT,
street4Bets INT,
street0Raises INT,
street1Raises INT,
street2Raises INT,
street3Raises INT,
street4Raises INT,
actionString REAL)
"""
################################ ################################
@ -977,7 +1109,105 @@ class Sql:
street4Raises INT) street4Raises INT)
""" """
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createHudCacheTable'] = """ """ self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
id INTEGER PRIMARY KEY,
gametypeId INT,
playerId INT,
activeSeats INT,
position TEXT,
tourneyTypeId INT,
styleKey TEXT NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
HDs INT,
wonWhenSeenStreet1 REAL NOT NULL,
wonWhenSeenStreet2 REAL,
wonWhenSeenStreet3 REAL,
wonWhenSeenStreet4 REAL,
wonAtSD REAL NOT NULL,
street0VPI INT NOT NULL,
street0Aggr INT,
street0_3BChance INT NOT NULL,
street0_3BDone INT NOT NULL,
street0_4BChance INT,
street0_4BDone INT,
other3BStreet0 INT,
other4BStreet0 INT,
street1Seen INT,
street2Seen INT,
street3Seen INT,
street4Seen INT,
sawShowdown INT,
street1Aggr INT,
street2Aggr INT,
street3Aggr INT,
street4Aggr INT,
otherRaisedStreet0 INT,
otherRaisedStreet1 INT,
otherRaisedStreet2 INT,
otherRaisedStreet3 INT,
otherRaisedStreet4 INT,
foldToOtherRaisedStreet0 INT,
foldToOtherRaisedStreet1 INT,
foldToOtherRaisedStreet2 INT,
foldToOtherRaisedStreet3 INT,
foldToOtherRaisedStreet4 INT,
stealAttemptChance INT,
stealAttempted INT,
foldBbToStealChance INT,
foldedBbToSteal INT,
foldSbToStealChance INT,
foldedSbToSteal INT,
street1CBChance INT,
street1CBDone INT,
street2CBChance INT,
street2CBDone INT,
street3CBChance INT,
street3CBDone INT,
street4CBChance INT,
street4CBDone INT,
foldToStreet1CBChance INT,
foldToStreet1CBDone INT,
foldToStreet2CBChance INT,
foldToStreet2CBDone INT,
foldToStreet3CBChance INT,
foldToStreet3CBDone INT,
foldToStreet4CBChance INT,
foldToStreet4CBDone INT,
totalProfit INT,
street1CheckCallRaiseChance INT,
street1CheckCallRaiseDone INT,
street2CheckCallRaiseChance INT,
street2CheckCallRaiseDone INT,
street3CheckCallRaiseChance INT,
street3CheckCallRaiseDone INT,
street4CheckCallRaiseChance INT,
street4CheckCallRaiseDone INT,
street0Calls INT,
street1Calls INT,
street2Calls INT,
street3Calls INT,
street4Calls INT,
street0Bets INT,
street1Bets INT,
street2Bets INT,
street3Bets INT,
street4Bets INT,
street0Raises INT,
street1Raises INT,
street2Raises INT,
street3Raises INT,
street4Raises INT)
"""
if db_server == 'mysql': if db_server == 'mysql':
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)""" self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
@ -1004,9 +1234,10 @@ class Sql:
self.query['get_last_hand'] = "select max(id) from Hands" self.query['get_last_hand'] = "select max(id) from Hands"
self.query['get_player_id'] = """ self.query['get_player_id'] = """
select Players.id AS player_id from Players, Sites select Players.id AS player_id
where Players.name = %(player)s from Players, Sites
and Sites.name = %(site)s where Players.name = %s
and Sites.name = %s
and Players.SiteId = Sites.id and Players.SiteId = Sites.id
""" """
@ -1081,7 +1312,7 @@ class Sql:
AND hc.styleKey > %s AND hc.styleKey > %s
/* styleKey is currently 'd' (for date) followed by a yyyymmdd /* styleKey is currently 'd' (for date) followed by a yyyymmdd
date key. Set it to 0000000 or similar to get all records */ date key. Set it to 0000000 or similar to get all records */
/* also check activeseats here? even if only 3 groups eg 2-3/4-6/7+ ?? /* also check activeseats here even if only 3 groups eg 2-3/4-6/7+
e.g. could use a multiplier: e.g. could use a multiplier:
AND h.seats > X / 1.25 and hp.seats < X * 1.25 AND h.seats > X / 1.25 and hp.seats < X * 1.25
where X is the number of active players at the current table (and where X is the number of active players at the current table (and
@ -1164,7 +1395,7 @@ class Sql:
date key. Set it to 0000000 or similar to get all records */ date key. Set it to 0000000 or similar to get all records */
/* Note: s means the placeholder 'percent's but we can't include that /* Note: s means the placeholder 'percent's but we can't include that
in comments. (db api thinks they are actual arguments) in comments. (db api thinks they are actual arguments)
Could also check activeseats here? even if only 3 groups eg 2-3/4-6/7+ ?? Could also check activeseats here even if only 3 groups eg 2-3/4-6/7+
e.g. could use a multiplier: e.g. could use a multiplier:
AND h.seats > s / 1.25 and hp.seats < s * 1.25 AND h.seats > s / 1.25 and hp.seats < s * 1.25
where s is the number of active players at the current table (and where s is the number of active players at the current table (and
@ -1252,7 +1483,7 @@ class Sql:
INNER JOIN HandsPlayers hp2 ON (hp2.playerId+0 = hp.playerId+0 AND (hp2.handId = h2.id+0)) /* other hands by these players */ INNER JOIN HandsPlayers hp2 ON (hp2.playerId+0 = hp.playerId+0 AND (hp2.handId = h2.id+0)) /* other hands by these players */
INNER JOIN Players p ON (p.id = hp2.PlayerId+0) INNER JOIN Players p ON (p.id = hp2.PlayerId+0)
WHERE hp.handId = %s WHERE hp.handId = %s
/* check activeseats once this data returned? (don't want to do that here as it might /* check activeseats once this data returned (don't want to do that here as it might
assume a session ended just because the number of seats dipped for a few hands) assume a session ended just because the number of seats dipped for a few hands)
*/ */
ORDER BY h.handStart desc, hp2.PlayerId ORDER BY h.handStart desc, hp2.PlayerId
@ -1331,7 +1562,7 @@ class Sql:
AND hp2.handId = h2.id) /* other hands by these players */ AND hp2.handId = h2.id) /* other hands by these players */
INNER JOIN Players p ON (p.id = hp2.PlayerId+0) INNER JOIN Players p ON (p.id = hp2.PlayerId+0)
WHERE h.id = %s WHERE h.id = %s
/* check activeseats once this data returned? (don't want to do that here as it might /* check activeseats once this data returned (don't want to do that here as it might
assume a session ended just because the number of seats dipped for a few hands) assume a session ended just because the number of seats dipped for a few hands)
*/ */
ORDER BY h.handStart desc, hp2.PlayerId ORDER BY h.handStart desc, hp2.PlayerId
@ -2450,6 +2681,10 @@ class Sql:
else: # assume postgres else: # assume postgres
self.query['lockForInsert'] = "" self.query['lockForInsert'] = ""
if db_server == 'sqlite':
for k,q in self.query.iteritems():
self.query[k] = re.sub('%s','?',q)
if __name__== "__main__": if __name__== "__main__":
# just print the default queries and exit # just print the default queries and exit
s = Sql(game = 'razz', type = 'ptracks') s = Sql(game = 'razz', type = 'ptracks')

View File

@ -64,7 +64,7 @@ class fpdb_db:
if backend==fpdb_db.MYSQL_INNODB: if backend==fpdb_db.MYSQL_INNODB:
import MySQLdb import MySQLdb
try: try:
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True) self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True, charset="utf8")
except: except:
raise fpdb_simple.FpdbError("MySQL connection failed") raise fpdb_simple.FpdbError("MySQL connection failed")
elif backend==fpdb_db.PGSQL: elif backend==fpdb_db.PGSQL:
@ -155,7 +155,7 @@ class fpdb_db:
return (self.host, self.database, self.user, self.password) return (self.host, self.database, self.user, self.password)
#end def get_db_info #end def get_db_info
def getLastInsertId(self): def getLastInsertId(self, cursor=None):
try: try:
if self.backend == self.MYSQL_INNODB: if self.backend == self.MYSQL_INNODB:
ret = self.db.insert_id() ret = self.db.insert_id()
@ -177,9 +177,7 @@ class fpdb_db:
else: else:
ret = row[0] ret = row[0]
elif self.backend == fpdb_db.SQLITE: elif self.backend == fpdb_db.SQLITE:
# don't know how to do this in sqlite ret = cursor.lastrowid
print "getLastInsertId(): not coded for sqlite yet"
ret = -1
else: else:
print "getLastInsertId(): unknown backend ", self.backend print "getLastInsertId(): unknown backend ", self.backend
ret = -1 ret = -1

View File

@ -78,19 +78,18 @@ class Importer:
#Set defaults #Set defaults
self.callHud = self.config.get_import_parameters().get("callFpdbHud") self.callHud = self.config.get_import_parameters().get("callFpdbHud")
# CONFIGURATION OPTIONS - update allowHudcacheRebuild and forceThreads for faster imports # CONFIGURATION OPTIONS
self.settings.setdefault("minPrint", 30) self.settings.setdefault("minPrint", 30)
self.settings.setdefault("handCount", 0) self.settings.setdefault("handCount", 0)
self.settings.setdefault("allowHudcacheRebuild", False) # if True speeds up big imports a lot, also #self.settings.setdefault("allowHudcacheRebuild", True) # NOT USED NOW
# stops deadlock problems with threaded imports #self.settings.setdefault("forceThreads", 2) # NOT USED NOW
self.settings.setdefault("forceThreads", 0) # set to 1/2/more for faster imports
self.settings.setdefault("writeQSize", 1000) # no need to change self.settings.setdefault("writeQSize", 1000) # no need to change
self.settings.setdefault("writeQMaxWait", 10) # not used self.settings.setdefault("writeQMaxWait", 10) # not used
self.writeq = None self.writeq = None
self.database = Database.Database(self.config, sql = self.sql) self.database = Database.Database(self.config, sql = self.sql)
self.writerdbs = [] self.writerdbs = []
self.settings.setdefault("threads", 1) # value overridden by GuiBulkImport - use forceThreads above self.settings.setdefault("threads", 1) # value set by GuiBulkImport
for i in xrange(self.settings['threads']): for i in xrange(self.settings['threads']):
self.writerdbs.append( Database.Database(self.config, sql = self.sql) ) self.writerdbs.append( Database.Database(self.config, sql = self.sql) )
@ -124,6 +123,9 @@ class Importer:
def setDropIndexes(self, value): def setDropIndexes(self, value):
self.settings['dropIndexes'] = value self.settings['dropIndexes'] = value
def setDropHudCache(self, value):
self.settings['dropHudCache'] = value
# def setWatchTime(self): # def setWatchTime(self):
# self.updated = time() # self.updated = time()
@ -186,8 +188,8 @@ class Importer:
def runImport(self): def runImport(self):
""""Run full import on self.filelist. This is called from GuiBulkImport.py""" """"Run full import on self.filelist. This is called from GuiBulkImport.py"""
if self.settings['forceThreads'] > 0: # use forceThreads until threading enabled in GuiBulkImport #if self.settings['forceThreads'] > 0: # use forceThreads until threading enabled in GuiBulkImport
self.setThreads(self.settings['forceThreads']) # self.setThreads(self.settings['forceThreads'])
# Initial setup # Initial setup
start = datetime.datetime.now() start = datetime.datetime.now()
@ -195,7 +197,7 @@ class Importer:
print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes'] print "Started at", start, "--", len(self.filelist), "files to import.", self.settings['dropIndexes']
if self.settings['dropIndexes'] == 'auto': if self.settings['dropIndexes'] == 'auto':
self.settings['dropIndexes'] = self.calculate_auto2(self.database, 12.0, 500.0) self.settings['dropIndexes'] = self.calculate_auto2(self.database, 12.0, 500.0)
if self.settings['allowHudcacheRebuild']: if self.settings['dropHudCache'] == 'auto':
self.settings['dropHudCache'] = self.calculate_auto2(self.database, 25.0, 500.0) # returns "drop"/"don't drop" self.settings['dropHudCache'] = self.calculate_auto2(self.database, 25.0, 500.0) # returns "drop"/"don't drop"
if self.settings['dropIndexes'] == 'drop': if self.settings['dropIndexes'] == 'drop':
@ -237,7 +239,7 @@ class Importer:
self.database.afterBulkImport() self.database.afterBulkImport()
else: else:
print "No need to rebuild indexes." print "No need to rebuild indexes."
if self.settings['allowHudcacheRebuild'] and self.settings['dropHudCache'] == 'drop': if self.settings['dropHudCache'] == 'drop':
self.database.rebuild_hudcache() self.database.rebuild_hudcache()
else: else:
print "No need to rebuild hudcache." print "No need to rebuild hudcache."

View File

@ -49,37 +49,6 @@ class FpdbError(Exception):
def __str__(self): def __str__(self):
return repr(self.value) return repr(self.value)
# gets value for last auto-increment key generated
# returns -1 if a problem occurs
def getLastInsertId(backend, conn, cursor):
if backend == MYSQL_INNODB:
ret = conn.insert_id()
if ret < 1 or ret > 999999999:
print "getLastInsertId(): problem fetching insert_id? ret=", ret
ret = -1
elif backend == PGSQL:
# some options:
# currval(hands_id_seq) - use name of implicit seq here
# lastval() - still needs sequences set up?
# insert ... returning is useful syntax (but postgres specific?)
# see rules (fancy trigger type things)
cursor.execute ("SELECT lastval()")
row = cursor.fetchone()
if not row:
print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row
ret = -1
else:
ret = row[0]
elif backend == SQLITE:
# don't know how to do this in sqlite
print "getLastInsertId(): not coded for sqlite yet"
ret = -1
else:
print "getLastInsertId(): unknown backend ", backend
ret = -1
return ret
#end def getLastInsertId
#returns an array of the total money paid. intending to add rebuys/addons here #returns an array of the total money paid. intending to add rebuys/addons here
def calcPayin(count, buyin, fee): def calcPayin(count, buyin, fee):
return [buyin + fee for i in xrange(count)] return [buyin + fee for i in xrange(count)]