sqlite - connecting and (re)creating some tables

This commit is contained in:
Matt Turnbull 2009-07-14 00:04:10 +01:00
parent 22ff98d7c9
commit dc6a1c45f9
5 changed files with 170 additions and 51 deletions

View File

@ -493,6 +493,8 @@ class Config:
db['db-backend'] = 2 db['db-backend'] = 2
elif string.lower(self.supported_databases[name].db_server) == 'postgresql': elif string.lower(self.supported_databases[name].db_server) == 'postgresql':
db['db-backend'] = 3 db['db-backend'] = 3
elif string.lower(self.supported_databases[name].db_server) == 'sqlite':
db['db-backend'] = 4
else: db['db-backend'] = None # this is big trouble else: db['db-backend'] = None # this is big trouble
return db return db

View File

@ -38,7 +38,9 @@ class FpdbSQLQueries:
elif(self.dbname == 'PostgreSQL'): elif(self.dbname == 'PostgreSQL'):
self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'""" self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['list_tables'] = """ """ self.query['list_tables'] = """SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;"""
################################################################## ##################################################################
# Drop Tables - MySQL, PostgreSQL and SQLite all share same syntax # Drop Tables - MySQL, PostgreSQL and SQLite all share same syntax
@ -63,8 +65,8 @@ class FpdbSQLQueries:
self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)""" self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
#Probably doesn't work. self.query['createSettingsTable'] = """CREATE TABLE Settings
self.query['createSettingsTable'] = """ """ (version INTEGER) """
################################ ################################
@ -83,7 +85,10 @@ class FpdbSQLQueries:
name varchar(32), name varchar(32),
currency char(3))""" currency char(3))"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['createSitesTable'] = """ """ self.query['createSitesTable'] = """CREATE TABLE Sites (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
currency TEXT NOT NULL)"""
################################ ################################
@ -118,7 +123,19 @@ class FpdbSQLQueries:
smallBet int, smallBet int,
bigBet int)""" bigBet int)"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['createGametypesTable'] = """ """ self.query['createGametypesTable'] = """CREATE TABLE GameTypes (
id INTEGER PRIMARY KEY,
siteId INTEGER,
type TEXT,
base TEXT,
category TEXT,
limitType TEXT,
hiLo TEXT,
smallBlind INTEGER,
bigBlind INTEGER,
smallBet INTEGER,
bigBet INTEGER,
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
################################ ################################
@ -141,7 +158,13 @@ class FpdbSQLQueries:
comment text, comment text,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['createPlayersTable'] = """ """ self.query['createPlayersTable'] = """CREATE TABLE Players (
id INTEGER PRIMARY KEY,
name TEXT,
siteId INTEGER,
comment TEXT,
commentTs BLOB,
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
################################ ################################
@ -245,11 +268,22 @@ class FpdbSQLQueries:
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['createHandsTable'] = """ """ self.query['createHandsTable'] = """CREATE TABLE Hands (
id INTEGER PRIMARY KEY,
tableName TEXT(20),
siteHandNo INTEGER,
gametypeId INTEGER,
handStart BLOB,
importTime BLOB,
seats INTEGER,
maxSeats INTEGER,
comment TEXT,
commentTs BLOB,
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
################################ ################################
# Create Gametypes # Create BoardCards
################################ ################################
if(self.dbname == 'MySQL InnoDB'): if(self.dbname == 'MySQL InnoDB'):
@ -336,7 +370,14 @@ class FpdbSQLQueries:
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['createTourneysTable'] = """ """ self.query['createTourneysTable'] = """CREATE TABLE TourneyTypes (
id INTEGER PRIMARY KEY,
siteId INTEGER,
buyin INTEGER,
fee INTEGER,
knockout INTEGER,
rebuyOrAddon BOOL,
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
################################ ################################
# Create HandsPlayers # Create HandsPlayers
@ -869,6 +910,13 @@ class FpdbSQLQueries:
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['addPlayersIndex'] = """ """ self.query['addPlayersIndex'] = """ """
if(self.dbname == 'MySQL InnoDB' or self.dbname == 'PostgreSQL'):
self.query['set tx level'] = """SET SESSION TRANSACTION
ISOLATION LEVEL READ COMMITTED"""
elif(self.dbname == 'SQLite'):
self.query['set tx level'] = """ """
################################ ################################
# Queries used in GuiGraphViewer # Queries used in GuiGraphViewer
################################ ################################

View File

@ -19,7 +19,6 @@ import os
import sys import sys
import Options import Options
import string import string
cl_options = string.join(sys.argv[1:]) cl_options = string.join(sys.argv[1:])
(options, sys.argv) = Options.fpdb_options() (options, sys.argv) = Options.fpdb_options()
@ -28,6 +27,8 @@ if not options.errorsToConsole:
errorFile = open('fpdb-error-log.txt', 'w', 0) errorFile = open('fpdb-error-log.txt', 'w', 0)
sys.stderr = errorFile sys.stderr = errorFile
import logging
import pygtk import pygtk
pygtk.require('2.0') pygtk.require('2.0')
import gtk import gtk
@ -481,6 +482,11 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
#end def tabGraphViewer #end def tabGraphViewer
def __init__(self): def __init__(self):
LOG_FILENAME = './logging.out'
LOG_FORMAT = "%(asctime)-15s %(levelname)-8s %(message)s"
logging.basicConfig(filename=LOG_FILENAME,level=10,format=LOG_FORMAT)
logging.info("Fpdb started")
self.threads=[] self.threads=[]
self.db=None self.db=None
self.config = Configuration.Config(file=options.config, dbname=options.dbname) self.config = Configuration.Config(file=options.config, dbname=options.dbname)

View File

@ -18,20 +18,21 @@
import os import os
import re import re
import sys import sys
import logging
from time import time, strftime from time import time, strftime
import fpdb_simple import fpdb_simple
import FpdbSQLQueries import FpdbSQLQueries
class fpdb_db: class fpdb_db:
MYSQL_INNODB = 2
PGSQL = 3
SQLITE = 4
def __init__(self): def __init__(self):
"""Simple constructor, doesnt really do anything""" """Simple constructor, doesnt really do anything"""
self.db = None self.db = None
self.cursor = None self.cursor = None
self.sql = {} self.sql = {}
self.MYSQL_INNODB = 2
self.PGSQL = 3
self.SQLITE = 4
# Data Structures for index and foreign key creation # Data Structures for index and foreign key creation
# drop_code is an int with possible values: 0 - don't drop for bulk import # drop_code is an int with possible values: 0 - don't drop for bulk import
@ -72,6 +73,8 @@ class fpdb_db:
, {'tab':'TourneysPlayers', 'col':'tourneyId', 'drop':0} , {'tab':'TourneysPlayers', 'col':'tourneyId', 'drop':0}
, {'tab':'TourneyTypes', 'col':'siteId', 'drop':0} , {'tab':'TourneyTypes', 'col':'siteId', 'drop':0}
] ]
, [ # indexes for sqlite (list index 4)
]
] ]
self.foreignKeys = [ self.foreignKeys = [
@ -146,12 +149,12 @@ class fpdb_db:
self.settings = {} self.settings = {}
self.settings['os'] = "linuxmac" if os.name != "nt" else "windows" self.settings['os'] = "linuxmac" if os.name != "nt" else "windows"
self.settings.update(config.get_db_parameters()) db = config.get_db_parameters()
self.connect(self.settings['db-backend'], self.connect(backend=db['db-backend'],
self.settings['db-host'], host=db['db-host'],
self.settings['db-databaseName'], database=db['db-databaseName'],
self.settings['db-user'], user=db['db-user'],
self.settings['db-password']) password=db['db-password'])
#end def do_connect #end def do_connect
def connect(self, backend=None, host=None, database=None, def connect(self, backend=None, host=None, database=None,
@ -164,13 +167,13 @@ class fpdb_db:
self.user=user self.user=user
self.password=password self.password=password
self.database=database self.database=database
if backend==self.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)
except: except:
raise fpdb_simple.FpdbError("MySQL connection failed") raise fpdb_simple.FpdbError("MySQL connection failed")
elif backend==self.PGSQL: elif backend==fpdb_db.PGSQL:
import psycopg2 import psycopg2
import psycopg2.extensions import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
@ -201,12 +204,19 @@ class fpdb_db:
msg = "PostgreSQL connection to database (%s) user (%s) failed." % (database, user) msg = "PostgreSQL connection to database (%s) user (%s) failed." % (database, user)
print msg print msg
raise fpdb_simple.FpdbError(msg) raise fpdb_simple.FpdbError(msg)
elif backend==fpdb_db.SQLITE:
logging.info("Connecting to SQLite:(%s)")
import sqlite3
self.db = sqlite3.connect(database,detect_types=sqlite3.PARSE_DECLTYPES)
sqlite3.register_converter("bool", lambda x: bool(int(x)))
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
else: else:
raise fpdb_simple.FpdbError("unrecognised database backend:"+backend) raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
self.cursor=self.db.cursor() self.cursor=self.db.cursor()
self.cursor.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED')
# Set up query dictionary as early in the connection process as we can. # Set up query dictionary as early in the connection process as we can.
self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name()) self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
self.cursor.execute(self.sql.query['set tx level'])
self.wrongDbVersion=False self.wrongDbVersion=False
try: try:
self.cursor.execute("SELECT * FROM Settings") self.cursor.execute("SELECT * FROM Settings")
@ -237,7 +247,9 @@ class fpdb_db:
def create_tables(self): def create_tables(self):
#todo: should detect and fail gracefully if tables already exist. #todo: should detect and fail gracefully if tables already exist.
logging.debug(self.sql.query['createSettingsTable'])
self.cursor.execute(self.sql.query['createSettingsTable']) self.cursor.execute(self.sql.query['createSettingsTable'])
logging.debug(self.sql.query['createSitesTable'])
self.cursor.execute(self.sql.query['createSitesTable']) self.cursor.execute(self.sql.query['createSitesTable'])
self.cursor.execute(self.sql.query['createGametypesTable']) self.cursor.execute(self.sql.query['createGametypesTable'])
self.cursor.execute(self.sql.query['createPlayersTable']) self.cursor.execute(self.sql.query['createPlayersTable'])
@ -275,10 +287,12 @@ class fpdb_db:
for table in tables: for table in tables:
self.cursor.execute(self.sql.query['drop_table'] + table[0] + ' cascade') self.cursor.execute(self.sql.query['drop_table'] + table[0] + ' cascade')
elif(self.get_backend_name() == 'SQLite'): elif(self.get_backend_name() == 'SQLite'):
#todo: sqlite version here self.cursor.execute(self.sql.query['list_tables'])
print "Empty function here" for table in self.cursor.fetchall():
logging.debug(self.sql.query['drop_table'] + table[0])
self.cursor.execute(self.sql.query['drop_table'] + table[0])
self.db.commit() self.db.commit()
#end def drop_tables #end def drop_tables
def drop_referential_integrity(self): def drop_referential_integrity(self):
@ -307,6 +321,8 @@ class fpdb_db:
return "MySQL InnoDB" return "MySQL InnoDB"
elif self.backend==3: elif self.backend==3:
return "PostgreSQL" return "PostgreSQL"
elif self.backend==4:
return "SQLite"
else: else:
raise fpdb_simple.FpdbError("invalid backend") raise fpdb_simple.FpdbError("invalid backend")
#end def get_backend_name #end def get_backend_name
@ -316,11 +332,14 @@ class fpdb_db:
#end def get_db_info #end def get_db_info
def fillDefaultData(self): def fillDefaultData(self):
self.cursor.execute("INSERT INTO Settings VALUES (118);") logging.debug("INSERT INTO Settings (version) VALUES (118);")
self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');") self.cursor.execute("INSERT INTO Settings (version) VALUES (118);")
self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');") self.cursor.execute("INSERT INTO Sites (name,currency) VALUES ('Full Tilt Poker', 'USD')")
self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Everleaf', 'USD');") self.cursor.execute("INSERT INTO Sites (name,currency) VALUES ('PokerStars', 'USD')")
self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);") self.cursor.execute("INSERT INTO Sites (name,currency) VALUES ('Everleaf', 'USD')")
self.cursor.execute("""INSERT INTO TourneyTypes
(siteId,buyin,fee,knockout,rebuyOrAddon) VALUES
(1,0,0,0,?)""",(False,) )
#end def fillDefaultData #end def fillDefaultData
def recreate_tables(self): def recreate_tables(self):
@ -617,7 +636,7 @@ class fpdb_db:
ret = -1 ret = -1
else: else:
ret = row[0] ret = row[0]
elif self.backend == self.SQLITE: elif self.backend == fpdb_db.SQLITE:
# don't know how to do this in sqlite # don't know how to do this in sqlite
print "getLastInsertId(): not coded for sqlite yet" print "getLastInsertId(): not coded for sqlite yet"
ret = -1 ret = -1
@ -628,27 +647,70 @@ class fpdb_db:
def storeHand(self, p): def storeHand(self, p):
#stores into table hands: #stores into table hands:
self.cursor.execute ("""INSERT INTO Hands self.cursor.execute ("""INSERT INTO Hands (
(siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats tablename,
,boardcard1, boardcard2, boardcard3, boardcard4, boardcard5 sitehandno,
,playersVpi, playersAtStreet1, playersAtStreet2 gametypeid,
,playersAtStreet3, playersAtStreet4, playersAtShowdown handstart,
,street0Raises, street1Raises, street2Raises importtime,
,street3Raises, street4Raises, street1Pot seats,
,street2Pot, street3Pot, street4Pot maxseats,
,showdownPot boardcard1,
boardcard2,
boardcard3,
boardcard4,
boardcard5,
-- texture,
playersVpi,
playersAtStreet1,
playersAtStreet2,
playersAtStreet3,
playersAtStreet4,
playersAtShowdown,
street0Raises,
street1Raises,
street2Raises,
street3Raises,
street4Raises,
-- street1Pot,
-- street2Pot,
-- street3Pot,
-- street4Pot,
-- showdownPot
) )
VALUES 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,
,(p['siteHandNo'], gametype_id, p['handStart'], len(names), p['tableName'], datetime.datetime.today(), p['maxSeats'] %s, %s, %s, %s, %s, %s, %s)""",
,p['boardcard1'], ['boardcard2'], p['boardcard3'], ['boardcard4'], ['boardcard5'] (
,hudCache['playersVpi'], hudCache['playersAtStreet1'], hudCache['playersAtStreet2'] p['tablename'],
,hudCache['playersAtStreet3'], hudCache['playersAtStreet4'], hudCache['playersAtShowdown'] p['sitehandno'],
,hudCache['street0Raises'], hudCache['street1Raises'], hudCache['street2Raises'] p['gametypeid'],
,hudCache['street3Raises'], hudCache['street4Raises'], hudCache['street1Pot'] p['handStart'],
,hudCache['street2Pot'], hudCache['street3Pot'], hudCache['street4Pot'] datetime.datetime.today(),
,hudCache['showdownPot'] 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) #return getLastInsertId(backend, conn, cursor)
#end class fpdb_db #end class fpdb_db

View File

@ -22,6 +22,7 @@
import os # todo: remove this once import_dir is in fpdb_import import os # todo: remove this once import_dir is in fpdb_import
import sys import sys
from time import time, strftime from time import time, strftime
import logging
import traceback import traceback
import math import math
import datetime import datetime