~ubuntu-branches/ubuntu/precise/gozerbot/precise

« back to all changes in this revision

Viewing changes to build/lib/gozerbot/db.py

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Malcolm
  • Date: 2008-06-02 19:26:39 UTC
  • mfrom: (1.1.3 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080602192639-3rn65nx4q1sgd6sy
Tags: 0.8.1-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# gozerbot/db.py
2
 
#
3
 
#
4
 
 
5
 
""" mysql interface """
6
 
 
7
 
__copyright__ = 'this file is in the public domain'
8
 
 
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
13
 
 
14
 
dblock = thread.allocate_lock()
15
 
dblocked = lockdec(dblock)
16
 
 
17
 
class Db(object):
18
 
 
19
 
    """ this class implements an database connection. it connects to the 
20
 
        database on initialisation.
21
 
    """
22
 
 
23
 
    def __init__(self, doconnect=True, dbtype=None):
24
 
        self.dbname = ""
25
 
        self.dbhost = ""
26
 
        self.dbuser = ""
27
 
        self.dbpasswd = ""
28
 
        self.connection = None
29
 
        self.timeout = 15
30
 
        self.oldstyle = ""
31
 
        self.dbtype = dbtype or config['dbtype'] or 'mysql'
32
 
        if doconnect:
33
 
            self.connect()
34
 
 
35
 
    @dblocked
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':
46
 
            import MySQLdb
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':
51
 
            import sqlite
52
 
            self.connection = sqlite.connect(datadir + os.sep + self.dbname)
53
 
        elif self.dbtype == 'postgres':
54
 
            import psycopg2
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)
58
 
        else:
59
 
            rlog(100, 'db', 'unknown database type %s' % self.dbtype)
60
 
            return 0
61
 
        rlog(5, 'db', "database ok")
62
 
        return 1
63
 
 
64
 
    def reconnect(self):
65
 
        """ reconnect to the mysql server """
66
 
        if self.dbtype == 'mysql':
67
 
            import MySQLdb
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':
72
 
            import sqlite
73
 
            self.connection = sqlite.connect(self.dbname)
74
 
        elif self.dbtype == 'postgres':
75
 
            import psycopg2
76
 
            self.connection = psycopg2.connect(database=self.dbname, \
77
 
host=self.dbhost, user=self.dbuser, password=self.dbpasswd)
78
 
        else:
79
 
            rlog(100, 'db', 'unknown database type %s' % self.dbtype)
80
 
            return 0
81
 
        rlog(10, 'db', 'reconnect done')
82
 
        return 1
83
 
 
84
 
    @dblocked
85
 
    def execute(self, execstr, args=None):
86
 
        """ execute string on database """
87
 
        time.sleep(0.001)
88
 
        result = None
89
 
        execstr = execstr.strip()
90
 
        # first to ping to see if connection is alive .. if not reconnect
91
 
        if self.dbtype == 'mysql':
92
 
            try:
93
 
                self.ping()
94
 
            except Exception, ex:
95
 
                rlog(10, 'db', "can't ping database: %s" % str(ex))
96
 
                rlog(10, 'db', 'reconnecting')
97
 
                try:
98
 
                    self.reconnect()
99
 
                except Exception, ex:
100
 
                    rlog(10, 'db', 'failed reconnect: %s' % str(ex))
101
 
                    return
102
 
        # get cursor
103
 
        cursor = self.cursor()
104
 
        # excecute string on cursor
105
 
        nr = 0
106
 
        if args:
107
 
            if self.oldstyle:
108
 
                nargs = []
109
 
                for i in args:
110
 
                    nargs.append(tolatin1(i))
111
 
                args = nargs
112
 
            rlog(-2, 'db', 'exec %s %s' % (execstr, args))
113
 
            try:
114
 
                if type(args) == tuple or type(args) == list:
115
 
                    nr = cursor.execute(execstr, args)
116
 
                else:
117
 
                    nr = cursor.execute(execstr, (args, ))
118
 
            except:
119
 
                if self.dbtype == 'postgres':
120
 
                    cursor.execute(""" ROLLBACK """)
121
 
                raise
122
 
        else:
123
 
            rlog(-2, 'db', 'exec %s' % execstr)
124
 
            nr = cursor.execute(execstr)
125
 
        # see if we need to commit the query
126
 
        got = False
127
 
        if execstr.startswith('INSERT') or execstr.startswith('UPDATE'):
128
 
            nr = cursor.lastrowid or nr
129
 
            got = True
130
 
        elif execstr.startswith('DELETE'):
131
 
            nr = cursor.rowcount
132
 
            got = True
133
 
        if got:
134
 
            self.commit()
135
 
        # fetch results
136
 
        result = None
137
 
        try:
138
 
            result = cursor.fetchall()
139
 
            if not result:
140
 
                result = nr
141
 
        except Exception, ex:
142
 
            if 'no results to fetch' in str(ex):
143
 
                pass
144
 
            else:
145
 
                handle_exception()
146
 
            result = nr
147
 
        cursor.close()
148
 
        return result
149
 
 
150
 
    def cursor(self):
151
 
        """ return cursor to the database """
152
 
        return self.connection.cursor()
153
 
 
154
 
    def commit(self):
155
 
        """ do a commit on the datase """
156
 
        self.connection.commit()
157
 
 
158
 
    def ping(self):
159
 
        """ do a ping """
160
 
        return self.connection.ping()
161
 
 
162
 
    def close(self):
163
 
        """ close database """
164
 
        self.connection.close()
165
 
 
166
 
# create default database if enabled
167
 
cfg = config['dbenable']
168
 
if cfg:
169
 
    db = Db()
170
 
else:
171
 
    db = None