webgo/psql.py

350 lines
8.4 KiB
Python
Executable file

import helper
import pgdb,sys
dbusername="webgouser"
dbpassword="webgopassword"
dbname="webgo"
#pgdb.connect(connect_string) -> connection
#connect_string = 'host:database:user:password:opt:tty'
connect_string='localhost:'+dbname+':'+dbusername+':'+dbpassword
db=pgdb.connect(connect_string)
def create_table(name,layout=""):
"""
create_table(name:string, layout:string)
returns name if successfull, None if not.
simple function to create a table. the function itself would just
create an empty table with the command 'CREATE TABLE ();'.
The real layout is given to the function as an argument of type
string. This string contains all column declarations in SQL syntax:
"var1 real, var2 int"
name is the name of the table
"""
executestring = "CREATE TABLE %s ( %s );" % (name,layout)
sql_one_liner(executestring)
def insert_into_table(table, content):
"""
gets the name of a table and a content string.
executes INSERT INTO name VALUES content;
"""
executestring = "INSERT INTO %s VALUES %s" % (table,content)
sql_one_liner(executestring)
def drop_table(name):
"""
gets: name of table.
executes DROP TABLE <name>
"""
executestring = "DROP TABLE %s;" % (name)
sql_one_liner(executestring)
def sql_one_liner(data):
"""
gets:SQL statement
creates a cursor, executes <statement>, closes cursor.
"""
cursor=db.cursor()
cursor.execute(data)
# Commit the changes
db.commit()
cursor.close()
def create_goban_table(player1,player2,size):
"""
gets:player1, player2, size of goban.
creates postgresql table containing goban data.
returns: name of created table.
the table looks like this:
line x1 x2 x3 x4 ... x(size)
y1
y2
y3
...
y(size)
turn_number
size
name
player1
player2
and the meaning of these fields:
(xn,yn) is a field of the goban,
(turn_number,x1) is the current turn,
(size,x1) is the length of a side of the goban,
(name,x1) is the name of this goban.
(player1,x1) is the name of one player.
(player2,x1) is the name of the other player.
"""
tablename = helper.generate_game_name()
data="line text"
for i in range(1,size+1):
if data != "":
data += ", "
data += "x"+str(i) + ' text'
create_table(tablename,data)
#table created, now fill the table
for i in range(1,size+1):
tmplist=[]
tmplist.append("y"+str(i))
for k in range(1,size+1):
tmplist.append(0)
insert_into_table(tablename,str(tuple(tmplist)))
#ok, goban itself has been created and filled,
#now insert additional variables
tmplist=[]
tmplist.append("turn_number")
tmplist.append("1")
insert_into_table(tablename,str(tuple(tmplist)))
#size of goban
tmplist=[]
tmplist.append("size")
tmplist.append(size)
insert_into_table(tablename,str(tuple(tmplist)))
#name of goban (=name of table in database)
tmplist=[]
tmplist.append("name")
tmplist.append(tablename)
insert_into_table(tablename,str(tuple(tmplist)))
#name of player1
tmplist=[]
tmplist.append("player1")
tmplist.append(player1)
insert_into_table(tablename,str(tuple(tmplist)))
#name of player2
tmplist=[]
tmplist.append("player2")
tmplist.append(player2)
insert_into_table(tablename,str(tuple(tmplist)))
return tablename
def create_user_table():
"""
creates a table named users with following columns:
name - name of user
password - passsword of user
game1 - the 10 game slots of this user contain names
... of goban tables
game10
sessionid - id of current session
timeout - when does session time out?
"""
data = "username varchar(15)"
data += ", password text"
for i in range(1,11):
data += ", game"+str(i)+" text"
data += ", sessionid text"
data += ", timeout int"
create_table("users",data)
def read_table(table):
"""
gets the name of a table, does a
SELECT * FROM table;
returns output.
"""
cursor=db.cursor()
data="SELECT * FROM %s;" % (table)
cursor.execute(data)
# Commit the changes
db.commit()
ret = cursor.fetchall()
cursor.close()
return ret
def get_user_game_list(name):
"""
gets a username, returns the list of games for user.
"""
cursor=db.cursor()
ret = []
for x in range(1,11):
data="SELECT game%s FROM users WHERE username = '%s'" % (x,name)
try:
cursor.execute(data)
# Commit the changes
db.commit()
ret.append(cursor.fetchone()[0]) #[0], because return is a list
except:
ret = "could not get info of all games -- table corrupt?"
return ret
cursor.close()
return ret
def get_user_info(name,infotype):
"""
gets the name of a user and the type of requested info.
returns info from database.
"""
cursor=db.cursor()
if infotype in ("password","sessionid","timeout"):
data="SELECT %s FROM users WHERE username = '%s'" % (infotype,name)
try:
cursor.execute(data)
# Commit the changes
db.commit()
ret = cursor.fetchone()[0] #[0], because return is a list
except:
ret = "no such user"
cursor.close()
else:
ret = "Are your sure about the infotype?"
return ret
def set_user_sessionid(username,sessionid):
"""
gets username and sessionid, writes sessid into database
"""
executestring ="UPDATE users SET sessionid = '%s' WHERE username = '%s'" %(sessionid, username)
sql_one_liner(executestring)
def set_user_timeout(username):
"""
gets username, sets timeout to time.time + 30min
"""
import time
timeout = int(time.time()) + 900 #current time in seconds + seconds for session
executestring ="UPDATE users SET timeout = '%s' WHERE username = '%s'" %(timeout, username)
sql_one_liner(executestring)
def update_database_field(table,column,line,data):
"""
gets: table name, column name, line name, new content for field.
executes an SQL UPDATE statement for line.
"""
executestring ="UPDATE %s SET %s = '%s' WHERE line = '%s'" %(table,column,data,line)
sql_one_liner(executestring)
def update_goban_field(table,x,y,content):
"""
gets: goban dictionary, x,y coordinates, new content for field.
modifies goban in database.
"""
update_database_field(table,"x"+str(x),"y"+str(y),content)
def update_turn_number(table,new_number):
"""
gets: name of table,new turn number
modifies 'turn_number' in table
"""
update_database_field(table,"x1","turn_number",new_number)
def add_webgo_user(name,password):
"""
adds a database entry for a user.
gets: username and password
"""
#size of goban
tmplist=[]
tmplist.append(name)
tmplist.append(password)
insert_into_table("users",str(tuple(tmplist)))
def fetchall_list_to_goban_dict(list):
"""
gets the output from read_table (a list),
returns a goban dictionary.
"""
#create dictionary
ret = {}
#get size of goban
for item in list:
if item[0] == "size":
size=int(item[1])
ret["size"] = size
#populate dictionary with goban field
for item in list:
if item[0][0] == "y": #goban fields
#get current y coordinate
y = int(item[0][1:])
#fill dictionary for current y coordinate
for x in range(1,size+1):
ret[(x,y)]=helper.check_for_int(item[x])
else: #other variables
ret[item[0]]=helper.check_for_int(item[1])
return ret
def get_users_with_free_game_slots():
"""
gets nothing.
returns a list of all users who have at least one game slot free.
"""
cursor=db.cursor()
data = """select username from users where
(game1 IS NULL) OR (game2 IS NULL) OR (game3 IS NULL) OR
(game4 IS NULL) OR (game5 IS NULL) OR (game6 IS NULL) OR
(game7 IS NULL) OR (game8 IS NULL) OR (game9 IS NULL) OR
(game10 IS NULL)"""
cursor.execute(data)
# Commit the changes
db.commit()
tmplist = cursor.fetchall()
ret = [item[0] for item in tmplist]
return ret
def get_free_game_slot(username):
"""
gets a username
returns the name of a free game slot or "" if none found.
"""
ret = ""
for i in range(1,11):
cursor=db.cursor()
data = "SELECT username FROM users WHERE username='%s' AND game%s IS NULL" % (username,i)
cursor.execute(data)
# Commit the changes
db.commit()
tmp = [item[0] for item in cursor.fetchall()]
if tmp != []:
ret = "game"+str(i)
return ret
def set_game_slot(username,gameslot,gamename):
"""
gets username,game slot,game name.
sets the game slot for user username to game name ;>
"""
executestring ="UPDATE users SET %s = '%s' WHERE username = '%s'" %(gameslot,gamename, username)
sql_one_liner(executestring)
def test():
#create_table("test")
drop_table("test")
create_goban_table(9)
update_database_field("test","x1","turn_number",4)
list = read_table("test")
print list
dict = fetchall_list_to_goban_dict(list)
print dict
print dict["turn_number"]
print dict["name"]
print type(dict["turn_number"])
#test()