Index: /pykota/trunk/pykota/storages/sql.py
===================================================================
--- /pykota/trunk/pykota/storages/sql.py (revision 2734)
+++ /pykota/trunk/pykota/storages/sql.py (revision 2735)
@@ -672,8 +672,4 @@
         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, warncount=0, datelimit=NULL WHERE id=%s" % (self.doQuote(newpagecounter), self.doQuote(newlifepagecounter), self.doQuote(userpquota.ident)))
-       
     def saveBillingCode(self, code) :    
         """Saves the billing code to the database."""
@@ -718,7 +714,14 @@
             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, hostname=%s, jobsizebytes=%s, md5sum=%s, pages=%s, billingcode=%s, precomputedjobsize=%s, precomputedjobprice=%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(clienthost), self.doQuote(jobsizebytes), self.doQuote(jobmd5sum), self.doQuote(jobpages), self.doQuote(jobbilling), self.doQuote(precomputedsize), self.doQuote(precomputedprice), self.doQuote(printer.LastJob.ident)))
             
-    def writeUserPQuotaLimits(self, userpquota, softlimit, hardlimit) :
-        """Sets soft and hard limits for a user quota."""
-        self.doModify("UPDATE userpquota SET softlimit=%s, hardlimit=%s, warncount=0, datelimit=NULL WHERE id=%s" % (self.doQuote(softlimit), self.doQuote(hardlimit), self.doQuote(userpquota.ident)))
+    def saveUserPQuota(self, userpquota) :
+        """Saves an user print quota entry."""
+        self.doModify("UPDATE userpquota SET softlimit=%s, hardlimit=%s, warncount=%s, datelimit=%s, pagecounter=%s, lifepagecounter=%s WHERE id=%s" \
+                              % (self.doQuote(userpquota.SoftLimit), \
+                                 self.doQuote(userpquota.HardLimit), \
+                                 self.doQuote(userpquota.WarnCount), \
+                                 self.doQuote(userpquota.DateLimit), \
+                                 self.doQuote(userpquota.PageCounter), \
+                                 self.doQuote(userpquota.LifePageCounter), \
+                                 self.doQuote(userpquota.ident)))
         
     def writeUserPQuotaWarnCount(self, userpquota, warncount) :
@@ -730,7 +733,11 @@
         self.doModify("UPDATE userpquota SET warncount=warncount+1 WHERE id=%s" % self.doQuote(userpquota.ident))
         
-    def writeGroupPQuotaLimits(self, grouppquota, softlimit, hardlimit) :
-        """Sets soft and hard limits for a group quota on a specific printer."""
-        self.doModify("UPDATE grouppquota SET softlimit=%s, hardlimit=%s, datelimit=NULL WHERE id=%s" % (self.doQuote(softlimit), self.doQuote(hardlimit), self.doQuote(grouppquota.ident)))
+    def saveGroupPQuota(self, grouppquota) :
+        """Saves a group print quota entry."""
+        self.doModify("UPDATE grouppquota SET softlimit=%s, hardlimit=%s, datelimit=%s WHERE id=%s" \
+                              % (self.doQuote(grouppquota.SoftLimit), \
+                                 self.doQuote(grouppquota.HardLimit), \
+                                 self.doQuote(grouppquota.DateLimit), \
+                                 self.doQuote(grouppquota.ident)))
 
     def writePrinterToGroup(self, pgroup, printer) :
Index: /pykota/trunk/pykota/storages/ldapstorage.py
===================================================================
--- /pykota/trunk/pykota/storages/ldapstorage.py (revision 2726)
+++ /pykota/trunk/pykota/storages/ldapstorage.py (revision 2735)
@@ -1114,14 +1114,4 @@
         return self.doModify(userpquota.ident, fields)         
         
-    def writeUserPQuotaPagesCounters(self, userpquota, newpagecounter, newlifepagecounter) :    
-        """Sets the new page counters permanently for a user print quota."""
-        fields = {
-                   "pykotaPageCounter" : str(newpagecounter),
-                   "pykotaLifePageCounter" : str(newlifepagecounter),
-                   "pykotaDateLimit" : None,
-                   "pykotaWarnCount" : "0",
-                 }  
-        return self.doModify(userpquota.ident, fields)         
-       
     def decreaseUserAccountBalance(self, user, amount) :    
         """Decreases user's account balance from an amount."""
