Index: /pykota/trunk/checkdeps.py
===================================================================
--- /pykota/trunk/checkdeps.py (revision 2629)
+++ /pykota/trunk/checkdeps.py (revision 2638)
@@ -70,4 +70,5 @@
     modulestocheck = [ ("Python-PygreSQL", "pg", "PygreSQL is mandatory if you want to use PostgreSQL as the quota database backend.\nSee http://www.pygresql.org"),
                        ("Python-SQLite", "pysqlite2", "Python-SQLite is mandatory if you want to use SQLite as the quota database backend.\nSee http://www.pysqlite.org"),
+		       ("MySQL-Python", "MySQLdb", "MySQL-Python is mandatory if you want to use MySQL as the quota database backend.\nSee http://sourceforge.net/projects/mysql-python"),
                        ("Python-egenix-mxDateTime", "mx.DateTime", "eGenix' mxDateTime is mandatory for PyKota to work.\nSee http://www.egenix.com"),
                        ("Python-LDAP", "ldap", "Python-LDAP is mandatory if you plan to use an LDAP\ndirectory as the quota database backend.\nSee http://python-ldap.sf.net"),
Index: /pykota/trunk/conf/pykotadmin.conf.sample
===================================================================
--- /pykota/trunk/conf/pykotadmin.conf.sample (revision 2622)
+++ /pykota/trunk/conf/pykotadmin.conf.sample (revision 2638)
@@ -60,5 +60,5 @@
 # For SQLite3, you can comment out all the lines in this file.
 
-# PostgreSQL's Quota Storage administrator's name and password
+# PostgreSQL's or MySQL's Quota Storage administrator's name and password
 # Please comment these lines out and see further below if you use LDAP.
 storageadmin: pykotaadmin
Index: /pykota/trunk/conf/pykota.conf.sample
===================================================================
--- /pykota/trunk/conf/pykota.conf.sample (revision 2635)
+++ /pykota/trunk/conf/pykota.conf.sample (revision 2638)
@@ -49,7 +49,7 @@
 # Storage backend for quotas
 # only PGStorage (PostgreSQL), LDAPStorage (OpenLDAP or else),
-# and SQLiteStorage (SQLite 3) are supported.
-#
-# MySQL and BerkeleyDB are planned.
+# MySQLStorage (MySQL) and SQLiteStorage (SQLite 3) are supported.
+#
+# BerkeleyDB is planned.
 
 ####################################################################
@@ -60,8 +60,9 @@
 #storagename: /etc/pykota/pykota.db
 
-####################################################################
-# PostgreSQL : comment this section out if you use another backend #
-####################################################################
+############################################################################
+# PostgreSQL or MySQL: comment this section out if you use another backend #
+############################################################################
 storagebackend: pgstorage
+# storagebackend: mysqlstorage
 
 # Quota Storage Server hostname (and optional port)
Index: /pykota/trunk/setup.py
===================================================================
--- /pykota/trunk/setup.py (revision 2622)
+++ /pykota/trunk/setup.py (revision 2638)
@@ -68,4 +68,5 @@
 data_files.append((os.path.join(docdir, "postgresql"), ["initscripts/postgresql/README.postgresql"]))
 data_files.append((os.path.join(docdir, "ldap"), ["initscripts/ldap/README.ldap"]))
+data_files.append((os.path.join(docdir, "mysql"), ["initscripts/mysql/README.mysql"]))
 
 directory = os.sep.join(["share", "man", "man1"])
@@ -105,4 +106,7 @@
 data_files.append((ldapdirectory, ["initscripts/ldap/README.ldap", "initscripts/ldap/pykota.schema", "initscripts/ldap/pykota-sample.ldif"]))
 
+mysqldirectory = os.sep.join([directory, "mysql"])
+data_files.append((mysqldirectory, ["initscripts/mysql/README.mysql", "initscripts/mysql/pykota-mysql.sql"]))
+
 os.umask(022)
 setup(name = "pykota", version = __version__,
Index: /pykota/trunk/README
===================================================================
--- /pykota/trunk/README (revision 2622)
+++ /pykota/trunk/README (revision 2638)
@@ -62,4 +62,7 @@
           An SQL script to create the database is included.
           
+        - Supports MySQL as the database backend.
+          An SQL script to create the database is included.
+
         - The print jobs history can be stored in any database  
           of your choice (or in plain text files) if needed. 
@@ -383,4 +386,8 @@
       as the database backend (http://www.sqlite.org). You also need the 
       PySQLite module v2.0.5 or higher (http://www.pysqlite.org)
+ or
+    - MySQL 4.0 or higher and the MySQL-python bindings. 
+      IMPORTANT: If you are using MySQL 4.1, then MySQL-python must be 
+      version 1.2 or greater. Version 1.0 does not work correctly with 4.1.
       
     
Index: /pykota/trunk/pykota/storages/sql.py
===================================================================
--- /pykota/trunk/pykota/storages/sql.py (revision 2622)
+++ /pykota/trunk/pykota/storages/sql.py (revision 2638)
@@ -226,5 +226,5 @@
         userpquota = StorageUserPQuota(self, user, printer)
         if printer.Exists and user.Exists :
-            result = self.doSearch("SELECT * FROM userpquota WHERE userid=%s AND printerid=%s" % (self.doQuote(user.ident), self.doQuote(printer.ident)))
+            result = self.doSearch("SELECT * FROM userpquota WHERE userid=%s AND printerid=%s;" % (self.doQuote(user.ident), self.doQuote(printer.ident)))
             if result :
                 fields = result[0]
Index: /pykota/trunk/initscripts/mysql/pykota-mysql.sql
===================================================================
--- /pykota/trunk/initscripts/mysql/pykota-mysql.sql (revision 2622)
+++ /pykota/trunk/initscripts/mysql/pykota-mysql.sql (revision 2638)
@@ -31,53 +31,66 @@
 -- Create the print quota database
 --
+CREATE DATABASE pykota;
 
 --
 -- Create the print quota database users
 -- 
--- TODO : CREATE USER pykotaadmin;
--- TODO : CREATE USER pykotauser;
+GRANT USAGE ON *.* TO 'pykotauser'@'localhost' IDENTIFIED BY 'readonly';
+GRANT USAGE ON *.* TO 'pykotaadmin'@'localhost' IDENTIFIED BY 'readwrite';
 
 -- 
 -- Now connect to the new database
 -- 
-\u pykota
+use pykota;
 
 --
 -- Create the users table
 --
-CREATE TABLE users(id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
+CREATE TABLE users (id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
                    username VARCHAR(255) UNIQUE NOT NULL,
                    email TEXT, 
                    balance FLOAT DEFAULT 0.0,
                    lifetimepaid FLOAT DEFAULT 0.0,
-                   limitby VARCHAR(30) DEFAULT 'quota');
+                   limitby VARCHAR(30) DEFAULT 'quota',
+		   description TEXT,
+		   overcharge FLOAT NOT NULL DEFAULT 1.0) TYPE=INNODB;
                    
 --
 -- Create the groups table
 --
-CREATE TABLE groups(id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
+CREATE TABLE groups (id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
                     groupname VARCHAR(255) UNIQUE NOT NULL,
-                    limitby VARCHAR(30) DEFAULT 'quota');
+		    description TEXT,
+                    limitby VARCHAR(30) DEFAULT 'quota') TYPE=INNODB;
                     
 --
 -- Create the printers table
 --
-CREATE TABLE printers(id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
+CREATE TABLE printers (id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
                       printername VARCHAR(255) UNIQUE NOT NULL,
                       description TEXT,
                       priceperpage FLOAT DEFAULT 0.0,
-                      priceperjob FLOAT DEFAULT 0.0);
+                      priceperjob FLOAT DEFAULT 0.0,
+		      passthrough ENUM('t','f') DEFAULT 'f',
+		      maxjobsize INT4) TYPE=INNODB;
                     
 --
 -- Create the print quota table for users
 --
-CREATE TABLE userpquota(id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
-                        userid INT4 REFERENCES users(id),
-                        printerid INT4 REFERENCES printers(id),
+CREATE TABLE userpquota (id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
+                        userid INT4, 
+                        printerid INT4, 
                         lifepagecounter INT4 DEFAULT 0,
                         pagecounter INT4 DEFAULT 0,
                         softlimit INT4,
                         hardlimit INT4,
-                        datelimit TIMESTAMP);
+                        datelimit TIMESTAMP,
+			maxjobsize INT4,
+                        warncount INT4 DEFAULT 0, 
+			FOREIGN KEY (userid) REFERENCES users(id),
+			FOREIGN KEY (printerid) REFERENCES printers(id)) 
+			TYPE=INNODB;
+CREATE INDEX userpquota_u_id_ix ON userpquota (userid);
+CREATE INDEX userpquota_p_id_ix ON userpquota (printerid);
 CREATE UNIQUE INDEX userpquota_up_id_ix ON userpquota (userid, printerid);
                         
@@ -99,7 +112,12 @@
                         options TEXT,
                         hostname VARCHAR(255),
-                        jobdate TIMESTAMP,
-                        CONSTRAINT checkUserPQuota FOREIGN KEY (userid, printerid) 
-                                                           REFERENCES userpquota(userid, printerid));
+			md5sum TEXT,
+			pages TEXT,
+			billingcode TEXT,
+			precomputedjobsize INT4,
+			precomputedjobprice FLOAT,
+                        jobdate TIMESTAMP DEFAULT,
+                        CONSTRAINT checkUserPQuota FOREIGN KEY (userid, printerid) REFERENCES userpquota(userid, printerid)) TYPE=INNODB;
+CREATE INDEX jobhistory_u_id_ix ON jobhistory (userid);
 CREATE INDEX jobhistory_p_id_ix ON jobhistory (printerid);
 CREATE INDEX jobhistory_pd_id_ix ON jobhistory (printerid, jobdate);
@@ -110,9 +128,15 @@
 --
 CREATE TABLE grouppquota(id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
-                         groupid INT4 REFERENCES groups(id),
-                         printerid INT4 REFERENCES printers(id),
+                         groupid INT4, 
+                         printerid INT4,
                          softlimit INT4,
                          hardlimit INT4,
-                         datelimit TIMESTAMP);
+			 maxjobsize INT4,
+                         datelimit TIMESTAMP,
+			 FOREIGN KEY (groupid) REFERENCES groups(id),
+			 FOREIGN KEY (printerid) REFERENCES printers(id))
+			 TYPE=INNODB;
+CREATE INDEX grouppquota_g_id_ix ON grouppquota (groupid);
+CREATE INDEX grouppquota_p_id_ix ON grouppquota (printerid);
 CREATE UNIQUE INDEX grouppquota_up_id_ix ON grouppquota (groupid, printerid);
                         
@@ -120,31 +144,51 @@
 -- Create the groups/members relationship
 --
-CREATE TABLE groupsmembers(groupid INT4 REFERENCES groups(id),
-                           userid INT4 REFERENCES users(id),
-                           PRIMARY KEY (groupid, userid));
+CREATE TABLE groupsmembers(groupid INT4,
+                           userid INT4,
+			   FOREIGN KEY (groupid) REFERENCES groups(id),
+			   FOREIGN KEY (userid) REFERENCES users(id),
+                           PRIMARY KEY (groupid, userid)) TYPE=INNODB;
                            
 --                         
 -- Create the printer groups relationship
 --
-CREATE TABLE printergroupsmembers(groupid INT4 REFERENCES printers(id),
-                           printerid INT4 REFERENCES printers(id),
-                           PRIMARY KEY (groupid, printerid));
+CREATE TABLE printergroupsmembers(groupid INT4,
+                           printerid INT4,
+			   FOREIGN KEY (groupid) REFERENCES groups(id),
+			   FOREIGN KEY (printerid) REFERENCES printers(id),
+                           PRIMARY KEY (groupid, printerid)) TYPE=INNODB;
 --
 -- Create the table for payments
 -- 
 CREATE TABLE payments (id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
-                       userid INT4 REFERENCES users(id),
+                       userid INT4,
                        amount FLOAT,
-                       date TIMESTAMP DEFAULT now());
+		       description TEXT,
+                       date TIMESTAMP DEFAULT now(),
+		       FOREIGN KEY (userid) REFERENCES users(id)) TYPE=INNODB;
 CREATE INDEX payments_date_ix ON payments (date);
 
