Changeset 1269

Show
Ignore:
Timestamp:
01/10/04 10:44:02 (20 years ago)
Author:
jalet
Message:

Fixed potential accuracy problem if a user printed on several printers at
the very same time.

Location:
pykota/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/NEWS

    r1258 r1269  
    2222PyKota NEWS : 
    2323 
     24    - 1.16alpha23 : 
     25     
     26        - Fixed concurrent access potential accounting accuracy problem. 
     27         
    2428    - 1.16alpha22 : 
    2529     
  • pykota/trunk/pykota/storage.py

    r1259 r1269  
    2222# 
    2323# $Log$ 
     24# Revision 1.36  2004/01/10 09:44:02  jalet 
     25# Fixed potential accuracy problem if a user printed on several printers at 
     26# the very same time. 
     27# 
    2428# Revision 1.35  2004/01/08 16:33:27  jalet 
    2529# Additionnal check to not create a circular printers group. 
     
    171175    def consumeAccountBalance(self, amount) :      
    172176        """Consumes an amount of money from the user's account balance.""" 
    173         newbalance = float(self.AccountBalance or 0.0) - amount 
    174         self.parent.writeUserAccountBalance(self, newbalance) 
    175         self.AccountBalance = newbalance 
     177        self.parent.decreaseUserAccountBalance(self, amount) 
     178        self.AccountBalance = float(self.AccountBalance or 0.0) - amount 
    176179         
    177180    def setAccountBalance(self, balance, lifetimepaid) :     
     
    250253        if (printer not in self.parent.getParentPrinters(self)) and (printer.ident != self.ident) : 
    251254            self.parent.writePrinterToGroup(self, printer) 
     255            # TODO : reset cached value for printer parents, or add new parent to cached value 
    252256         
    253257    def setPrices(self, priceperpage = None, priceperjob = None) :     
     
    301305                self.User.consumeAccountBalance(jobprice) 
    302306                for upq in [ self ] + self.ParentPrintersUserPQuota : 
    303                     newpagecounter = int(upq.PageCounter or 0) + nbpages 
    304                     newlifepagecounter = int(upq.LifePageCounter or 0) + nbpages 
    305                     self.parent.writeUserPQuotaPagesCounters(upq, newpagecounter, newlifepagecounter) 
    306                     upq.PageCounter = newpagecounter 
    307                     upq.LifePageCounter = newlifepagecounter 
     307                    self.parent.increaseUserPQuotaPagesCounters(upq, nbpages) 
     308                    upq.PageCounter = int(upq.PageCounter or 0) + nbpages 
     309                    upq.LifePageCounter = int(upq.LifePageCounter or 0) + nbpages 
    308310        except PyKotaStorageError, msg :     
    309311            self.parent.rollbackTransaction() 
  • pykota/trunk/pykota/storages/ldapstorage.py

    r1259 r1269  
    2222# 
    2323# $Log$ 
     24# Revision 1.47  2004/01/10 09:44:02  jalet 
     25# Fixed potential accuracy problem if a user printed on several printers at 
     26# the very same time. 
     27# 
    2428# Revision 1.46  2004/01/08 16:33:27  jalet 
    2529# Additionnal check to not create a circular printers group. 
     
    285289    def doModify(self, dn, fields, ignoreold=1) : 
    286290        """Modifies an entry in the LDAP directory.""" 
    287         fields = self.normalizeFields(fields) 
    288291        try : 
    289292            oldentry = self.doSearch("objectClass=*", base=dn, scope=ldap.SCOPE_BASE) 
     293            for (k, v) in fields.items() : 
     294                if type(v) == type({}) : 
     295                    try : 
     296                        oldvalue = v["convert"](oldentry[0][1].get(k, [0])[0]) 
     297                    except ValueError :     
     298                        self.tool.logdebug("Error converting %s with %s(%s)" % (oldentry[0][1].get(k), k, v)) 
     299                        oldvalue = 0 
     300                    if v["operator"] == '+' : 
     301                        newvalue = oldvalue + v["value"] 
     302                    else :     
     303                        newvalue = oldvalue - v["value"] 
     304                    fields[k] = str(newvalue) 
     305            fields = self.normalizeFields(fields) 
    290306            self.tool.logdebug("QUERY : Modify(%s, %s ==> %s)" % (dn, oldentry[0][1], fields)) 
    291307            self.database.modify_s(dn, modlist.modifyModlist(oldentry[0][1], fields, ignore_oldexistent=ignoreold)) 
     
    735751        return self.doModify(grouppquota.ident, fields) 
    736752         
     753    def increaseUserPQuotaPagesCounters(self, userpquota, nbpages) :     
     754        """Increase page counters for a user print quota.""" 
     755        fields = { 
     756                   "pykotaPageCounter" : { "operator" : "+", "value" : nbpages, "convert" : int }, 
     757                   "pykotaLifePageCounter" : { "operator" : "+", "value" : nbpages, "convert" : int }, 
     758                 } 
     759        return self.doModify(userpquota.ident, fields)          
     760         
    737761    def writeUserPQuotaPagesCounters(self, userpquota, newpagecounter, newlifepagecounter) :     
    738762        """Sets the new page counters permanently for a user print quota.""" 
     
    742766                 }   
    743767        return self.doModify(userpquota.ident, fields)          
     768        
     769    def decreaseUserAccountBalance(self, user, amount) :     
     770        """Decreases user's account balance from an amount.""" 
     771        fields = { 
     772                   "pykotaBalance" : { "operator" : "-", "value" : amount, "convert" : float }, 
     773                 } 
     774        return self.doModify(user.idbalance, fields)          
    744775        
    745776    def writeUserAccountBalance(self, user, newbalance, newlifetimepaid=None) :     
     
    825856        """Puts a printer into a printer group.""" 
    826857        if printer.ident not in pgroup.uniqueMember : 
     858            pgroup.uniqueMember.append(printer.ident) 
    827859            fields = { 
    828                        "uniqueMember" : pgroup.uniqueMember + [printer.ident] 
     860                       "uniqueMember" : pgroup.uniqueMember 
    829861                     }   
    830862            self.doModify(pgroup.ident, fields)          
  • pykota/trunk/pykota/storages/pgstorage.py

    r1259 r1269  
    2222# 
    2323# $Log$ 
     24# Revision 1.31  2004/01/10 09:44:02  jalet 
     25# Fixed potential accuracy problem if a user printed on several printers at 
     26# the very same time. 
     27# 
    2428# Revision 1.30  2004/01/08 16:33:27  jalet 
    2529# Additionnal check to not create a circular printers group. 
     
    213217        """Extracts all user names.""" 
    214218        usernames = [] 
    215         result = self.doSearch("SELECT username FROM users;") 
     219        result = self.doSearch("SELECT username FROM users") 
    216220        if result : 
    217221            usernames = [record["username"] for record in result] 
     
    221225        """Extracts all group names.""" 
    222226        groupnames = [] 
    223         result = self.doSearch("SELECT groupname FROM groups;") 
     227        result = self.doSearch("SELECT groupname FROM groups") 
    224228        if result : 
    225229            groupnames = [record["groupname"] for record in result] 
     
    354358        """Get all the printer groups this printer is a member of.""" 
    355359        pgroups = [] 
    356         result = self.doSearch("SELECT groupid,printername FROM printergroupsmembers JOIN printers ON groupid=id WHERE printerid=%s;" % self.doQuote(printer.ident)) 
     360        result = self.doSearch("SELECT groupid,printername FROM printergroupsmembers JOIN printers ON groupid=id WHERE printerid=%s" % self.doQuote(printer.ident)) 
    357361        if result : 
    358362            for record in result : 
     
    477481        self.doModify("UPDATE grouppquota SET datelimit=%s WHERE id=%s" % (self.doQuote(datelimit), self.doQuote(grouppquota.ident))) 
    478482         
     483    def increaseUserPQuotaPagesCounters(self, userpquota, nbpages) :     
     484        """Increase page counters for a user print quota.""" 
     485        self.doModify("UPDATE userpquota SET pagecounter=pagecounter+%s,lifepagecounter=lifepagecounter+%s WHERE id=%s" % (self.doQuote(nbpages), self.doQuote(nbpages), self.doQuote(userpquota.ident))) 
     486        
    479487    def writeUserPQuotaPagesCounters(self, userpquota, newpagecounter, newlifepagecounter) :     
    480        """Sets the new page counters permanently for a user print quota.""" 
    481        self.doModify("UPDATE userpquota SET pagecounter=%s,lifepagecounter=%s WHERE id=%s" % (self.doQuote(newpagecounter), self.doQuote(newlifepagecounter), self.doQuote(userpquota.ident))) 
     488        """Sets the new page counters permanently for a user print quota.""" 
     489        self.doModify("UPDATE userpquota SET pagecounter=%s,lifepagecounter=%s WHERE id=%s" % (self.doQuote(newpagecounter), self.doQuote(newlifepagecounter), self.doQuote(userpquota.ident))) 
     490        
     491    def decreaseUserAccountBalance(self, user, amount) :     
     492        """Decreases user's account balance from an amount.""" 
     493        self.doModify("UPDATE users SET balance=balance-%s WHERE id=%s" % (self.doQuote(amount), self.doQuote(user.ident))) 
    482494        
    483495    def writeUserAccountBalance(self, user, newbalance, newlifetimepaid=None) :     
    484        """Sets the new account balance and eventually new lifetime paid.""" 
    485        if newlifetimepaid is not None : 
    486            self.doModify("UPDATE users SET balance=%s, lifetimepaid=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(newlifetimepaid), self.doQuote(user.ident))) 
    487        else :     
    488            self.doModify("UPDATE users SET balance=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(user.ident))) 
     496        """Sets the new account balance and eventually new lifetime paid.""" 
     497        if newlifetimepaid is not None : 
     498            self.doModify("UPDATE users SET balance=%s, lifetimepaid=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(newlifetimepaid), self.doQuote(user.ident))) 
     499        else :     
     500            self.doModify("UPDATE users SET balance=%s WHERE id=%s" % (self.doQuote(newbalance), self.doQuote(user.ident))) 
    489501             
    490502    def writeLastJobSize(self, lastjob, jobsize, jobprice) :         
     
    501513        else :         
    502514            # here we explicitly want to reset jobsize to NULL if needed 
    503             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))) 
     515            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))) 
    504516             
    505517    def writeUserPQuotaLimits(self, userpquota, softlimit, hardlimit) : 
     
    514526        """Puts a printer into a printer group.""" 
    515527        children = [] 
    516         result = self.doSearch("SELECT printerid FROM printergroupsmembers WHERE groupid=%s;" % self.doQuote(pgroup.ident)) 
     528        result = self.doSearch("SELECT printerid FROM printergroupsmembers WHERE groupid=%s" % self.doQuote(pgroup.ident)) 
    517529        if result : 
    518530            for record in result : 
    519531                children.append(record.get("printerid")) # TODO : put this into the database integrity rules 
    520532        if printer.ident not in children :         
    521             self.doModify("INSERT INTO printergroupsmembers (groupid, printerid) VALUES (%s, %s);" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident))) 
     533            self.doModify("INSERT INTO printergroupsmembers (groupid, printerid) VALUES (%s, %s)" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident))) 
    522534         
    523535    def deleteUser(self, user) :     
  • pykota/trunk/pykota/version.py

    r1258 r1269  
    2222# 
    2323 
    24 __version__ = "1.16alpha22_unofficial" 
     24__version__ = "1.16alpha23_unofficial" 
    2525 
    2626__doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""