@@ -1208,11 +1198,13 @@
             self.doAdd(lastjdn, fields)          
             
-    def writeUserPQuotaLimits(self, userpquota, softlimit, hardlimit) :
-        """Sets soft and hard limits for a user quota."""
+    def saveUserPQuota(self, userpquota) :
+        """Saves an user print quota entry."""
         fields = { 
-                   "pykotaSoftLimit" : str(softlimit),
-                   "pykotaHardLimit" : str(hardlimit),
-                   "pykotaDateLimit" : "None",
-                   "pykotaWarnCount" : "0",
+                   "pykotaSoftLimit" : str(userpquota.SoftLimit),
+                   "pykotaHardLimit" : str(userpquota.HardLimit),
+                   "pykotaDateLimit" : str(userpquota.DateLimit),
+                   "pykotaWarnCount" : str(userpquota.WarnCount),
+                   "pykotaPageCounter" : str(userpquota.PageCounter),
+                   "pykotaLifePageCounter" : str(userpquota.LifePageCounter),
                  }
         self.doModify(userpquota.ident, fields)
@@ -1232,10 +1224,10 @@
         return self.doModify(userpquota.ident, fields)         
         
-    def writeGroupPQuotaLimits(self, grouppquota, softlimit, hardlimit) :
-        """Sets soft and hard limits for a group quota on a specific printer."""
+    def saveGroupPQuota(self, grouppquota) :
+        """Saves a group print quota entry."""
         fields = { 
-                   "pykotaSoftLimit" : str(softlimit),
-                   "pykotaHardLimit" : str(hardlimit),
-                   "pykotaDateLimit" : "None",
+                   "pykotaSoftLimit" : str(grouppquota.SoftLimit),
+                   "pykotaHardLimit" : str(grouppquota.HardLimit),
+                   "pykotaDateLimit" : str(grouppquota.DateLimit),
                  }
         self.doModify(grouppquota.ident, fields)
Index: /pykota/trunk/pykota/storage.py
===================================================================
--- /pykota/trunk/pykota/storage.py (revision 2733)
+++ /pykota/trunk/pykota/storage.py (revision 2735)
@@ -266,9 +266,9 @@
     def setLimits(self, softlimit, hardlimit) :    
         """Sets the soft and hard limit for this quota."""
-        self.parent.writeUserPQuotaLimits(self, softlimit, hardlimit)
         self.SoftLimit = softlimit
         self.HardLimit = hardlimit
         self.DateLimit = None
         self.WarnCount = 0
+        self.isDirty = True
         
     def setUsage(self, used) :
@@ -276,21 +276,11 @@
         vused = int(used)
         if used.startswith("+") or used.startswith("-") :
-            self.parent.beginTransaction()
-            try :
-                self.parent.increaseUserPQuotaPagesCounters(self, vused)
-                self.parent.writeUserPQuotaDateLimit(self, None)
-                self.parent.writeUserPQuotaWarnCount(self, 0)
-            except PyKotaStorageError, msg :    
-                self.parent.rollbackTransaction()
-                raise PyKotaStorageError, msg
-            else :
-                self.parent.commitTransaction()
             self.PageCounter += vused
             self.LifePageCounter += vused
         else :
-            self.parent.writeUserPQuotaPagesCounters(self, vused, vused)
             self.PageCounter = self.LifePageCounter = vused
         self.DateLimit = None
         self.WarnCount = 0
+        self.isDirty = 1
 
     def incDenyBannerCounter(self) :
@@ -306,13 +296,13 @@
     def reset(self) :    
         """Resets page counter to 0."""
-        self.parent.writeUserPQuotaPagesCounters(self, 0, int(self.LifePageCounter or 0))
         self.PageCounter = 0
         self.DateLimit = None
+        self.isDirty = True
         
     def hardreset(self) :    
         """Resets actual and life time page counters to 0."""
-        self.parent.writeUserPQuotaPagesCounters(self, 0, 0)
         self.PageCounter = self.LifePageCounter = 0
         self.DateLimit = None