+--
+-- Create the table for coefficients wrt paper sizes and the like
+--
+CREATE TABLE coefficients (id INT4 PRIMARY KEY NOT NULL AUTO_INCREMENT,
+			   printerid INT4 NOT NULL,
+			   label VARCHAR(255) NOT NULL,
+			   coefficient FLOAT DEFAULT 1.0,
+			   FOREIGN KEY (printerid) REFERENCES printers(id),
+			   CONSTRAINT coeffconstraint UNIQUE (printerid, label));
+
+-- 
+-- Create the table for the billing codes
+--
+CREATE TABLE billingcodes (id INT4 PRIMARY KEY NOT NULL,
+                           billingcode VARCHAR(255) UNIQUE NOT NULL,
+                           description TEXT,
+                           balance FLOAT DEFAULT 0.0,
+                           pagecounter INT4 DEFAULT 0) TYPE=INNODB;
 --                        
 -- Set some ACLs                        
 --
--- TODO : REVOKE ALL ON users, groups, printers, userpquota, grouppquota, groupsmembers, printergroupsmembers, jobhistory, payments FROM public;                        
--- TODO : REVOKE ALL ON users_id_seq, groups_id_seq, printers_id_seq, userpquota_id_seq, grouppquota_id_seq, jobhistory_id_seq, payments_id_seq FROM public;
+GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON `pykota`.* TO 'pykotaadmin'@'localhost';
+GRANT SELECT ON `pykota`.* TO 'pykotauser'@'localhost';
 
--- TODO : GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON users, groups, printers, userpquota, grouppquota, groupsmembers, printergroupsmembers, jobhistory, payments TO pykotaadmin;
--- TODO : GRANT SELECT, UPDATE ON users_id_seq, groups_id_seq, printers_id_seq, userpquota_id_seq, grouppquota_id_seq, jobhistory_id_seq, payments_id_seq TO pykotaadmin;
--- TODO : GRANT SELECT ON users, groups, printers, userpquota, grouppquota, groupsmembers, printergroupsmembers, jobhistory, payments TO pykotauser;
-
