database interface
Bases: object
this class implements a database connection. it connects to the database on initialisation.
close database.
do a commit on the datase.
connect to the database.
return cursor to the database.
the locked function.
the locked function.
do a ping.
reconnect to the database server.
# gozerbot/databse/db.py # # """ database interface """ __status__ = "seen"
from gozerbot.config import config from gozerbot.utils.log import rlog from gozerbot.utils.locking import lockdec from gozerbot.utils.generic import tolatin1 from gozerbot.utils.exception import handle_exception from gozerbot.datadir import datadir
import thread import os import time import types
dblock = thread.allocate_lock() dblocked = lockdec(dblock)
class Db(object): """ this class implements a database connection. it connects to the database on initialisation. """ def __init__(self, doconnect=True, dbtype=None, ddir=None,configin=None): self.datadir = ddir or datadir if not os.path.isdir(self.datadir + os.sep + 'db/'): os.mkdir(self.datadir + os.sep + 'db/') self.config = configin or config self.dbname = self.config['dbname'] or "" self.dbhost = self.config['dbhost'] or "" self.dbuser = self.config['dbuser'] or "" self.dbpasswd = self.config['dbpasswd'] or "" self.connection = None self.timeout = 15 self.oldstyle = "" self.dbtype = dbtype or self.config['dbtype'] or 'sqlite' if doconnect: self.connect() def connect(self, dbname=None, dbhost=None, dbuser=None, dbpasswd=None, timeout=15, oldstyle=False): """ connect to the database. """ self.dbname = dbname or self.config['dbname'] self.dbhost = dbhost or self.config['dbhost'] self.dbuser = dbuser or self.config['dbuser'] self.dbpasswd = dbpasswd or self.config['dbpasswd'] self.timeout = timeout self.oldstyle = oldstyle or self.config['dboldstyle'] if self.dbtype == 'mysql': import MySQLdb self.connection = MySQLdb.connect(db=self.dbname, host=self.dbhost, user=self.dbuser, passwd=self.dbpasswd, connect_timeout=self.timeout, charset='utf8') elif 'sqlite' in self.dbtype: try: import sqlite self.connection = sqlite.connect(self.datadir + os.sep + self.dbname) except ImportError: import sqlite3 self.connection = sqlite3.connect(self.datadir + os.sep + self.dbname, check_same_thread=False) elif self.dbtype == 'postgres': import psycopg2 rlog(1000, 'db', 'NOTE THAT POSTGRES IS NOT FULLY SUPPORTED') self.connection = psycopg2.connect(database=self.dbname, host=self.dbhost, user=self.dbuser, password=self.dbpasswd) else: rlog(100, 'db', 'unknown database type %s' % self.dbtype) return 0 rlog(10, 'db', "%s database ok" % self.dbname) return 1 def reconnect(self): """ reconnect to the database server. """ return self.connect() @dblocked def executescript(self, txt): """ run executescript on the cursor. """ cursor = self.cursor() cursor.executescript(txt) cursor.close() self.commit() @dblocked def execute(self, execstr, args=None): """ execute string on database. """ time.sleep(0.001) result = None execstr = execstr.strip() if not self.connection: self.connect() if self.dbtype == 'sqlite': execstr = execstr.replace('%s', '?') if self.dbtype == 'mysql': try: self.ping() except AttributeError: self.reconnect() except Exception, ex: rlog(10, 'db', "can't ping database: %s" % str(ex)) rlog(10, 'db', 'reconnecting') try: self.reconnect() except Exception, ex: rlog(10, 'db', 'failed reconnect: %s' % str(ex)) return if args and self.oldstyle: nargs = [] for i in args: nargs.append(tolatin1(i)) args = nargs rlog(-2, 'db', 'exec %s %s' % (execstr, args)) cursor = self.cursor() nr = 0 try: if args: if type(args) == tuple or type(args) == list: nr = cursor.execute(execstr, args) else: nr = cursor.execute(execstr, (args, )) else: nr = cursor.execute(execstr) except: if self.dbtype == 'postgres': cursor.execute(""" ROLLBACK """) if 'sqlite' in self.dbtype: cursor.close() raise got = False if execstr.startswith('INSERT'): nr = cursor.lastrowid or nr ; got = True elif execstr.startswith('UPDATE'): nr = cursor.rowcount ; got = True elif execstr.startswith('DELETE'): nr = cursor.rowcount ; got = True if got: self.commit() if self.dbtype == 'sqlite' and not got and type(nr) != types.IntType: nr = cursor.rowcount or cursor.lastrowid if nr == -1: nr = 0 result = None try: result = cursor.fetchall() if not result: result = nr except Exception, ex: if 'no results to fetch' in str(ex): pass else: handle_exception() result = nr cursor.close() return result def cursor(self): """ return cursor to the database. """ return self.connection.cursor() def commit(self): """ do a commit on the datase. """ self.connection.commit() def ping(self): """ do a ping. """ return self.connection.ping() def close(self): """ close database. """ if 'sqlite' in self.dbtype: self.commit() self.connection.close()
db = Db()
def init_tables(): if True: if db.dbtype in ["sqlite", "sqlite3"]: import sqlite3 try: rlog(10, 'db', 'trying to create tables') db.executescript(sqlite3_newtxt) rlog(10, 'db', 'tables created') except sqlite3.OperationalError, ex: if 'already exists' in str(ex): rlog(10, 'db', 'tables are already created') except Exception, ex: handle_exception() else: rlog(10, 'db', "dbtype is %s .. NOT initialising tables. see the files dir for mysql or postgress schema's" % db.dbtype)
sqlite3_oldtxt = """ CREATE TABLE userhosts ( userhost VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL ); CREATE TABLE perms ( name VARCHAR(255) NOT NULL, perm VARCHAR(255) NOT NULL ); CREATE TABLE email ( name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL ); CREATE TABLE permits ( name VARCHAR(255) NOT NULL, permit VARCHAR(255) NOT NULL ); CREATE TABLE statuses ( name VARCHAR(255) NOT NULL, status VARCHAR(255) NOT NULL ); CREATE TABLE passwords ( name VARCHAR(255) NOT NULL, passwd VARCHAR(255) NOT NULL, PRIMARY KEY (name) ); CREATE TABLE infoitems ( indx INTEGER PRIMARY KEY, item VARCHAR(255) NOT NULL, description TEXT NOT NULL, userhost VARCHAR(255) NOT NULL, time INT(20) NOT NULL ); CREATE TABLE karma ( item VARCHAR(255) NOT NULL, value INT(20) NOT NULL, PRIMARY KEY (item) ); CREATE TABLE whykarma ( item VARCHAR(255) NOT NULL, updown VARCHAR(10) NOT NULL, why TEXT NOT NULL ); CREATE TABLE whokarma ( item VARCHAR(255) NOT NULL, nick VARCHAR(255) NOT NULL, updown VARCHAR(10) NOT NULL ); CREATE TABLE quotes ( indx INTEGER PRIMARY KEY, quote text NOT NULL, userhost VARCHAR(255) NOT NULL, createtime INT(20) NOT NULL, nick VARCHAR(255) NOT NULL ); CREATE TABLE todo ( indx INTEGER PRIMARY KEY, name VARCHAR(255) NOT NULL, time INT(20) DEFAULT NULL, duration INT(20) DEFAULT NULL, warnsec INT(20) DEFAULT NULL, descr TEXT NOT NULL, priority INT(20) DEFAULT NULL ); CREATE TABLE birthday ( name VARCHAR(255) NOT NULL, birthday varchar(255) NOT NULL, PRIMARY KEY (name) ); CREATE TABLE list ( indx INTEGER PRIMARY KEY, username VARCHAR(255) NOT NULL, listname VARCHAR(255) NOT NULL, item TEXT NOT NULL ); """ sqlite3_newtxt = """ PRAGMA foreign_keys=OFF; CREATE TABLE user ( name VARCHAR(255) NOT NULL, PRIMARY KEY (name) ); CREATE TABLE perms ( name VARCHAR(255) NOT NULL, perm VARCHAR(255) NOT NULL, FOREIGN KEY(name) REFERENCES user (name) ); INSERT INTO "perms" VALUES('owner','USER'); INSERT INTO "perms" VALUES('owner','OPER'); CREATE TABLE userhosts ( userhost VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY (userhost), FOREIGN KEY(name) REFERENCES user (name) ); CREATE TABLE permits ( name VARCHAR(255) NOT NULL, permit VARCHAR(255) NOT NULL, FOREIGN KEY(name) REFERENCES user (name) ); CREATE TABLE passwords ( name VARCHAR(255) NOT NULL, passwd VARCHAR(255) NOT NULL, PRIMARY KEY (name), FOREIGN KEY(name) REFERENCES user (name) ); CREATE TABLE statuses ( name VARCHAR(255) NOT NULL, status VARCHAR(255) NOT NULL, FOREIGN KEY(name) REFERENCES user (name) ); CREATE TABLE email ( name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, "order" INTEGER NOT NULL, FOREIGN KEY(name) REFERENCES user (name) ); CREATE TABLE whokarma ( item VARCHAR(255) NOT NULL, nick VARCHAR(255) NOT NULL, updown VARCHAR(10) NOT NULL ); CREATE TABLE karma ( item VARCHAR(255) NOT NULL, value INTEGER NOT NULL, PRIMARY KEY (item) ); CREATE TABLE whykarma ( item VARCHAR(255) NOT NULL, updown VARCHAR(10) NOT NULL, why TEXT NOT NULL ); CREATE TABLE quotes ( indx INTEGER NOT NULL, quote TEXT NOT NULL, userhost VARCHAR(255) NOT NULL, createtime DATETIME NOT NULL, nick VARCHAR(255) NOT NULL, PRIMARY KEY (indx), FOREIGN KEY(userhost) REFERENCES userhosts (userhost) ); CREATE TABLE todo ( indx INTEGER NOT NULL, name VARCHAR(255) NOT NULL, time DATETIME, duration INTEGER, warnsec INTEGER, descr TEXT NOT NULL, priority INTEGER, PRIMARY KEY (indx) ); CREATE TABLE birthday ( name VARCHAR(255) NOT NULL, birthday VARCHAR(255) NOT NULL, PRIMARY KEY (name) ); CREATE TABLE infoitems ( indx INTEGER NOT NULL, item VARCHAR(255) NOT NULL, description TEXT NOT NULL, userhost VARCHAR(255) NOT NULL, time DATETIME NOT NULL, PRIMARY KEY (indx), FOREIGN KEY(userhost) REFERENCES userhosts (userhost) ); CREATE TABLE list ( indx INTEGER NOT NULL, username VARCHAR(255) NOT NULL, listname VARCHAR(255) NOT NULL, item TEXT NOT NULL, PRIMARY KEY (indx) ); """