+        self.isDirty = True
         
     def computeJobPrice(self, jobsize) :    
@@ -385,5 +375,5 @@
                 uq = self.parent.getUserPQuota(user, self.Printer)
                 uq.reset()
-            self.parent.writeGroupPQuotaDateLimit(self, None)
+                uq.save()
         except PyKotaStorageError, msg :    
             self.parent.rollbackTransaction()
@@ -393,4 +383,5 @@
         self.PageCounter = 0
         self.DateLimit = None
+        self.isDirty = True
         
     def hardreset(self) :    
@@ -401,5 +392,5 @@
                 uq = self.parent.getUserPQuota(user, self.Printer)
                 uq.hardreset()
-            self.parent.writeGroupPQuotaDateLimit(self, None)
+                uq.save()
         except PyKotaStorageError, msg :    
             self.parent.rollbackTransaction()
@@ -409,4 +400,5 @@
         self.PageCounter = self.LifePageCounter = 0
         self.DateLimit = None
+        self.isDirty = True
         
     def setDateLimit(self, datelimit) :    
@@ -423,8 +415,8 @@
     def setLimits(self, softlimit, hardlimit) :    
         """Sets the soft and hard limit for this quota."""
-        self.parent.writeGroupPQuotaLimits(self, softlimit, hardlimit)
         self.SoftLimit = softlimit
         self.HardLimit = hardlimit
         self.DateLimit = None
+        self.isDirty = True
         
     def delete(self) :    
Index: /pykota/trunk/bin/edpykota
===================================================================
--- /pykota/trunk/bin/edpykota (revision 2731)
+++ /pykota/trunk/bin/edpykota (revision 2735)
@@ -166,8 +166,9 @@
             self.display("%s...\n" % _("Deletion"))
             nbtotal = len(pqentries)
-            for i in range(nbtotal) :
-                (pqkey, pqentry) = pqentries.popitem()
+            i = 0
+            for (pqkey, pqentry) in pqentries.items() :
                 if pqentry.Exists :
                     pqentry.delete()
+                i += 1    
                 percent = 100.0 * float(i) / float(nbtotal)
                 self.display("\r%.02f%%" % percent)
@@ -197,7 +198,7 @@
                             else :
                                 pqentries[pqkey] = newpqentry
+                        i += 1
                         percent = 100.0 * float(i) / float(nbtotal)
                         self.display("\r%.02f%%" % percent)
-                        i += 1
                 self.display("\r100.00%%\r        \r%s\n" % _("Done."))
                 
@@ -220,6 +221,4 @@
             else :
                 self.display("%s...\n" % _("Modification"))
-                raise PyKotaCommandLineError, "Not implemented yet."
-                softlimit = hardlimit = None
                 
                 used = options["used"]
@@ -238,5 +237,7 @@
                         raise PyKotaCommandLineError, _("Invalid increase value %s.") % increase
                 
-                if not options["noquota"] :
+                softlimit = hardlimit = None
+                noquota = options["noquota"]
+                if not noquota :
                     if options["softlimit"] :
                         try :
@@ -257,80 +258,48 @@
                         self.printInfo(_("Hard limit %i is less than soft limit %i, values will be exchanged.") % (hardlimit, softlimit))
                         (softlimit, hardlimit) = (hardlimit, softlimit)
+                    if hardlimit is None :    
+                        hardlimit = softlimit
+                        if hardlimit is not None :
+                            self.printInfo(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer.Name))
+                    if softlimit is None :    
+                        softlimit = hardlimit
+                        if softlimit is not None :
+                            self.printInfo(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer.Name))
                     
