Index: /pykota/trunk/pykota/storages/mysqlstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/mysqlstorage.py (revision 2639)
+++ /pykota/trunk/pykota/storages/mysqlstorage.py (revision 2639)
@@ -0,0 +1,148 @@
+# PyKota
+# -*- coding: ISO-8859-15 -*-
+#
+# PyKota : Print Quotas for CUPS and LPRng
+#
+# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
+# (c) 2005 Matt Hyclak <hyclak@math.ohiou.edu>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# $Id: pgstorage.py 1725 2005-09-03 12:20:30Z jerome $
+#
+#
+
+from pykota.storage import PyKotaStorageError,BaseStorage,StorageObject,StorageUser,StorageGroup,StoragePrinter,StorageJob,StorageLastJob,StorageUserPQuota,StorageGroupPQuota
+from pykota.storages.sql import SQLStorage
+
+try :
+    import MySQLdb
+except ImportError :    
+    import sys
+    # TODO : to translate or not to translate ?
+    raise PyKotaStorageError, "This python version (%s) doesn't seem to have the MySQL module installed correctly." % sys.version.split()[0]
+
+class Storage(BaseStorage, SQLStorage) :
+    def __init__(self, pykotatool, host, dbname, user, passwd) :
+        """Opens the MySQL database connection."""
+        BaseStorage.__init__(self, pykotatool)
+        try :
+            (host, port) = host.split(":")
+            port = int(port)
+        except ValueError :    
+            port = -1		# Use the default MySQL port
+        
+        self.tool.logdebug("Trying to open database (host=%s, port=%s, dbname=%s, user=%s)..." % (host, port, dbname, user))
+        self.database = MySQLdb.connect(host=host, port=port, db=dbname, user=user, passwd=passwd)
+	self.cursor = self.database.cursor()
+        self.closed = 0
+        self.tool.logdebug("Database opened (host=%s, port=%s, dbname=%s, user=%s)" % (host, port, dbname, user))
+            
+    def close(self) :    
+        """Closes the database connection."""
+        if not self.closed :
+	    self.cursor.close()
+            self.database.close()
+            self.closed = 1
+            self.tool.logdebug("Database closed.")
+        
+    def beginTransaction(self) :    
+        """Starts a transaction."""
+        self.database.begin()
+        self.tool.logdebug("Transaction begins...")
+        
+    def commitTransaction(self) :    
+        """Commits a transaction."""
+        self.database.commit()
+        self.tool.logdebug("Transaction committed.")
+        
+    def rollbackTransaction(self) :     
+        """Rollbacks a transaction."""
+        self.database.rollback()
+        self.tool.logdebug("Transaction aborted.")
+        
+    def doRawSearch(self, query) :
+        """Does a raw search query."""
+        query = query.strip()    
+        if not query.endswith(';') :    
+            query += ';'
+        try :
+            self.tool.logdebug("QUERY : %s" % query)
+            self.cursor.execute(query)
+        except self.database.Error, msg :    
+            raise PyKotaStorageError, str(msg)
+        else :    
+	    # This returns a list of lists. Integers are returned as longs.
+            return self.cursor.fetchall()
+            
+    def doSearch(self, query) :        
+        """Does a search query."""
+        result = self.doRawSearch(query)
+	if result :
+	    rows = []
+            fields = {}
+            for i in range(len(self.cursor.description)) :
+		fields[i] = self.cursor.description[i][0]
+	    for row in result :
+                rowdict = {}
+                for field in fields.keys() :
+		    value = row[field]
+		    try :
+			value = value.encode("UTF-8")
+		    except:
+			pass
+		    rowdict[fields[field]] = value
+		rows.append(rowdict)
+	    # returns a list of dicts
+	    return rows
+
+    def doModify(self, query) :
+        """Does a (possibly multiple) modify query."""
+        query = query.strip()    
+        if not query.endswith(';') :    
+            query += ';'
+        try :
+            self.tool.logdebug("QUERY : %s" % query)
+            self.cursor.execute(query)
+        except self.database.Error, msg :    
+            raise PyKotaStorageError, str(msg)
+            
+    def doQuote(self, field) :
+        """Quotes a field for use as a string in SQL queries."""
+        if type(field) == type(0.0) :
+            return field
+        elif type(field) == type(0) :
+            return field
+        elif type(field) == type(0L) :
+            return field
+        elif field is not None :
+            return (self.database.string_literal(field)).encode("UTF-8")
+        else :
+	    self.tool.logdebug("WARNING: field has no type, returning NULL")
+            return "NULL"
+
+    def prepareRawResult(self, result) :
+        """Prepares a raw result by including the headers."""
+        if result :
+            entries = [tuple([f[0] for f in self.cursor.description])]
+	    for entry in result :
+                row = []
+                for value in entry :
+                    try :
+                        value = value.encode("UTF-8")
+                    except :
+                        pass
+                    row.append(value)
+                entries.append(tuple(row))
+            return entries
