Index: pykota/trunk/pykota/storages/pgstorage.py
===================================================================
--- pykota/trunk/pykota/storages/pgstorage.py (revision 1259)
+++ pykota/trunk/pykota/storages/pgstorage.py (revision 1269)
@@ -22,4 +22,8 @@
 #
 # $Log$
+# Revision 1.31  2004/01/10 09:44:02  jalet
+# Fixed potential accuracy problem if a user printed on several printers at
+# the very same time.
+#
 # Revision 1.30  2004/01/08 16:33:27  jalet
 # Additionnal check to not create a circular printers group.
@@ -213,5 +217,5 @@
         """Extracts all user names."""
         usernames = []
-        result = self.doSearch("SELECT username FROM users;")
+        result = self.doSearch("SELECT username FROM users")
         if result :
             usernames = [record["username"] for record in result]
@@ -221,5 +225,5 @@
         """Extracts all group names."""
         groupnames = []
-        result = self.doSearch("SELECT groupname FROM groups;")
+        result = self.doSearch("SELECT groupname FROM groups")
         if result :
             groupnames = [record["groupname"] for record in result]
@@ -354,5 +358,5 @@
         """Get all the printer groups this printer is a member of."""
         pgroups = []
-        result = self.doSearch("SELECT groupid,printername FROM printergroupsmembers JOIN printers ON groupid=id WHERE printerid=%s;" % self.doQuote(printer.ident))
+        result = self.doSearch("SELECT groupid,printername FROM printergroupsmembers JOIN printers ON groupid=id WHERE printerid=%s" % self.doQuote(printer.ident))
         if result :
             for record in result :
@@ -477,14 +481,22 @@
         self.doModify("UPDATE grouppquota SET datelimit=%s WHERE id=%s" % (self.doQuote(datelimit), self.doQuote(grouppquota.ident)))
         
+    def increaseUserPQuotaPagesCounters(self, userpquota, nbpages) :    
+        """Increase page counters for a user print quota."""
+        self.doModify("UPDATE userpquota SET pagecounter=pagecounter+%s,lifepagecounter=lifepagecounter+%s WHERE id=%s" % (self.doQuote(nbpages), self.doQuote(nbpages), self.doQuote(userpquota.ident)))
+       
     def writeUserPQuotaPagesCounters(self, userpquota, newpagecounter, newlifepagecounter) :    
-       """Sets the new page counters permanently for a user print quota."""
-       self.doModify("UPDATE userpquota SET pagecounter=%s,lifepagecounter=%s WHERE id=%s" % (self.doQuote(newpagecounter), self.doQuote(newlifepagecounter), self.doQuote(userpquota.ident)))
+        """Sets the new page counters permanently for a user print quota."""
+        self.doModify("UPDATE userpquota SET pagecounter=%s,lifepagecounter=%s WHERE id=%s" % (self.doQuote(newpagecounter), self.doQuote(newlifepagecounter), self.doQuote(userpquota.ident)))
+       
+    def decreaseUserAccountBalance(self, user, amount) :    
+        """Decreases user's account balance from an amount."""
+        self.doModify("UPDATE users SET balance=balance-%s WHERE id=%s" % (self.doQuote(amount), self.doQuote(user.ident)))
        
     def writeUserAccountBalance(self, user, newbalance, newlifetimepaid=None) :    