-                sys.stdout.write(_("Managing print quotas... (this may take a lot of time)"))
-                sys.stdout.flush()
-                missingusers = {}
-                missinggroups = {}    
-                changed = {} # tracks changes made at the user/group level
-                for printer in printers :
-                    if not options["noquota"] :    
-                        if hardlimit is None :    
-                            hardlimit = softlimit
-                            if hardlimit is not None :
-                                self.printInfo(_("Undefined hard limit set to soft limit (%s) on printer %s.") % (str(hardlimit), printer.Name))
-                        if softlimit is None :    
-                            softlimit = hardlimit
-                            if softlimit is not None :
-                                self.printInfo(_("Undefined soft limit set to hard limit (%s) on printer %s.") % (str(softlimit), printer.Name))
+                nbtotal = len(pqentries)    
+                i = 0
+                for pqentry in pqentries :    
+                    ename = getattr(pqentry, suffix).Name
+                    pname = pqentry.Printer.Name
+                    if pqentry.Exists :     
+                        if noquota or ((softlimit is not None) and (hardlimit is not None)) :
+                            pqentry.setLimits(softlimit, hardlimit)
+                            
+                        if increase :
+                           if (pqentry.SoftLimit is None) \
+                               or (pqentry.HardLimit is None) :
+                               self.printInfo(_("You can't increase limits by %s when no limit is set.") % increase, "error")
+                           else :
+                               newsoft = pqentry.SoftLimit + increase         
+                               newhard = pqentry.HardLimit + increase         
+                               if (newsoft >= 0) and (newhard >= 0) :
+                                   pqentry.setLimits(newsoft, newhard)
+                               else :    
+                                   self.printInfo(_("You can't set negative limits."), "error")
+                        
+                        if options["reset"] :
+                            pqentry.reset()
+                            
+                        if options["hardreset"] :    
+                            pqentry.hardreset()
+                            
+                        if not options["groups"] :
+                            if used :
+                                pqentry.setUsage(used)
                                 
-                    if options["add"] :    
-                        allentries = []    
-                        for name in names :
-                            email = ""
-                            if not options["groups"] :
-                                splitname = name.split('/', 1)     # username/email
-                                if len(splitname) == 1 :
-                                    splitname.append("")
-                                (name, email) = splitname
-                                if email and (email.count('@') != 1) :
-                                    self.printInfo(_("Invalid email address %s") % email)
-                                    email = ""
-                            entry = getattr(self.storage, "get%s" % suffix)(name)
-                            if email and not options["groups"] :
-                                entry.Email = email
-                            entrypquota = getattr(self.storage, "get%sPQuota" % suffix)(entry, printer)
-                            allentries.append((entry, entrypquota))
-                    else :   
-                        allentries = getattr(self.storage, "getPrinter%ssAndQuotas" % suffix)(printer, names)
-                        
-                    for (entry, entrypquota) in allentries :
-                        if not changed.has_key(entry.Name) :
-                            changed[entry.Name] = {}
-                            if not options["groups"] :
-                                changed[entry.Name]["ingroups"] = []
-                                
-                        if entry.Exists and (not entrypquota.Exists) :
-                            # not found
-                            if options["add"] :
-                                entrypquota = getattr(self.storage, "add%sPQuota" % suffix)(entry, printer)
-                                
-                        if not entrypquota.Exists :     
-                            self.printInfo(_("Quota not found for object %s on printer %s.") % (entry.Name, printer.Name))
-                        else :    
-                            if options["noquota"] \
-                               or ((softlimit is not None) and (hardlimit is not None)) :
-                                entrypquota.setLimits(softlimit, hardlimit)
-                                
-                            if increase :
-                               if (entrypquota.SoftLimit is None) \
-                                   or (entrypquota.HardLimit is None) :
-                                   self.printInfo(_("You can't increase limits by %s when no limit is set.") % increase, "error")
-                               else :
-                                   newsoft = entrypquota.SoftLimit + increase         
-                                   newhard = entrypquota.HardLimit + increase         
-                                   if (newsoft >= 0) and (newhard >= 0) :
-                                       entrypquota.setLimits(newsoft, newhard)
-                                   else :    
-                                       self.printInfo(_("You can't set negative limits."), "error")
-                            
-                            if options["reset"] :
-                                entrypquota.reset()
-                                
-                            if options["hardreset"] :    
-                                entrypquota.hardreset()
-                                
-                            if not options["groups"] :
-                                if used :
-                                    entrypquota.setUsage(used)
+                        pqentry.save()        
+                    i += 1            
+                    percent = 100.0 * float(i) / float(nbtotal)
+                    self.display("\r%.02f%%" % percent)
                                 
         if not options["list"] :                
