5
""" mysql interface """
7
__copyright__ = 'this file is in the public domain'
9
from gozerbot.config import config
10
from gozerbot.generic import rlog, lockdec, tolatin1, handle_exception
11
from gozerbot.datadir import datadir
12
import thread, os, time
14
dblock = thread.allocate_lock()
15
dblocked = lockdec(dblock)
19
""" this class implements an database connection. it connects to the
20
database on initialisation.
23
def __init__(self, doconnect=True, dbtype=None):
28
self.connection = None
31
self.dbtype = dbtype or config['dbtype'] or 'mysql'
36
def connect(self, dbname=None, dbhost=None, dbuser=None, dbpasswd=None, \
37
timeout=15, oldstyle=False):
38
""" connect to the database """
39
self.dbname = dbname or config['dbname']
40
self.dbhost = dbhost or config['dbhost']
41
self.dbuser = dbuser or config['dbuser']
42
self.dbpasswd = dbpasswd or config['dbpasswd']
43
self.timeout = timeout
44
self.oldstyle = oldstyle or config['dboldstyle']
45
if self.dbtype == 'mysql':
47
self.connection = MySQLdb.connect(db=self.dbname, \
48
host=self.dbhost, user=self.dbuser, passwd=self.dbpasswd, \
49
connect_timeout=self.timeout, charset='utf8')
50
elif self.dbtype == 'sqlite':
52
self.connection = sqlite.connect(datadir + os.sep + self.dbname)
53
elif self.dbtype == 'postgres':
55
rlog(1000, 'db', 'NOTE THAT POSTGRES IS NOT FULLY SUPPORTED')
56
self.connection = psycopg2.connect(database=self.dbname, \
57
host=self.dbhost, user=self.dbuser, password=self.dbpasswd)
59
rlog(100, 'db', 'unknown database type %s' % self.dbtype)
61
rlog(5, 'db', "database ok")
65
""" reconnect to the mysql server """
66
if self.dbtype == 'mysql':
68
self.connection = MySQLdb.connect(db=self.dbname, \
69
host=self.dbhost, user=self.dbuser, passwd=self.dbpasswd, \
70
connect_timeout=self.timeout, charset='utf8')
71
elif self.dbtype == 'sqlite':
73
self.connection = sqlite.connect(self.dbname)
74
elif self.dbtype == 'postgres':
76
self.connection = psycopg2.connect(database=self.dbname, \
77
host=self.dbhost, user=self.dbuser, password=self.dbpasswd)
79
rlog(100, 'db', 'unknown database type %s' % self.dbtype)
81
rlog(10, 'db', 'reconnect done')
85
def execute(self, execstr, args=None):
86
""" execute string on database """
89
execstr = execstr.strip()
90
# first to ping to see if connection is alive .. if not reconnect
91
if self.dbtype == 'mysql':
95
rlog(10, 'db', "can't ping database: %s" % str(ex))
96
rlog(10, 'db', 'reconnecting')
100
rlog(10, 'db', 'failed reconnect: %s' % str(ex))
103
cursor = self.cursor()
104
# excecute string on cursor
110
nargs.append(tolatin1(i))
112
rlog(-2, 'db', 'exec %s %s' % (execstr, args))
114
if type(args) == tuple or type(args) == list:
115
nr = cursor.execute(execstr, args)
117
nr = cursor.execute(execstr, (args, ))
119
if self.dbtype == 'postgres':
120
cursor.execute(""" ROLLBACK """)
123
rlog(-2, 'db', 'exec %s' % execstr)
124
nr = cursor.execute(execstr)
125
# see if we need to commit the query
127
if execstr.startswith('INSERT') or execstr.startswith('UPDATE'):
128
nr = cursor.lastrowid or nr
130
elif execstr.startswith('DELETE'):
138
result = cursor.fetchall()
141
except Exception, ex:
142
if 'no results to fetch' in str(ex):
151
""" return cursor to the database """
152
return self.connection.cursor()
155
""" do a commit on the datase """
156
self.connection.commit()
160
return self.connection.ping()
163
""" close database """
164
self.connection.close()
166
# create default database if enabled
167
cfg = config['dbenable']