-       """Sets the new account balance and eventually new lifetime paid."""
-       if newlifetimepaid is not None :
-           self.doModify("UPDATE users SET balance=%s, lifetimepaid=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(newlifetimepaid), self.doQuote(user.ident)))
-       else :    
-           self.doModify("UPDATE users SET balance=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(user.ident)))
+        """Sets the new account balance and eventually new lifetime paid."""
+        if newlifetimepaid is not None :
+            self.doModify("UPDATE users SET balance=%s, lifetimepaid=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(newlifetimepaid), self.doQuote(user.ident)))
+        else :    
+            self.doModify("UPDATE users SET balance=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(user.ident)))
             
     def writeLastJobSize(self, lastjob, jobsize, jobprice) :        
@@ -501,5 +513,5 @@
         else :        
             # here we explicitly want to reset jobsize to NULL if needed
-            self.doModify("UPDATE jobhistory SET userid=%s, jobid=%s, pagecounter=%s, action=%s, jobsize=%s, jobprice=%s, filename=%s, title=%s, copies=%s, options=%s, jobdate=now() WHERE id=%s;" % (self.doQuote(user.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options), self.doQuote(printer.LastJob.ident)))
+            self.doModify("UPDATE jobhistory SET userid=%s, jobid=%s, pagecounter=%s, action=%s, jobsize=%s, jobprice=%s, filename=%s, title=%s, copies=%s, options=%s, jobdate=now() WHERE id=%s" % (self.doQuote(user.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(filename), self.doQuote(title), self.doQuote(copies), self.doQuote(options), self.doQuote(printer.LastJob.ident)))
             
     def writeUserPQuotaLimits(self, userpquota, softlimit, hardlimit) :
@@ -514,10 +526,10 @@
         """Puts a printer into a printer group."""
         children = []
-        result = self.doSearch("SELECT printerid FROM printergroupsmembers WHERE groupid=%s;" % self.doQuote(pgroup.ident))
+        result = self.doSearch("SELECT printerid FROM printergroupsmembers WHERE groupid=%s" % self.doQuote(pgroup.ident))
         if result :
             for record in result :
                 children.append(record.get("printerid")) # TODO : put this into the database integrity rules
         if printer.ident not in children :        
-            self.doModify("INSERT INTO printergroupsmembers (groupid, printerid) VALUES (%s, %s);" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident)))
+            self.doModify("INSERT INTO printergroupsmembers (groupid, printerid) VALUES (%s, %s)" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident)))
         
     def deleteUser(self, user) :    
Index: pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- pykota/trunk/pykota/storages/ldapstorage.py (revision 1259)
+++ pykota/trunk/pykota/storages/ldapstorage.py (revision 1269)
@@ -22,4 +22,8 @@
 #
 # $Log$
+# Revision 1.47  2004/01/10 09:44:02  jalet
+# Fixed potential accuracy problem if a user printed on several printers at
+# the very same time.
+#
 # Revision 1.46  2004/01/08 16:33:27  jalet
 # Additionnal check to not create a circular printers group.
@@ -285,7 +289,19 @@
     def doModify(self, dn, fields, ignoreold=1) :
         """Modifies an entry in the LDAP directory."""
-        fields = self.normalizeFields(fields)
         try :
             oldentry = self.doSearch("objectClass=*", base=dn, scope=ldap.SCOPE_BASE)
+            for (k, v) in fields.items() :
+                if type(v) == type({}) :
+                    try :
+                        oldvalue = v["convert"](oldentry[0][1].get(k, [0])[0])
+                    except ValueError :    
+                        self.tool.logdebug("Error converting %s with %s(%s)" % (oldentry[0][1].get(k), k, v))
+                        oldvalue = 0
+                    if v["operator"] == '+' :
+                        newvalue = oldvalue + v["value"]
+                    else :    
+                        newvalue = oldvalue - v["value"]
+                    fields[k] = str(newvalue)
+            fields = self.normalizeFields(fields)
             self.tool.logdebug("QUERY : Modify(%s, %s ==> %s)" % (dn, oldentry[0][1], fields))
             self.database.modify_s(dn, modlist.modifyModlist(oldentry[0][1], fields, ignore_oldexistent=ignoreold))
@@ -735,4 +751,12 @@
         return self.doModify(grouppquota.ident, fields)
         
+    def increaseUserPQuotaPagesCounters(self, userpquota, nbpages) :    
+        """Increase page counters for a user print quota."""
+        fields = {
+                   "pykotaPageCounter" : { "operator" : "+", "value" : nbpages, "convert" : int },
+                   "pykotaLifePageCounter" : { "operator" : "+", "value" : nbpages, "convert" : int },
+                 }
+        return self.doModify(userpquota.ident, fields)         
+        
     def writeUserPQuotaPagesCounters(self, userpquota, newpagecounter, newlifepagecounter) :    
         """Sets the new page counters permanently for a user print quota."""
@@ -742,4 +766,11 @@
                  }  
         return self.doModify(userpquota.ident, fields)         
+       
+    def decreaseUserAccountBalance(self, user, amount) :    
+        """Decreases user's account balance from an amount."""
+        fields = {
+                   "pykotaBalance" : { "operator" : "-", "value" : amount, "convert" : float },
+                 }
+        return self.doModify(user.idbalance, fields)         
        
     def writeUserAccountBalance(self, user, newbalance, newlifetimepaid=None) :    
@@ -825,6 +856,7 @@
         """Puts a printer into a printer group."""
         if printer.ident not in pgroup.uniqueMember :
+            pgroup.uniqueMember.append(printer.ident)
             fields = {
-                       "uniqueMember" : pgroup.uniqueMember + [printer.ident]
+                       "uniqueMember" : pgroup.uniqueMember
                      }  
             self.doModify(pgroup.ident, fields)         
