From 6de41be9c99e673c8a91879370f41cbe6d8226c2 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Thu, 6 Aug 2009 20:31:46 +0100 Subject: [PATCH] mainly sqlite fixes, also removed not null on many hudcache columns --- pyfpdb/Database.py | 262 +++++++++++++++++++-------- pyfpdb/SQL.py | 355 +++++++++++++++++++++++++++++-------- pyfpdb/fpdb_db.py | 101 ----------- pyfpdb/fpdb_parse_logic.py | 6 +- pyfpdb/fpdb_simple.py | 48 +++-- 5 files changed, 497 insertions(+), 275 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 7c2b9ecc..5c071a85 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -98,7 +98,7 @@ class Database: foreignKeys = [ [ ] # no db with index 0 , [ ] # no db with index 1 - , [ # foreign keys for mysql + , [ # foreign keys for mysql (index 2) {'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} @@ -107,7 +107,7 @@ class Database: , {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0} , {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1} ] - , [ # foreign keys for postgres + , [ # foreign keys for postgres (index 3) {'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} @@ -116,6 +116,8 @@ class Database: , {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0} , {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1} ] + , [ # no foreign keys in sqlite (index 4) + ] ] @@ -233,9 +235,15 @@ class Database: self.fdb.reconnect(due_to_error=False) def get_backend_name(self): - """Reconnects the DB""" - return self.fdb.get_backend_name() - + """Returns the name of the currently used backend""" + if self.backend==2: + return "MySQL InnoDB" + elif self.backend==3: + return "PostgreSQL" + elif self.backend==4: + return "SQLite" + else: + raise fpdb_simple.FpdbError("invalid backend") def get_table_name(self, hand_id): c = self.connection.cursor() @@ -465,11 +473,39 @@ class Database: result = c.fetchall() return result - def get_last_insert_id(self): + def get_last_insert_id(self, cursor=None): + ret = None try: - ret = self.fdb.getLastInsertId() + if self.backend == self.MYSQL_INNODB: + ret = self.connection.insert_id() + if ret < 1 or ret > 999999999: + print "getLastInsertId(): problem fetching insert_id? ret=", ret + ret = -1 + elif self.backend == self.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) + c = self.get_cursor() + ret = c.execute ("SELECT lastval()") + row = c.fetchone() + if not row: + print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row + ret = -1 + else: + ret = row[0] + elif self.backend == self.SQLITE: + ret = cursor.lastrowid + else: + print "getLastInsertId(): unknown backend ", self.backend + ret = -1 except: - print "get_last_insert_id error:", str(sys.exc_value) + ret = -1 + err = traceback.extract_tb(sys.exc_info()[2]) + print "***get_last_insert_id error: " + str(sys.exc_info()[1]) + print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] ) + raise return ret @@ -847,6 +883,7 @@ class Database: self.commit() except: + err = traceback.extract_tb(sys.exc_info()[2])[-1] print "***Error dropping tables: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) self.rollback() raise @@ -996,15 +1033,21 @@ class Database: def insertPlayer(self, name, site_id): result = None c = self.get_cursor() - c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) - tmp=c.fetchall() + c.execute ("SELECT id FROM Players WHERE name=%s".replace('%s',self.sql.query['placeholder']) + ,(name,)) + tmp = c.fetchone() 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)".replace('%s',self.sql.query['placeholder']) + ,(name, site_id)) #Get last id might be faster here. - c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) - tmp=c.fetchall() - return tmp[0][0] + #c.execute ("SELECT id FROM Players WHERE name=%s", (name,)) + tmp = [self.get_last_insert_id(c)] + return tmp[0] + def insertGameTypes(self, row): + c = self.get_cursor() + c.execute( self.sql.query['insertGameTypes'], row ) + return [self.get_last_insert_id(c)] def store_the_hand(self, h): """Take a HandToWrite object and store it in the db""" @@ -1064,6 +1107,76 @@ class Database: return result #end def store_the_hand + def storeHand(self, p): + #stores into table hands: + self.cursor.execute ("""INSERT INTO Hands ( + tablename, + sitehandno, + gametypeid, + handstart, + importtime, + seats, + maxseats, + boardcard1, + boardcard2, + boardcard3, + boardcard4, + boardcard5, +-- texture, + playersVpi, + playersAtStreet1, + playersAtStreet2, + playersAtStreet3, + playersAtStreet4, + playersAtShowdown, + street0Raises, + street1Raises, + street2Raises, + street3Raises, + street4Raises, +-- street1Pot, +-- street2Pot, +-- street3Pot, +-- street4Pot, +-- showdownPot + ) + VALUES + (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, + %s, %s, %s, %s, %s, %s, %s)""", + ( + p['tablename'], + p['sitehandno'], + p['gametypeid'], + p['handStart'], + datetime.datetime.today(), + len(p['names']), + p['maxSeats'], + p['boardcard1'], + p['boardcard2'], + p['boardcard3'], + p['boardcard4'], + p['boardcard5'], + hudCache['playersVpi'], + hudCache['playersAtStreet1'], + hudCache['playersAtStreet2'], + hudCache['playersAtStreet3'], + hudCache['playersAtStreet4'], + hudCache['playersAtShowdown'], + hudCache['street0Raises'], + hudCache['street1Raises'], + hudCache['street2Raises'], + hudCache['street3Raises'], + hudCache['street4Raises'], + hudCache['street1Pot'], + hudCache['street2Pot'], + hudCache['street3Pot'], + hudCache['street4Pot'], + hudCache['showdownPot'] + ) + ) + #return getLastInsertId(backend, conn, cursor) + # def storeHand + def storeHands(self, backend, site_hand_no, gametype_id ,hand_start_time, names, tableName, maxSeats, hudCache ,board_values, board_suits): @@ -1071,30 +1184,31 @@ class Database: cards = [Card.cardFromValueSuit(v,s) for v,s in zip(board_values,board_suits)] #stores into table hands: try: - self.get_cursor().execute ("""INSERT INTO Hands - (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats - ,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5 - ,playersVpi, playersAtStreet1, playersAtStreet2 - ,playersAtStreet3, playersAtStreet4, playersAtShowdown - ,street0Raises, street1Raises, street2Raises - ,street3Raises, street4Raises, street1Pot - ,street2Pot, street3Pot, street4Pot - ,showdownPot - ) - VALUES - (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) - """ - , (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats - ,cards[0], cards[1], cards[2], cards[3], cards[4] - ,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2'] - ,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown'] - ,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises'] - ,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot'] - ,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot'] - ,hudCache['showdownPot'] - )) - ret = self.get_last_insert_id() + c = self.get_cursor() + c.execute ("""INSERT INTO Hands + (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats + ,boardcard1,boardcard2,boardcard3,boardcard4,boardcard5 + ,playersVpi, playersAtStreet1, playersAtStreet2 + ,playersAtStreet3, playersAtStreet4, playersAtShowdown + ,street0Raises, street1Raises, street2Raises + ,street3Raises, street4Raises, street1Pot + ,street2Pot, street3Pot, street4Pot + ,showdownPot + ) + VALUES + (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, + %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + """.replace('%s', self.sql.query['placeholder']) + , (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.today(), maxSeats + ,cards[0], cards[1], cards[2], cards[3], cards[4] + ,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2'] + ,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown'] + ,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises'] + ,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot'] + ,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot'] + ,hudCache['showdownPot'] + )) + ret = self.get_last_insert_id(c) except: ret = -1 raise fpdb_simple.FpdbError( "storeHands error: " + str(sys.exc_value) ) @@ -1163,7 +1277,8 @@ class Database: hudCache['street0Calls'][i], hudCache['street1Calls'][i], hudCache['street2Calls'][i], hudCache['street3Calls'][i], hudCache['street4Calls'][i], hudCache['street0Bets'][i], hudCache['street1Bets'][i], hudCache['street2Bets'][i], hudCache['street3Bets'][i], hudCache['street4Bets'][i] ) ) - self.get_cursor().executemany (""" + c = self.get_cursor() + c.executemany (""" INSERT INTO HandsPlayers (handId, playerId, startCash, position, tourneyTypeId, card1, card2, card3, card4, startCards, winnings, rake, seatNo, totalProfit, @@ -1186,13 +1301,9 @@ class Database: VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" + %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) ,inserts ) - result.append( self.get_last_insert_id() ) - - #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) - #result.append(cursor.fetchall()[0][0]) - result.append( self.get_last_insert_id() ) + result.append( self.get_last_insert_id(c) ) # wrong? not used currently except: raise fpdb_simple.FpdbError( "store_hands_players_holdem_omaha error: " + str(sys.exc_value) ) @@ -1215,13 +1326,14 @@ class Database: card6 = Card.cardFromValueSuit(card_values[i][5], card_suits[i][5]) card7 = Card.cardFromValueSuit(card_values[i][6], card_suits[i][6]) - self.get_cursor().execute ("""INSERT INTO HandsPlayers + c = self.get_cursor() + c.execute ("""INSERT INTO HandsPlayers (handId, playerId, startCash, ante, tourneyTypeId, card1, card2, card3, card4, card5, card6, card7, winnings, rake, seatNo) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']), (hands_id, player_ids[i], start_cashes[i], antes[i], 1, card1, card2, card3, card4, @@ -1229,7 +1341,7 @@ class Database: card7, winnings[i], rakes[i], seatNos[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) #result.append(cursor.fetchall()[0][0]) - result.append( self.get_last_insert_id() ) + result.append( self.get_last_insert_id(c) ) except: raise fpdb_simple.FpdbError( "store_hands_players_stud error: " + str(sys.exc_value) ) @@ -1292,7 +1404,8 @@ class Database: hudCache['street3Bets'][i], hudCache['street4Bets'][i] ) ) - self.get_cursor().executemany (""" + c = self.get_cursor() + c.executemany (""" INSERT INTO HandsPlayers (handId, playerId, startCash, position, tourneyTypeId, card1, card2, card3, card4, startCards, winnings, rake, tourneysPlayersId, seatNo, totalProfit, @@ -1316,10 +1429,10 @@ class Database: (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" + %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) ,inserts ) - result.append( self.get_last_insert_id() ) + result.append( self.get_last_insert_id(c) ) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) #result.append(cursor.fetchall()[0][0]) except: @@ -1335,14 +1448,15 @@ class Database: try: result=[] for i in xrange(len(player_ids)): - self.get_cursor().execute ("""INSERT INTO HandsPlayers + c = self.get_cursor() + c.execute ("""INSERT INTO HandsPlayers (handId, playerId, startCash, ante, card1Value, card1Suit, card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit, card5Value, card5Suit, card6Value, card6Suit, card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s, %s, %s)""", + %s, %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']), (hands_id, player_ids[i], start_cashes[i], antes[i], card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1], card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3], @@ -1350,7 +1464,7 @@ class Database: card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i])) #result.append(cursor.fetchall()[0][0]) - result.append( self.get_last_insert_id() ) + result.append( self.get_last_insert_id(c) ) except: raise fpdb_simple.FpdbError( "store_hands_players_stud_tourney error: " + str(sys.exc_value) ) @@ -1488,18 +1602,19 @@ class Database: AND position=%s AND tourneyTypeId+0=%s AND styleKey=%s - """, (row[6], row[7], row[8], row[9], row[10], - row[11], row[12], row[13], row[14], row[15], - row[16], row[17], row[18], row[19], row[20], - row[21], row[22], row[23], row[24], row[25], - row[26], row[27], row[28], row[29], row[30], - row[31], row[32], row[33], row[34], row[35], - row[36], row[37], row[38], row[39], row[40], - row[41], row[42], row[43], row[44], row[45], - row[46], row[47], row[48], row[49], row[50], - row[51], row[52], row[53], row[54], row[55], - row[56], row[57], row[58], row[59], row[60], - row[1], row[2], row[3], str(row[4]), row[5], styleKey)) + """.replace('%s', self.sql.query['placeholder']) + ,(row[6], row[7], row[8], row[9], row[10], + row[11], row[12], row[13], row[14], row[15], + row[16], row[17], row[18], row[19], row[20], + row[21], row[22], row[23], row[24], row[25], + row[26], row[27], row[28], row[29], row[30], + row[31], row[32], row[33], row[34], row[35], + row[36], row[37], row[38], row[39], row[40], + row[41], row[42], row[43], row[44], row[45], + row[46], row[47], row[48], row[49], row[50], + row[51], row[52], row[53], row[54], row[55], + row[56], row[57], row[58], row[59], row[60], + row[1], row[2], row[3], str(row[4]), row[5], styleKey)) # Test statusmessage to see if update worked, do insert if not #print "storehud2, upd num =", num if ( (backend == self.PGSQL and cursor.statusmessage != "UPDATE 1") @@ -1529,7 +1644,7 @@ class Database: %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s, %s)""" + %s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) , (row[1], row[2], row[3], row[4], row[5], styleKey, row[6], row[7], row[8], row[9], row[10] ,row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20] ,row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30] @@ -1552,7 +1667,8 @@ class Database: def store_tourneys(self, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime): try: cursor = self.get_cursor() - cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId)) + cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s".replace('%s', self.sql.query['placeholder']) + , (siteTourneyNo, tourneyTypeId)) tmp=cursor.fetchone() #print "tried SELECTing tourneys.id, result:",tmp @@ -1561,7 +1677,8 @@ class Database: except TypeError:#means we have to create new one cursor.execute("""INSERT INTO Tourneys (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime) - VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)) + VALUES (%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']) + ,(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)) cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId)) tmp=cursor.fetchone() #print "created new tourneys.id:",tmp @@ -1581,7 +1698,8 @@ class Database: #print "ranks:",ranks #print "winnings:",winnings for i in xrange(len(player_ids)): - cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i])) + cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s".replace('%s', self.sql.query['placeholder']) + ,(tourney_id, player_ids[i])) tmp=cursor.fetchone() #print "tried SELECTing tourneys_players.id:",tmp @@ -1589,10 +1707,10 @@ class Database: len(tmp) except TypeError: cursor.execute("""INSERT INTO TourneysPlayers - (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""", + (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""".replace('%s', self.sql.query['placeholder']), (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i])) - cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", + cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s".replace('%s', self.sql.query['placeholder']), (tourney_id, player_ids[i])) tmp=cursor.fetchone() #print "created new tourneys_players.id:",tmp diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 972bf615..a5be2878 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -410,16 +410,37 @@ class Sql: elif db_server == 'sqlite': self.query['createHandsTable'] = """CREATE TABLE Hands ( id INTEGER PRIMARY KEY, - tableName TEXT(20), - siteHandNo INTEGER, - gametypeId INTEGER, - handStart REAL, - importTime REAL, - seats INTEGER, - maxSeats INTEGER, + tableName TEXT(20) NOT NULL, + siteHandNo INT NOT NULL, + gametypeId INT NOT NULL, + handStart REAL NOT NULL, + importTime REAL NOT NULL, + seats INT NOT NULL, + maxSeats INT NOT NULL, + boardcard1 INT, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */ + boardcard2 INT, + boardcard3 INT, + boardcard4 INT, + boardcard5 INT, + texture INT, + playersVpi INT NOT NULL, /* num of players vpi */ + playersAtStreet1 INT NOT NULL, /* num of players seeing flop/street4 */ + playersAtStreet2 INT NOT NULL, + playersAtStreet3 INT NOT NULL, + playersAtStreet4 INT NOT NULL, + playersAtShowdown INT NOT NULL, + street0Raises INT NOT NULL, /* num small bets paid to see flop/street4, including blind */ + street1Raises INT NOT NULL, /* num small bets paid to see turn/street5 */ + street2Raises INT NOT NULL, /* num big bets paid to see river/street6 */ + street3Raises INT NOT NULL, /* num big bets paid to see sd/street7 */ + street4Raises INT NOT NULL, /* num big bets paid to see showdown */ + street1Pot INT, /* pot size at flop/street4 */ + street2Pot INT, /* pot size at turn/street5 */ + street3Pot INT, /* pot size at river/street6 */ + street4Pot INT, /* pot size at sd/street7 */ + showdownPot INT, /* pot size at sd/street7 */ comment TEXT, - commentTs REAL, - FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)""" + commentTs REAL)""" ################################ @@ -919,78 +940,78 @@ class Sql: styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */ HDs INT NOT NULL, - wonWhenSeenStreet1 FLOAT NOT NULL, + wonWhenSeenStreet1 FLOAT, wonWhenSeenStreet2 FLOAT, wonWhenSeenStreet3 FLOAT, wonWhenSeenStreet4 FLOAT, - wonAtSD FLOAT NOT NULL, + wonAtSD FLOAT, - street0VPI INT NOT NULL, - street0Aggr INT NOT NULL, - street0_3BChance INT NOT NULL, - street0_3BDone INT NOT NULL, + street0VPI INT, + street0Aggr INT, + street0_3BChance INT, + street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, other3BStreet0 INT, other4BStreet0 INT, - street1Seen INT NOT NULL, - street2Seen INT NOT NULL, - street3Seen INT NOT NULL, - street4Seen INT NOT NULL, - sawShowdown INT NOT NULL, + street1Seen INT, + street2Seen INT, + street3Seen INT, + street4Seen INT, + sawShowdown INT, - street1Aggr INT NOT NULL, - street2Aggr INT NOT NULL, - street3Aggr INT NOT NULL, - street4Aggr INT NOT NULL, + street1Aggr INT, + street2Aggr INT, + street3Aggr INT, + street4Aggr INT, otherRaisedStreet0 INT, - otherRaisedStreet1 INT NOT NULL, - otherRaisedStreet2 INT NOT NULL, - otherRaisedStreet3 INT NOT NULL, - otherRaisedStreet4 INT NOT NULL, + otherRaisedStreet1 INT, + otherRaisedStreet2 INT, + otherRaisedStreet3 INT, + otherRaisedStreet4 INT, foldToOtherRaisedStreet0 INT, - foldToOtherRaisedStreet1 INT NOT NULL, - foldToOtherRaisedStreet2 INT NOT NULL, - foldToOtherRaisedStreet3 INT NOT NULL, - foldToOtherRaisedStreet4 INT NOT NULL, + foldToOtherRaisedStreet1 INT, + foldToOtherRaisedStreet2 INT, + foldToOtherRaisedStreet3 INT, + foldToOtherRaisedStreet4 INT, - stealAttemptChance INT NOT NULL, - stealAttempted INT NOT NULL, - foldBbToStealChance INT NOT NULL, - foldedBbToSteal INT NOT NULL, - foldSbToStealChance INT NOT NULL, - foldedSbToSteal INT NOT NULL, + stealAttemptChance INT, + stealAttempted INT, + foldBbToStealChance INT, + foldedBbToSteal INT, + foldSbToStealChance INT, + foldedSbToSteal INT, - street1CBChance INT NOT NULL, - street1CBDone INT NOT NULL, - street2CBChance INT NOT NULL, - street2CBDone INT NOT NULL, - street3CBChance INT NOT NULL, - street3CBDone INT NOT NULL, - street4CBChance INT NOT NULL, - street4CBDone INT NOT NULL, + street1CBChance INT, + street1CBDone INT, + street2CBChance INT, + street2CBDone INT, + street3CBChance INT, + street3CBDone INT, + street4CBChance INT, + street4CBDone INT, - foldToStreet1CBChance INT NOT NULL, - foldToStreet1CBDone INT NOT NULL, - foldToStreet2CBChance INT NOT NULL, - foldToStreet2CBDone INT NOT NULL, - foldToStreet3CBChance INT NOT NULL, - foldToStreet3CBDone INT NOT NULL, - foldToStreet4CBChance INT NOT NULL, - foldToStreet4CBDone INT NOT NULL, + foldToStreet1CBChance INT, + foldToStreet1CBDone INT, + foldToStreet2CBChance INT, + foldToStreet2CBDone INT, + foldToStreet3CBChance INT, + foldToStreet3CBDone INT, + foldToStreet4CBChance INT, + foldToStreet4CBDone INT, - totalProfit INT NOT NULL, + totalProfit INT, - street1CheckCallRaiseChance INT NOT NULL, - street1CheckCallRaiseDone INT NOT NULL, - street2CheckCallRaiseChance INT NOT NULL, - street2CheckCallRaiseDone INT NOT NULL, - street3CheckCallRaiseChance INT NOT NULL, - street3CheckCallRaiseDone INT NOT NULL, - street4CheckCallRaiseChance INT NOT NULL, - street4CheckCallRaiseDone INT NOT NULL, + street1CheckCallRaiseChance INT, + street1CheckCallRaiseDone INT, + street2CheckCallRaiseChance INT, + street2CheckCallRaiseDone INT, + street3CheckCallRaiseChance INT, + street3CheckCallRaiseDone INT, + street4CheckCallRaiseChance INT, + street4CheckCallRaiseDone INT, street0Calls INT, street1Calls INT, @@ -1020,16 +1041,16 @@ class Sql: styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */ HDs INT, - wonWhenSeenStreet1 FLOAT NOT NULL, + wonWhenSeenStreet1 FLOAT, wonWhenSeenStreet2 FLOAT, wonWhenSeenStreet3 FLOAT, wonWhenSeenStreet4 FLOAT, - wonAtSD FLOAT NOT NULL, + wonAtSD FLOAT, - street0VPI INT NOT NULL, + street0VPI INT, street0Aggr INT, - street0_3BChance INT NOT NULL, - street0_3BDone INT NOT NULL, + street0_3BChance INT, + street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, other3BStreet0 INT, @@ -1119,16 +1140,16 @@ class Sql: styleKey TEXT NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */ HDs INT, - wonWhenSeenStreet1 REAL NOT NULL, + wonWhenSeenStreet1 REAL, wonWhenSeenStreet2 REAL, wonWhenSeenStreet3 REAL, wonWhenSeenStreet4 REAL, - wonAtSD REAL NOT NULL, + wonAtSD REAL, - street0VPI INT NOT NULL, + street0VPI INT, street0Aggr INT, - street0_3BChance INT NOT NULL, - street0_3BDone INT NOT NULL, + street0_3BChance INT, + street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, other3BStreet0 INT, @@ -2515,7 +2536,7 @@ class Sql: ,hp.tourneyTypeId ,date_format(h.handStart, 'd%y%m%d') """ - else: # assume postgres + elif db_server == 'postgresql': self.query['rebuildHudCache'] = """ INSERT INTO HudCache (gametypeId @@ -2663,6 +2684,154 @@ class Sql: ,hp.tourneyTypeId ,to_char(h.handStart, 'YYMMDD') """ + else: # assume sqlite + self.query['rebuildHudCache'] = """ + INSERT INTO HudCache + (gametypeId + ,playerId + ,activeSeats + ,position + ,tourneyTypeId + ,styleKey + ,HDs + ,wonWhenSeenStreet1 + ,wonAtSD + ,street0VPI + ,street0Aggr + ,street0_3BChance + ,street0_3BDone + ,street1Seen + ,street2Seen + ,street3Seen + ,street4Seen + ,sawShowdown + ,street1Aggr + ,street2Aggr + ,street3Aggr + ,street4Aggr + ,otherRaisedStreet1 + ,otherRaisedStreet2 + ,otherRaisedStreet3 + ,otherRaisedStreet4 + ,foldToOtherRaisedStreet1 + ,foldToOtherRaisedStreet2 + ,foldToOtherRaisedStreet3 + ,foldToOtherRaisedStreet4 + ,stealAttemptChance + ,stealAttempted + ,foldBbToStealChance + ,foldedBbToSteal + ,foldSbToStealChance + ,foldedSbToSteal + ,street1CBChance + ,street1CBDone + ,street2CBChance + ,street2CBDone + ,street3CBChance + ,street3CBDone + ,street4CBChance + ,street4CBDone + ,foldToStreet1CBChance + ,foldToStreet1CBDone + ,foldToStreet2CBChance + ,foldToStreet2CBDone + ,foldToStreet3CBChance + ,foldToStreet3CBDone + ,foldToStreet4CBChance + ,foldToStreet4CBDone + ,totalProfit + ,street1CheckCallRaiseChance + ,street1CheckCallRaiseDone + ,street2CheckCallRaiseChance + ,street2CheckCallRaiseDone + ,street3CheckCallRaiseChance + ,street3CheckCallRaiseDone + ,street4CheckCallRaiseChance + ,street4CheckCallRaiseDone + ) + SELECT h.gametypeId + ,hp.playerId + ,h.seats + ,case when hp.position = 'B' then 'B' + when hp.position = 'S' then 'S' + when hp.position = '0' then 'D' + when hp.position = '1' then 'C' + when hp.position = '2' then 'M' + when hp.position = '3' then 'M' + when hp.position = '4' then 'M' + when hp.position = '5' then 'E' + when hp.position = '6' then 'E' + when hp.position = '7' then 'E' + when hp.position = '8' then 'E' + when hp.position = '9' then 'E' + else 'E' + end AS hc_position + ,hp.tourneyTypeId + ,'d' || substr(strftime('%Y%m%d', h.handStart),3) + ,count(1) + ,sum(wonWhenSeenStreet1) + ,sum(wonAtSD) + ,sum(CAST(street0VPI as integer)) + ,sum(CAST(street0Aggr as integer)) + ,sum(CAST(street0_3BChance as integer)) + ,sum(CAST(street0_3BDone as integer)) + ,sum(CAST(street1Seen as integer)) + ,sum(CAST(street2Seen as integer)) + ,sum(CAST(street3Seen as integer)) + ,sum(CAST(street4Seen as integer)) + ,sum(CAST(sawShowdown as integer)) + ,sum(CAST(street1Aggr as integer)) + ,sum(CAST(street2Aggr as integer)) + ,sum(CAST(street3Aggr as integer)) + ,sum(CAST(street4Aggr as integer)) + ,sum(CAST(otherRaisedStreet1 as integer)) + ,sum(CAST(otherRaisedStreet2 as integer)) + ,sum(CAST(otherRaisedStreet3 as integer)) + ,sum(CAST(otherRaisedStreet4 as integer)) + ,sum(CAST(foldToOtherRaisedStreet1 as integer)) + ,sum(CAST(foldToOtherRaisedStreet2 as integer)) + ,sum(CAST(foldToOtherRaisedStreet3 as integer)) + ,sum(CAST(foldToOtherRaisedStreet4 as integer)) + ,sum(CAST(stealAttemptChance as integer)) + ,sum(CAST(stealAttempted as integer)) + ,sum(CAST(foldBbToStealChance as integer)) + ,sum(CAST(foldedBbToSteal as integer)) + ,sum(CAST(foldSbToStealChance as integer)) + ,sum(CAST(foldedSbToSteal as integer)) + ,sum(CAST(street1CBChance as integer)) + ,sum(CAST(street1CBDone as integer)) + ,sum(CAST(street2CBChance as integer)) + ,sum(CAST(street2CBDone as integer)) + ,sum(CAST(street3CBChance as integer)) + ,sum(CAST(street3CBDone as integer)) + ,sum(CAST(street4CBChance as integer)) + ,sum(CAST(street4CBDone as integer)) + ,sum(CAST(foldToStreet1CBChance as integer)) + ,sum(CAST(foldToStreet1CBDone as integer)) + ,sum(CAST(foldToStreet2CBChance as integer)) + ,sum(CAST(foldToStreet2CBDone as integer)) + ,sum(CAST(foldToStreet3CBChance as integer)) + ,sum(CAST(foldToStreet3CBDone as integer)) + ,sum(CAST(foldToStreet4CBChance as integer)) + ,sum(CAST(foldToStreet4CBDone as integer)) + ,sum(CAST(totalProfit as integer)) + ,sum(CAST(street1CheckCallRaiseChance as integer)) + ,sum(CAST(street1CheckCallRaiseDone as integer)) + ,sum(CAST(street2CheckCallRaiseChance as integer)) + ,sum(CAST(street2CheckCallRaiseDone as integer)) + ,sum(CAST(street3CheckCallRaiseChance as integer)) + ,sum(CAST(street3CheckCallRaiseDone as integer)) + ,sum(CAST(street4CheckCallRaiseChance as integer)) + ,sum(CAST(street4CheckCallRaiseDone as integer)) + FROM HandsPlayers hp + INNER JOIN Hands h ON (h.id = hp.handId) + GROUP BY h.gametypeId + ,hp.playerId + ,h.seats + ,hc_position + ,hp.tourneyTypeId + ,'d' || substr(strftime('%Y%m%d', h.handStart),3) +""" if db_server == 'mysql': self.query['analyze'] = """ @@ -2681,6 +2850,44 @@ class Sql: else: # assume postgres self.query['lockForInsert'] = "" + self.query['getGametypeFL'] = """SELECT id + FROM Gametypes + WHERE siteId=%s + AND type=%s + AND category=%s + AND limitType=%s + AND smallBet=%s + AND bigBet=%s + """ + + self.query['getGametypeNL'] = """SELECT id + FROM Gametypes + WHERE siteId=%s + AND type=%s + AND category=%s + AND limitType=%s + AND smallBlind=%s + AND bigBlind=%s + """ + + self.query['insertGameTypes'] = """INSERT INTO Gametypes + (siteId, type, base, category, limitType + ,hiLo, smallBlind, bigBlind, smallBet, bigBet) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" + + self.query['isAlreadyInDB'] = """SELECT id FROM Hands + WHERE gametypeId=%s AND siteHandNo=%s + """ + + if db_server == 'mysql': + self.query['placeholder'] = u'%s' + elif db_server == 'postgresql': + self.query['placeholder'] = u'%s' + elif db_server == 'sqlite': + self.query['placeholder'] = u'?' + + + # If using sqlite, use the ? placeholder instead of %s if db_server == 'sqlite': for k,q in self.query.iteritems(): self.query[k] = re.sub('%s','?',q) diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index f0e0de12..6d07febe 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -155,105 +155,4 @@ class fpdb_db: return (self.host, self.database, self.user, self.password) #end def get_db_info - def getLastInsertId(self, cursor=None): - try: - if self.backend == self.MYSQL_INNODB: - ret = self.db.insert_id() - if ret < 1 or ret > 999999999: - print "getLastInsertId(): problem fetching insert_id? ret=", ret - ret = -1 - elif self.backend == self.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) - c = self.db.cursor() - ret = c.execute ("SELECT lastval()") - row = c.fetchone() - if not row: - print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row - ret = -1 - else: - ret = row[0] - elif self.backend == fpdb_db.SQLITE: - ret = cursor.lastrowid - else: - print "getLastInsertId(): unknown backend ", self.backend - ret = -1 - except: - ret = -1 - print "getLastInsertId error:", str(sys.exc_value), " ret =", ret - raise fpdb_simple.FpdbError( "getLastInsertId error: " + str(sys.exc_value) ) - - return ret - - def storeHand(self, p): - #stores into table hands: - self.cursor.execute ("""INSERT INTO Hands ( - tablename, - sitehandno, - gametypeid, - handstart, - importtime, - seats, - maxseats, - boardcard1, - boardcard2, - boardcard3, - boardcard4, - boardcard5, --- texture, - playersVpi, - playersAtStreet1, - playersAtStreet2, - playersAtStreet3, - playersAtStreet4, - playersAtShowdown, - street0Raises, - street1Raises, - street2Raises, - street3Raises, - street4Raises, --- street1Pot, --- street2Pot, --- street3Pot, --- street4Pot, --- showdownPot - ) - VALUES - (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s, %s, %s, %s)""", - ( - p['tablename'], - p['sitehandno'], - p['gametypeid'], - p['handStart'], - datetime.datetime.today(), - len(p['names']), - p['maxSeats'], - p['boardcard1'], - p['boardcard2'], - p['boardcard3'], - p['boardcard4'], - p['boardcard5'], - hudCache['playersVpi'], - hudCache['playersAtStreet1'], - hudCache['playersAtStreet2'], - hudCache['playersAtStreet3'], - hudCache['playersAtStreet4'], - hudCache['playersAtShowdown'], - hudCache['street0Raises'], - hudCache['street1Raises'], - hudCache['street2Raises'], - hudCache['street3Raises'], - hudCache['street4Raises'], - hudCache['street1Pot'], - hudCache['street2Pot'], - hudCache['street3Pot'], - hudCache['street4Pot'], - hudCache['showdownPot'] - ) - ) - #return getLastInsertId(backend, conn, cursor) #end class fpdb_db diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py index 0314b83e..696f42d2 100644 --- a/pyfpdb/fpdb_parse_logic.py +++ b/pyfpdb/fpdb_parse_logic.py @@ -79,7 +79,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non rebuyOrAddon = -1 tourneyTypeId = 1 - fpdb_simple.isAlreadyInDB(db.get_cursor(), gametypeID, siteHandNo) + fpdb_simple.isAlreadyInDB(db, gametypeID, siteHandNo) hand = fpdb_simple.filterCrap(hand, isTourney) @@ -93,7 +93,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non seatLines.append(line) names = fpdb_simple.parseNames(seatLines) - playerIDs = fpdb_simple.recognisePlayerIDs(db.get_cursor(), names, siteID) # inserts players as needed + playerIDs = fpdb_simple.recognisePlayerIDs(db, names, siteID) # inserts players as needed tmp = fpdb_simple.parseCashesAndSeatNos(seatLines) startCashes = tmp['startCashes'] seatNos = tmp['seatNos'] @@ -141,7 +141,7 @@ def mainParser(settings, siteID, category, hand, config, db = None, writeq = Non fpdb_simple.checkPositions(positions) c = db.get_cursor() - c.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, )) + c.execute("SELECT limitType FROM Gametypes WHERE id=%s" % (db.sql.query['placeholder'],), (gametypeID, )) limit_type = c.fetchone()[0] fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts) diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index d91becb8..4594b3f4 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -400,10 +400,11 @@ def isActionLine(line): #end def isActionLine #returns whether this is a duplicate -def isAlreadyInDB(cursor, gametypeID, siteHandNo): +def isAlreadyInDB(db, gametypeID, siteHandNo): #print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo - cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo)) - result=cursor.fetchall() + c = db.get_cursor() + c.execute( db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo)) + result = c.fetchall() if (len(result)>=1): raise DuplicateError ("dupl") #end isAlreadyInDB @@ -898,9 +899,11 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type if (limit_type=="fl"): - cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) + cursor.execute ( db.sql.query['getGametypeFL'] + , (site_id, type, category, limit_type, small_bet, big_bet)) else: - cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) + cursor.execute ( db.sql.query['getGametypeNL'] + , (site_id, type, category, limit_type, small_bet, big_bet)) result=cursor.fetchone() #print "recgt1 result=",result #ret=result[0] @@ -935,25 +938,16 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c small_blind=float2int(smallBlindLine[pos:]) else: small_blind=0 - cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType - ,hiLo, smallBlind, bigBlind, smallBet, bigBet) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" - , (site_id, type, base, category, limit_type, hiLo - ,small_blind, big_blind, small_bet, big_bet) ) + result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo + ,small_blind, big_blind, small_bet, big_bet) ) #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) else: - cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType - ,hiLo, smallBlind, bigBlind, smallBet, bigBet) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" - , (site_id, type, base, category, limit_type - ,hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind + result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo + ,small_bet, big_bet, 0, 0) )#remember, for these bet means blind #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s #AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) - #result=(db.insert_id(),) - result=(db.get_last_insert_id(),) - return result[0] #end def recogniseGametypeID @@ -990,17 +984,21 @@ def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon): # result.append(tmp[0][0]) # return result -def recognisePlayerIDs(cursor, names, site_id): - q = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in names]) - cursor.execute(q, names) # get all playerids by the names passed in - ids = dict(cursor.fetchall()) # convert to dict +def recognisePlayerIDs(db, names, site_id): + q = "SELECT name,id FROM Players WHERE name=" + " OR name=".join([db.sql.query['placeholder'] for n in names]) + c = db.get_cursor() + c.execute(q, names) # get all playerids by the names passed in + ids = dict(c.fetchall()) # convert to dict if len(ids) != len(names): notfound = [n for n in names if n not in ids] # make list of names not in database if notfound: # insert them into database - cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", [(n,) for n in notfound]) + q_ins = "INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")" + q_ins = q_ins.replace('%s', db.sql.query['placeholder']) + c.executemany(q_ins, [(n,) for n in notfound]) q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound]) - cursor.execute(q2, notfound) # get their new ids - tmp = cursor.fetchall() + q2 = q2.replace('%s', db.sql.query['placeholder']) + c.execute(q2, notfound) # get their new ids + tmp = c.fetchall() for n,id in tmp: # put them all into the same dict ids[n] = id # return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB