root / pykota / trunk / pykota / storages / mysqlstorage.py @ 2874

Revision 2874, 6.4 kB (checked in by jerome, 18 years ago)

Explicitely sets the default TCP ports to use, because it seems that once again, MySQL fails to be smart...

  • Property svn:keywords set to Author Date Id Revision
Line 
1# PyKota
2# -*- coding: ISO-8859-15 -*-
3#
4# PyKota : Print Quotas for CUPS and LPRng
5#
6# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
7# (c) 2005, 2006 Matt Hyclak <hyclak@math.ohiou.edu>
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21#
22# $Id$
23#
24#
25
26import time
27
28from pykota.storage import PyKotaStorageError, BaseStorage
29from pykota.storages.sql import SQLStorage
30
31try :
32    import MySQLdb
33except ImportError :   
34    import sys
35    # TODO : to translate or not to translate ?
36    raise PyKotaStorageError, "This python version (%s) doesn't seem to have the MySQL module installed correctly." % sys.version.split()[0]
37
38class Storage(BaseStorage, SQLStorage) :
39    def __init__(self, pykotatool, host, dbname, user, passwd) :
40        """Opens the MySQL database connection."""
41        BaseStorage.__init__(self, pykotatool)
42        try :
43            (host, port) = host.split(":")
44            port = int(port)
45        except ValueError :   
46            port = 3306           # Use the default MySQL port
47       
48        self.tool.logdebug("Trying to open database (host=%s, port=%s, dbname=%s, user=%s)..." % (host, port, dbname, user))
49        self.database = MySQLdb.connect(host=host, port=port, db=dbname, user=user, passwd=passwd)
50        self.database.autocommit(1)
51        self.cursor = self.database.cursor()
52        self.cursor.execute("SET TRANSACTION ISOLATION LEVEL READ COMMITTED;") # Same as PostgreSQL and Oracle's default
53        self.closed = 0
54        self.tool.logdebug("Database opened (host=%s, port=%s, dbname=%s, user=%s)" % (host, port, dbname, user))
55           
56    def close(self) :   
57        """Closes the database connection."""
58        if not self.closed :
59            self.cursor.close()
60            self.database.close()
61            self.closed = 1
62            self.tool.logdebug("Database closed.")
63       
64    def beginTransaction(self) :   
65        """Starts a transaction."""
66        self.before = time.time()
67        self.cursor.execute("BEGIN;")
68        self.tool.logdebug("Transaction begins...")
69       
70    def commitTransaction(self) :   
71        """Commits a transaction."""
72        self.database.commit()
73        after = time.time()
74        self.tool.logdebug("Transaction committed.")
75        self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))
76       
77    def rollbackTransaction(self) :     
78        """Rollbacks a transaction."""
79        self.database.rollback()
80        after = time.time()
81        self.tool.logdebug("Transaction aborted.")
82        self.tool.logdebug("Transaction duration : %.4f seconds" % (after - self.before))
83       
84    def doRawSearch(self, query) :
85        """Does a raw search query."""
86        query = query.strip()   
87        if not query.endswith(';') :   
88            query += ';'
89        try :
90            before = time.time()
91            self.tool.logdebug("QUERY : %s" % query)
92            self.cursor.execute(query)
93        except self.database.Error, msg :   
94            raise PyKotaStorageError, str(msg)
95        else :   
96            # This returns a list of lists. Integers are returned as longs.
97            result = self.cursor.fetchall()
98            after = time.time()
99            self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))
100            return result
101           
102    def doSearch(self, query) :       
103        """Does a search query."""
104        result = self.doRawSearch(query)
105        if result :
106            rows = []
107            fields = {}
108            for i in range(len(self.cursor.description)) :
109                fields[i] = self.cursor.description[i][0]
110            for row in result :
111                rowdict = {}
112                for field in fields.keys() :
113                    value = row[field]
114                    try :
115                        value = value.encode("UTF-8")
116                    except:
117                        pass
118                    rowdict[fields[field]] = value
119                rows.append(rowdict)
120            # returns a list of dicts
121            return rows
122
123    def doModify(self, query) :
124        """Does a (possibly multiple) modify query."""
125        query = query.strip()   
126        if not query.endswith(';') :   
127            query += ';'
128        try :
129            before = time.time()
130            self.tool.logdebug("QUERY : %s" % query)
131            self.cursor.execute(query)
132        except self.database.Error, msg :   
133            self.tool.logdebug("Query failed : %s" % repr(msg))
134            raise PyKotaStorageError, str(msg)
135        else :   
136            after = time.time()
137            self.tool.logdebug("Query Duration : %.4f seconds" % (after - before))
138           
139    def doQuote(self, field) :
140        """Quotes a field for use as a string in SQL queries."""
141        if type(field) == type(0.0) :
142            return field
143        elif type(field) == type(0) :
144            return field
145        elif type(field) == type(0L) :
146            return field
147        elif field is not None :
148            newfield = self.database.string_literal(field)
149            try :
150                return newfield.encode("UTF-8")
151            except :   
152                return newfield
153        else :
154            self.tool.logdebug("WARNING: field has no type, returning NULL")
155            return "NULL"
156
157    def prepareRawResult(self, result) :
158        """Prepares a raw result by including the headers."""
159        if result :
160            entries = [tuple([f[0] for f in self.cursor.description])]
161            for entry in result :
162                row = []
163                for value in entry :
164                    try :
165                        value = value.encode("UTF-8")
166                    except :
167                        pass
168                    row.append(value)
169                entries.append(tuple(row))
170            return entries
Note: See TracBrowser for help on using the browser.