Changeset 3413 for pykota/trunk/pykota/storages/sql.py
- Timestamp:
- 09/27/08 22:02:37 (16 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pykota/trunk/pykota/storages/sql.py
r3411 r3413 8 8 # the Free Software Foundation, either version 3 of the License, or 9 9 # (at your option) any later version. 10 # 10 # 11 11 # This program is distributed in the hope that it will be useful, 12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 # GNU General Public License for more details. 15 # 15 # 16 16 # You should have received a copy of the GNU General Public License 17 17 # along with this program. If not, see <http://www.gnu.org/licenses/>. … … 26 26 StorageJob, StorageLastJob, StorageUserPQuota, \ 27 27 StorageGroupPQuota, StorageBillingCode 28 29 from pykota.utils import * 28 29 from pykota.utils import * 30 30 31 31 class SQLStorage : … … 42 42 user.Exists = True 43 43 return user 44 44 45 45 def storageGroupFromRecord(self, groupname, record) : 46 46 """Returns a StorageGroup instance from a database record.""" … … 53 53 group.Exists = True 54 54 return group 55 55 56 56 def storagePrinterFromRecord(self, printername, record) : 57 57 """Returns a StoragePrinter instance from a database record.""" … … 69 69 printer.Exists = True 70 70 return printer 71 72 def setJobAttributesFromRecord(self, job, record) : 71 72 def setJobAttributesFromRecord(self, job, record) : 73 73 """Sets the attributes of a job from a database record.""" 74 74 job.ident = record.get("id") … … 78 78 job.JobPrice = record.get("jobprice") 79 79 job.JobAction = record.get("action") 80 job.JobFileName = databaseToUnicode(record.get("filename") or "") 81 job.JobTitle = databaseToUnicode(record.get("title") or "") 80 job.JobFileName = databaseToUnicode(record.get("filename") or "") 81 job.JobTitle = databaseToUnicode(record.get("title") or "") 82 82 job.JobCopies = record.get("copies") 83 job.JobOptions = databaseToUnicode(record.get("options") or "") 83 job.JobOptions = databaseToUnicode(record.get("options") or "") 84 84 job.JobDate = record.get("jobdate") 85 85 job.JobHostName = record.get("hostname") … … 95 95 (job.JobTitle, job.JobFileName, job.JobOptions) = (_("Hidden because of privacy concerns"),) * 3 96 96 job.Exists = True 97 97 98 98 def storageJobFromRecord(self, record) : 99 99 """Returns a StorageJob instance from a database record.""" … … 101 101 self.setJobAttributesFromRecord(job, record) 102 102 return job 103 103 104 104 def storageLastJobFromRecord(self, printer, record) : 105 105 """Returns a StorageLastJob instance from a database record.""" … … 107 107 self.setJobAttributesFromRecord(lastjob, record) 108 108 return lastjob 109 109 110 110 def storageUserPQuotaFromRecord(self, user, printer, record) : 111 111 """Returns a StorageUserPQuota instance from a database record.""" … … 120 120 userpquota.Exists = True 121 121 return userpquota 122 122 123 123 def storageGroupPQuotaFromRecord(self, group, printer, record) : 124 124 """Returns a StorageGroupPQuota instance from a database record.""" … … 135 135 grouppquota.Exists = True 136 136 return grouppquota 137 137 138 138 def storageBillingCodeFromRecord(self, billingcode, record) : 139 139 """Returns a StorageBillingCode instance from a database record.""" … … 145 145 code.Exists = True 146 146 return code 147 148 def createFilter(self, only) : 147 148 def createFilter(self, only) : 149 149 """Returns the appropriate SQL filter.""" 150 150 if only : … … 152 152 for (k, v) in only.items() : 153 153 expressions.append("%s=%s" % (k, self.doQuote(unicodeToDatabase(v)))) 154 return " AND ".join(expressions) 155 return "" 156 157 def createOrderBy(self, default, ordering) : 154 return " AND ".join(expressions) 155 return "" 156 157 def createOrderBy(self, default, ordering) : 158 158 """Creates a suitable ORDER BY statement based on a list of fieldnames prefixed with '+' (ASC) or '-' (DESC).""" 159 159 statements = [] 160 160 if not ordering : 161 161 ordering = default 162 for field in ordering : 163 if field.startswith("-") : 162 for field in ordering : 163 if field.startswith("-") : 164 164 statements.append("%s DESC" % field[1:]) 165 165 elif field.startswith("+") : 166 166 statements.append("%s ASC" % field[1:]) 167 else : 167 else : 168 168 statements.append("%s ASC" % field) 169 return ", ".join(statements) 170 169 return ", ".join(statements) 170 171 171 def extractPrinters(self, extractonly={}, ordering=[]) : 172 172 """Extracts all printer records.""" … … 177 177 result = self.doRawSearch("SELECT * FROM printers %(thefilter)s ORDER BY %(orderby)s" % locals()) 178 178 return self.prepareRawResult(result) 179 179 180 180 def extractUsers(self, extractonly={}, ordering=[]) : 181 181 """Extracts all user records.""" … … 186 186 result = self.doRawSearch("SELECT * FROM users %(thefilter)s ORDER BY %(orderby)s" % locals()) 187 187 return self.prepareRawResult(result) 188 188 189 189 def extractBillingcodes(self, extractonly={}, ordering=[]) : 190 190 """Extracts all billing codes records.""" … … 195 195 result = self.doRawSearch("SELECT * FROM billingcodes %(thefilter)s ORDER BY %(orderby)s" % locals()) 196 196 return self.prepareRawResult(result) 197 197 198 198 def extractGroups(self, extractonly={}, ordering=[]) : 199 199 """Extracts all group records.""" … … 204 204 result = self.doRawSearch("SELECT groups.*,COALESCE(SUM(balance), 0) AS balance, COALESCE(SUM(lifetimepaid), 0) as lifetimepaid FROM groups LEFT OUTER JOIN users ON users.id IN (SELECT userid FROM groupsmembers WHERE groupid=groups.id) %(thefilter)s GROUP BY groups.id,groups.groupname,groups.limitby,groups.description ORDER BY %(orderby)s" % locals()) 205 205 return self.prepareRawResult(result) 206 206 207 207 def extractPayments(self, extractonly={}, ordering=[]) : 208 208 """Extracts all payment records.""" … … 212 212 try : 213 213 del extractonly[limit] 214 except KeyError : 214 except KeyError : 215 215 pass 216 216 thefilter = self.createFilter(extractonly) … … 218 218 thefilter = "AND %s" % thefilter 219 219 (startdate, enddate) = self.cleanDates(startdate, enddate) 220 if startdate : 220 if startdate : 221 221 thefilter = "%s AND date>=%s" % (thefilter, self.doQuote(startdate)) 222 if enddate : 222 if enddate : 223 223 thefilter = "%s AND date<=%s" % (thefilter, self.doQuote(enddate)) 224 224 orderby = self.createOrderBy(["+payments.id"], ordering) 225 225 result = self.doRawSearch("SELECT username,payments.* FROM users,payments WHERE users.id=payments.userid %(thefilter)s ORDER BY %(orderby)s" % locals()) 226 226 return self.prepareRawResult(result) 227 227 228 228 def extractUpquotas(self, extractonly={}, ordering=[]) : 229 229 """Extracts all userpquota records.""" … … 234 234 result = self.doRawSearch("SELECT users.username,printers.printername,userpquota.* FROM users,printers,userpquota WHERE users.id=userpquota.userid AND printers.id=userpquota.printerid %(thefilter)s ORDER BY %(orderby)s" % locals()) 235 235 return self.prepareRawResult(result) 236 236 237 237 def extractGpquotas(self, extractonly={}, ordering=[]) : 238 238 """Extracts all grouppquota records.""" … … 243 243 result = self.doRawSearch("SELECT groups.groupname,printers.printername,grouppquota.*,coalesce(sum(pagecounter), 0) AS pagecounter,coalesce(sum(lifepagecounter), 0) AS lifepagecounter FROM groups,printers,grouppquota,userpquota WHERE groups.id=grouppquota.groupid AND printers.id=grouppquota.printerid AND userpquota.printerid=grouppquota.printerid AND userpquota.userid IN (SELECT userid FROM groupsmembers WHERE groupsmembers.groupid=grouppquota.groupid) %(thefilter)s GROUP BY grouppquota.id,grouppquota.groupid,grouppquota.printerid,grouppquota.softlimit,grouppquota.hardlimit,grouppquota.datelimit,grouppquota.maxjobsize,groups.groupname,printers.printername ORDER BY %(orderby)s" % locals()) 244 244 return self.prepareRawResult(result) 245 245 246 246 def extractUmembers(self, extractonly={}, ordering=[]) : 247 247 """Extracts all user groups members.""" … … 252 252 result = self.doRawSearch("SELECT groups.groupname, users.username, groupsmembers.* FROM groups,users,groupsmembers WHERE users.id=groupsmembers.userid AND groups.id=groupsmembers.groupid %(thefilter)s ORDER BY %(orderby)s" % locals()) 253 253 return self.prepareRawResult(result) 254 254 255 255 def extractPmembers(self, extractonly={}, ordering=[]) : 256 256 """Extracts all printer groups members.""" … … 268 268 result = self.doRawSearch("SELECT p1.printername as pgroupname, p2.printername as printername, printergroupsmembers.* FROM printers p1, printers p2, printergroupsmembers WHERE p1.id=printergroupsmembers.groupid AND p2.id=printergroupsmembers.printerid %(thefilter)s ORDER BY %(orderby)s" % locals()) 269 269 return self.prepareRawResult(result) 270 270 271 271 def extractHistory(self, extractonly={}, ordering=[]) : 272 272 """Extracts all jobhistory records.""" … … 276 276 try : 277 277 del extractonly[limit] 278 except KeyError : 278 except KeyError : 279 279 pass 280 280 thefilter = self.createFilter(extractonly) … … 282 282 thefilter = "AND %s" % thefilter 283 283 (startdate, enddate) = self.cleanDates(startdate, enddate) 284 if startdate : 284 if startdate : 285 285 thefilter = "%s AND jobdate>=%s" % (thefilter, self.doQuote(startdate)) 286 if enddate : 286 if enddate : 287 287 thefilter = "%s AND jobdate<=%s" % (thefilter, self.doQuote(enddate)) 288 288 orderby = self.createOrderBy(["+jobhistory.id"], ordering) 289 289 result = self.doRawSearch("SELECT users.username,printers.printername,jobhistory.* FROM users,printers,jobhistory WHERE users.id=jobhistory.userid AND printers.id=jobhistory.printerid %(thefilter)s ORDER BY %(orderby)s" % locals()) 290 290 return self.prepareRawResult(result) 291 291 292 292 def filterNames(self, records, attribute, patterns=None) : 293 293 """Returns a list of 'attribute' from a list of records. 294 294 295 295 Logs any missing attribute. 296 """ 296 """ 297 297 result = [] 298 298 for record in records : … … 307 307 if self.tool.matchString(attrval, patterns) : 308 308 result.append(attrval) 309 else : 309 else : 310 310 result.append(attrval) 311 return result 312 313 def getAllBillingCodes(self, billingcode=None) : 311 return result 312 313 def getAllBillingCodes(self, billingcode=None) : 314 314 """Extracts all billing codes or only the billing codes matching the optional parameter.""" 315 315 result = self.doSearch("SELECT billingcode FROM billingcodes") 316 316 if result : 317 317 return self.filterNames(result, "billingcode", billingcode) 318 else : 318 else : 319 319 return [] 320 321 def getAllPrintersNames(self, printername=None) : 320 321 def getAllPrintersNames(self, printername=None) : 322 322 """Extracts all printer names or only the printers' names matching the optional parameter.""" 323 323 result = self.doSearch("SELECT printername FROM printers") 324 324 if result : 325 325 return self.filterNames(result, "printername", printername) 326 else : 326 else : 327 327 return [] 328 329 def getAllUsersNames(self, username=None) : 328 329 def getAllUsersNames(self, username=None) : 330 330 """Extracts all user names.""" 331 331 result = self.doSearch("SELECT username FROM users") 332 332 if result : 333 333 return self.filterNames(result, "username", username) 334 else : 334 else : 335 335 return [] 336 337 def getAllGroupsNames(self, groupname=None) : 336 337 def getAllGroupsNames(self, groupname=None) : 338 338 """Extracts all group names.""" 339 339 result = self.doSearch("SELECT groupname FROM groups") … … 342 342 else : 343 343 return [] 344 344 345 345 def getUserNbJobsFromHistory(self, user) : 346 346 """Returns the number of jobs the user has in history.""" … … 349 349 return result[0]["count"] 350 350 return 0 351 352 def getUserFromBackend(self, username) : 351 352 def getUserFromBackend(self, username) : 353 353 """Extracts user information given its name.""" 354 354 result = self.doSearch("SELECT * FROM users WHERE username=%s"\ … … 356 356 if result : 357 357 return self.storageUserFromRecord(username, result[0]) 358 else : 358 else : 359 359 return StorageUser(self, username) 360 361 def getGroupFromBackend(self, groupname) : 360 361 def getGroupFromBackend(self, groupname) : 362 362 """Extracts group information given its name.""" 363 363 result = self.doSearch("SELECT groups.*,COALESCE(SUM(balance), 0.0) AS balance, COALESCE(SUM(lifetimepaid), 0.0) AS lifetimepaid FROM groups LEFT OUTER JOIN users ON users.id IN (SELECT userid FROM groupsmembers WHERE groupid=groups.id) WHERE groupname=%s GROUP BY groups.id,groups.groupname,groups.limitby,groups.description" \ … … 365 365 if result : 366 366 return self.storageGroupFromRecord(groupname, result[0]) 367 else : 367 else : 368 368 return StorageGroup(self, groupname) 369 370 def getPrinterFromBackend(self, printername) : 369 370 def getPrinterFromBackend(self, printername) : 371 371 """Extracts printer information given its name.""" 372 372 result = self.doSearch("SELECT * FROM printers WHERE printername=%s" \ … … 374 374 if result : 375 375 return self.storagePrinterFromRecord(printername, result[0]) 376 else : 376 else : 377 377 return StoragePrinter(self, printername) 378 379 def getBillingCodeFromBackend(self, label) : 378 379 def getBillingCodeFromBackend(self, label) : 380 380 """Extracts a billing code information given its name.""" 381 381 result = self.doSearch("SELECT * FROM billingcodes WHERE billingcode=%s" \ … … 383 383 if result : 384 384 return self.storageBillingCodeFromRecord(label, result[0]) 385 else : 385 else : 386 386 return StorageBillingCode(self, label) 387 388 def getUserPQuotaFromBackend(self, user, printer) : 387 388 def getUserPQuotaFromBackend(self, user, printer) : 389 389 """Extracts a user print quota.""" 390 390 if printer.Exists and user.Exists : … … 394 394 return self.storageUserPQuotaFromRecord(user, printer, result[0]) 395 395 return StorageUserPQuota(self, user, printer) 396 397 def getGroupPQuotaFromBackend(self, group, printer) : 396 397 def getGroupPQuotaFromBackend(self, group, printer) : 398 398 """Extracts a group print quota.""" 399 399 if printer.Exists and group.Exists : … … 403 403 return self.storageGroupPQuotaFromRecord(group, printer, result[0]) 404 404 return StorageGroupPQuota(self, group, printer) 405 406 def getPrinterLastJobFromBackend(self, printer) : 405 406 def getPrinterLastJobFromBackend(self, printer) : 407 407 """Extracts a printer's last job information.""" 408 408 result = self.doSearch("SELECT jobhistory.id, jobid, userid, username, pagecounter, jobsize, jobprice, filename, title, copies, options, hostname, jobdate, md5sum, pages, billingcode, precomputedjobsize, precomputedjobprice FROM jobhistory, users WHERE userid=users.id AND jobhistory.id IN (SELECT max(id) FROM jobhistory WHERE printerid=%s)" % self.doQuote(printer.ident)) 409 409 if result : 410 410 return self.storageLastJobFromRecord(printer, result[0]) 411 else : 411 else : 412 412 return StorageLastJob(self, printer) 413 414 def getGroupMembersFromBackend(self, group) : 413 414 def getGroupMembersFromBackend(self, group) : 415 415 """Returns the group's members list.""" 416 416 groupmembers = [] … … 422 422 groupmembers.append(user) 423 423 self.cacheEntry("USERS", user.Name, user) 424 return groupmembers 425 426 def getUserGroupsFromBackend(self, user) : 424 return groupmembers 425 426 def getUserGroupsFromBackend(self, user) : 427 427 """Returns the user's groups list.""" 428 428 groups = [] … … 431 431 for record in result : 432 432 groups.append(self.getGroup(databaseToUnicode(record.get("groupname")))) 433 return groups 434 435 def getParentPrintersFromBackend(self, printer) : 433 return groups 434 435 def getParentPrintersFromBackend(self, printer) : 436 436 """Get all the printer groups this printer is a member of.""" 437 437 pgroups = [] … … 444 444 pgroups.append(parentprinter) 445 445 return pgroups 446 446 447 447 def getMatchingPrinters(self, printerpattern) : 448 448 """Returns the list of all printers for which name matches a certain pattern.""" … … 456 456 try : 457 457 patdict = {}.fromkeys(patterns) 458 except AttributeError : 458 except AttributeError : 459 459 # Python v2.2 or earlier 460 460 patdict = {} … … 467 467 printers.append(printer) 468 468 self.cacheEntry("PRINTERS", printer.Name, printer) 469 return printers 470 469 return printers 470 471 471 def getMatchingUsers(self, userpattern) : 472 472 """Returns the list of all users for which name matches a certain pattern.""" … … 480 480 try : 481 481 patdict = {}.fromkeys(patterns) 482 except AttributeError : 482 except AttributeError : 483 483 # Python v2.2 or earlier 484 484 patdict = {} … … 491 491 users.append(user) 492 492 self.cacheEntry("USERS", user.Name, user) 493 return users 494 493 return users 494 495 495 def getMatchingGroups(self, grouppattern) : 496 496 """Returns the list of all groups for which name matches a certain pattern.""" … … 504 504 try : 505 505 patdict = {}.fromkeys(patterns) 506 except AttributeError : 506 except AttributeError : 507 507 # Python v2.2 or earlier 508 508 patdict = {} … … 515 515 groups.append(group) 516 516 self.cacheEntry("GROUPS", group.Name, group) 517 return groups 518 517 return groups 518 519 519 def getMatchingBillingCodes(self, billingcodepattern) : 520 520 """Returns the list of all billing codes for which the label matches a certain pattern.""" … … 525 525 try : 526 526 patdict = {}.fromkeys(patterns) 527 except AttributeError : 527 except AttributeError : 528 528 # Python v2.2 or earlier 529 529 patdict = {} … … 536 536 codes.append(code) 537 537 self.cacheEntry("BILLINGCODES", code.BillingCode, code) 538 return codes 539 540 def getPrinterUsersAndQuotas(self, printer, names=["*"]) : 538 return codes 539 540 def getPrinterUsersAndQuotas(self, printer, names=["*"]) : 541 541 """Returns the list of users who uses a given printer, along with their quotas.""" 542 542 usersandquotas = [] … … 552 552 self.cacheEntry("USERPQUOTAS", "%s@%s" % (user.Name, printer.Name), userpquota) 553 553 return usersandquotas 554 555 def getPrinterGroupsAndQuotas(self, printer, names=["*"]) : 554 555 def getPrinterGroupsAndQuotas(self, printer, names=["*"]) : 556 556 """Returns the list of groups which uses a given printer, along with their quotas.""" 557 557 groupsandquotas = [] … … 565 565 groupsandquotas.append((group, grouppquota)) 566 566 return groupsandquotas 567 568 def addPrinter(self, printer) : 567 568 def addPrinter(self, printer) : 569 569 """Adds a printer to the quota storage, returns the old value if it already exists.""" 570 570 oldentry = self.getPrinter(printer.Name) … … 580 580 printer.isDirty = False 581 581 return None # the entry created doesn't need further modification 582 582 583 583 def addBillingCode(self, bcode) : 584 584 """Adds a billing code to the quota storage, returns the old value if it already exists.""" … … 587 587 return oldentry 588 588 self.doModify("INSERT INTO billingcodes (billingcode, balance, pagecounter, description) VALUES (%s, %s, %s, %s)" \ 589 % (self.doQuote(unicodeToDatabase(bcode.BillingCode)), 589 % (self.doQuote(unicodeToDatabase(bcode.BillingCode)), 590 590 self.doQuote(bcode.Balance or 0.0), \ 591 591 self.doQuote(bcode.PageCounter or 0), \ … … 593 593 bcode.isDirty = False 594 594 return None # the entry created doesn't need further modification 595 596 def addUser(self, user) : 595 596 def addUser(self, user) : 597 597 """Adds a user to the quota storage, returns the old value if it already exists.""" 598 598 oldentry = self.getUser(user.Name) … … 613 613 user.isDirty = False 614 614 return None # the entry created doesn't need further modification 615 616 def addGroup(self, group) : 615 616 def addGroup(self, group) : 617 617 """Adds a group to the quota storage, returns the old value if it already exists.""" 618 618 oldentry = self.getGroup(group.Name) … … 626 626 return None # the entry created doesn't need further modification 627 627 628 def addUserToGroup(self, user, group) : 628 def addUserToGroup(self, user, group) : 629 629 """Adds an user to a group.""" 630 630 result = self.doSearch("SELECT COUNT(*) AS mexists FROM groupsmembers WHERE groupid=%s AND userid=%s" % (self.doQuote(group.ident), self.doQuote(user.ident))) 631 631 try : 632 632 mexists = int(result[0].get("mexists")) 633 except (IndexError, TypeError) : 633 except (IndexError, TypeError) : 634 634 mexists = 0 635 if not mexists : 635 if not mexists : 636 636 self.doModify("INSERT INTO groupsmembers (groupid, userid) VALUES (%s, %s)" % (self.doQuote(group.ident), self.doQuote(user.ident))) 637 638 def delUserFromGroup(self, user, group) : 637 638 def delUserFromGroup(self, user, group) : 639 639 """Removes an user from a group.""" 640 640 self.doModify("DELETE FROM groupsmembers WHERE groupid=%s AND userid=%s" % \ 641 641 (self.doQuote(group.ident), self.doQuote(user.ident))) 642 642 643 643 def addUserPQuota(self, upq) : 644 644 """Initializes a user print quota on a printer.""" … … 658 658 upq.isDirty = False 659 659 return None # the entry created doesn't need further modification 660 660 661 661 def addGroupPQuota(self, gpq) : 662 662 """Initializes a group print quota on a printer.""" … … 673 673 gpq.isDirty = False 674 674 return None # the entry created doesn't need further modification 675 676 def savePrinter(self, printer) : 675 676 def savePrinter(self, printer) : 677 677 """Saves the printer to the database in a single operation.""" 678 678 self.doModify("UPDATE printers SET passthrough=%s, maxjobsize=%s, description=%s, priceperpage=%s, priceperjob=%s WHERE id=%s" \ … … 683 683 self.doQuote(printer.PricePerJob or 0.0), \ 684 684 self.doQuote(printer.ident))) 685 686 def saveUser(self, user) : 685 686 def saveUser(self, user) : 687 687 """Saves the user to the database in a single operation.""" 688 688 self.doModify("UPDATE users SET limitby=%s, balance=%s, lifetimepaid=%s, email=%s, overcharge=%s, description=%s WHERE id=%s" \ … … 694 694 self.doQuote(unicodeToDatabase(user.Description)), \ 695 695 self.doQuote(user.ident))) 696 697 def saveGroup(self, group) : 696 697 def saveGroup(self, group) : 698 698 """Saves the group to the database in a single operation.""" 699 699 self.doModify("UPDATE groups SET limitby=%s, description=%s WHERE id=%s" \ … … 701 701 self.doQuote(unicodeToDatabase(group.Description)), \ 702 702 self.doQuote(group.ident))) 703 704 def writeUserPQuotaDateLimit(self, userpquota, datelimit) : 703 704 def writeUserPQuotaDateLimit(self, userpquota, datelimit) : 705 705 """Sets the date limit permanently for a user print quota.""" 706 706 self.doModify("UPDATE userpquota SET datelimit=%s WHERE id=%s" % (self.doQuote(datelimit), self.doQuote(userpquota.ident))) 707 708 def writeGroupPQuotaDateLimit(self, grouppquota, datelimit) : 707 708 def writeGroupPQuotaDateLimit(self, grouppquota, datelimit) : 709 709 """Sets the date limit permanently for a group print quota.""" 710 710 self.doModify("UPDATE grouppquota SET datelimit=%s WHERE id=%s" % (self.doQuote(datelimit), self.doQuote(grouppquota.ident))) 711 712 def increaseUserPQuotaPagesCounters(self, userpquota, nbpages) : 711 712 def increaseUserPQuotaPagesCounters(self, userpquota, nbpages) : 713 713 """Increase page counters for a user print quota.""" 714 714 self.doModify("UPDATE userpquota SET pagecounter=pagecounter + %s,lifepagecounter=lifepagecounter + %s WHERE id=%s" % (self.doQuote(nbpages), self.doQuote(nbpages), self.doQuote(userpquota.ident))) 715 716 def saveBillingCode(self, bcode) : 715 716 def saveBillingCode(self, bcode) : 717 717 """Saves the billing code to the database.""" 718 718 self.doModify("UPDATE billingcodes SET balance=%s, pagecounter=%s, description=%s WHERE id=%s" \ … … 721 721 self.doQuote(unicodeToDatabase(bcode.Description)), \ 722 722 self.doQuote(bcode.ident))) 723 723 724 724 def consumeBillingCode(self, bcode, pagecounter, balance) : 725 725 """Consumes from a billing code.""" 726 726 self.doModify("UPDATE billingcodes SET balance=balance + %s, pagecounter=pagecounter + %s WHERE id=%s" % (self.doQuote(balance), self.doQuote(pagecounter), self.doQuote(bcode.ident))) 727 728 def refundJob(self, jobident) : 727 728 def refundJob(self, jobident) : 729 729 """Marks a job as refunded in the history.""" 730 730 self.doModify("UPDATE jobhistory SET action='REFUND' WHERE id=%s;" % self.doQuote(jobident)) 731 732 def decreaseUserAccountBalance(self, user, amount) : 731 732 def decreaseUserAccountBalance(self, user, amount) : 733 733 """Decreases user's account balance from an amount.""" 734 734 self.doModify("UPDATE users SET balance=balance - %s WHERE id=%s" % (self.doQuote(amount), self.doQuote(user.ident))) 735 735 736 736 def writeNewPayment(self, user, amount, comment="") : 737 737 """Adds a new payment to the payments history.""" 738 738 if user.ident is not None : 739 739 self.doModify("INSERT INTO payments (userid, amount, description) VALUES (%s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(amount), self.doQuote(unicodeToDatabase(comment)))) 740 else : 740 else : 741 741 self.doModify("INSERT INTO payments (userid, amount, description) VALUES ((SELECT id FROM users WHERE username=%s), %s, %s)" % (self.doQuote(unicodeToDatabase(user.Name)), self.doQuote(amount), self.doQuote(unicodeToDatabase(comment)))) 742 743 def writeLastJobSize(self, lastjob, jobsize, jobprice) : 742 743 def writeLastJobSize(self, lastjob, jobsize, jobprice) : 744 744 """Sets the last job's size permanently.""" 745 745 self.doModify("UPDATE jobhistory SET jobsize=%s, jobprice=%s WHERE id=%s" % (self.doQuote(jobsize), self.doQuote(jobprice), self.doQuote(lastjob.ident))) 746 746 747 747 def writeJobNew(self, printer, user, jobid, pagecounter, action, jobsize=None, jobprice=None, filename=None, title=None, copies=None, options=None, clienthost=None, jobsizebytes=None, jobmd5sum=None, jobpages=None, jobbilling=None, precomputedsize=None, precomputedprice=None) : 748 748 """Adds a job in a printer's history.""" 749 if self.privacy : 749 if self.privacy : 750 750 # For legal reasons, we want to hide the title, filename and options 751 751 title = filename = options = "hidden" … … 757 757 if jobsize is not None : 758 758 self.doModify("INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, jobsize, jobprice, filename, title, copies, options, hostname, jobsizebytes, md5sum, pages, billingcode, precomputedjobsize, precomputedjobprice) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(printer.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))) 759 else : 759 else : 760 760 self.doModify("INSERT INTO jobhistory (userid, printerid, jobid, pagecounter, action, filename, title, copies, options, hostname, jobsizebytes, md5sum, pages, billingcode, precomputedjobsize, precomputedjobprice) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.doQuote(user.ident), self.doQuote(printer.ident), self.doQuote(jobid), self.doQuote(pagecounter), self.doQuote(action), 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))) 761 else : 761 else : 762 762 # here we explicitly want to reset jobsize to NULL if needed 763 763 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))) 764 764 765 765 def saveUserPQuota(self, userpquota) : 766 766 """Saves an user print quota entry.""" … … 774 774 self.doQuote(userpquota.MaxJobSize), \ 775 775 self.doQuote(userpquota.ident))) 776 776 777 777 def writeUserPQuotaWarnCount(self, userpquota, warncount) : 778 778 """Sets the warn counter value for a user quota.""" 779 779 self.doModify("UPDATE userpquota SET warncount=%s WHERE id=%s" % (self.doQuote(warncount), self.doQuote(userpquota.ident))) 780 780 781 781 def increaseUserPQuotaWarnCount(self, userpquota) : 782 782 """Increases the warn counter value for a user quota.""" 783 783 self.doModify("UPDATE userpquota SET warncount=warncount+1 WHERE id=%s" % self.doQuote(userpquota.ident)) 784 784 785 785 def saveGroupPQuota(self, grouppquota) : 786 786 """Saves a group print quota entry.""" … … 798 798 for record in result : 799 799 children.append(record.get("printerid")) # TODO : put this into the database integrity rules 800 if printer.ident not in children : 800 if printer.ident not in children : 801 801 self.doModify("INSERT INTO printergroupsmembers (groupid, printerid) VALUES (%s, %s)" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident))) 802 802 803 803 def removePrinterFromGroup(self, pgroup, printer) : 804 804 """Removes a printer from a printer group.""" 805 805 self.doModify("DELETE FROM printergroupsmembers WHERE groupid=%s AND printerid=%s" % (self.doQuote(pgroup.ident), self.doQuote(printer.ident))) 806 806 807 807 def retrieveHistory(self, user=None, printer=None, hostname=None, billingcode=None, jobid=None, limit=100, start=None, end=None) : 808 808 """Retrieves all print jobs for user on printer (or all) between start and end date, limited to first 100 results.""" … … 813 813 if printer is not None : # printer.ident is None anyway if printer doesn't exist 814 814 where.append("printerid=%s" % self.doQuote(printer.ident)) 815 if hostname is not None : 815 if hostname is not None : 816 816 where.append("hostname=%s" % self.doQuote(hostname)) 817 if billingcode is not None : 817 if billingcode is not None : 818 818 where.append("billingcode=%s" % self.doQuote(unicodeToDatabase(billingcode))) 819 if jobid is not None : 819 if jobid is not None : 820 820 where.append("jobid=%s" % self.doQuote(jobid)) # TODO : jobid is text, so unicodeToDatabase(jobid) but do all of them as well. 821 if start is not None : 821 if start is not None : 822 822 where.append("jobdate>=%s" % self.doQuote(start)) 823 if end is not None : 823 if end is not None : 824 824 where.append("jobdate<=%s" % self.doQuote(end)) 825 if where : 825 if where : 826 826 query += " AND %s" % " AND ".join(where) 827 827 query += " ORDER BY jobhistory.id DESC" … … 829 829 # TODO : LIMIT is not supported under DB2. 830 830 # TODO : so we must use something like " FETCH FIRST %s ROWS ONLY" % self.doQuote(int(limit)) 831 query += " LIMIT %s" % self.doQuote(int(limit)) 832 jobs = [] 833 result = self.doSearch(query) 831 query += " LIMIT %s" % self.doQuote(int(limit)) 832 jobs = [] 833 result = self.doSearch(query) 834 834 if result : 835 835 for fields in result : … … 837 837 jobs.append(job) 838 838 return jobs 839 840 def deleteUser(self, user) : 839 840 def deleteUser(self, user) : 841 841 """Completely deletes an user from the database.""" 842 842 # TODO : What should we do if we delete the last person who used a given printer ? 843 843 # TODO : we can't reassign the last job to the previous one, because next user would be 844 844 # TODO : incorrectly charged (overcharged). 845 for q in [ 845 for q in [ 846 846 "DELETE FROM payments WHERE userid=%s" % self.doQuote(user.ident), 847 847 "DELETE FROM groupsmembers WHERE userid=%s" % self.doQuote(user.ident), … … 851 851 ] : 852 852 self.doModify(q) 853 854 def multipleQueriesInTransaction(self, queries) : 853 854 def multipleQueriesInTransaction(self, queries) : 855 855 """Does many modifications in a single transaction.""" 856 856 self.beginTransaction() … … 858 858 for q in queries : 859 859 self.doModify(q) 860 except : 860 except : 861 861 self.rollbackTransaction() 862 862 raise 863 else : 863 else : 864 864 self.commitTransaction() 865 866 def deleteManyBillingCodes(self, billingcodes) : 865 866 def deleteManyBillingCodes(self, billingcodes) : 867 867 """Deletes many billing codes.""" 868 868 codeids = ", ".join(["%s" % self.doQuote(b.ident) for b in billingcodes]) 869 869 if codeids : 870 self.multipleQueriesInTransaction([ 870 self.multipleQueriesInTransaction([ 871 871 "DELETE FROM billingcodes WHERE id IN (%s)" % codeids,]) 872 873 def deleteManyUsers(self, users) : 872 873 def deleteManyUsers(self, users) : 874 874 """Deletes many users.""" 875 875 userids = ", ".join(["%s" % self.doQuote(u.ident) for u in users]) 876 876 if userids : 877 self.multipleQueriesInTransaction([ 877 self.multipleQueriesInTransaction([ 878 878 "DELETE FROM payments WHERE userid IN (%s)" % userids, 879 879 "DELETE FROM groupsmembers WHERE userid IN (%s)" % userids, … … 881 881 "DELETE FROM userpquota WHERE userid IN (%s)" % userids, 882 882 "DELETE FROM users WHERE id IN (%s)" % userids,]) 883 884 def deleteManyGroups(self, groups) : 883 884 def deleteManyGroups(self, groups) : 885 885 """Deletes many groups.""" 886 886 groupids = ", ".join(["%s" % self.doQuote(g.ident) for g in groups]) 887 887 if groupids : 888 self.multipleQueriesInTransaction([ 888 self.multipleQueriesInTransaction([ 889 889 "DELETE FROM groupsmembers WHERE groupid IN (%s)" % groupids, 890 890 "DELETE FROM grouppquota WHERE groupid IN (%s)" % groupids, 891 891 "DELETE FROM groups WHERE id IN (%s)" % groupids,]) 892 892 893 893 def deleteManyPrinters(self, printers) : 894 894 """Deletes many printers.""" 895 895 printerids = ", ".join(["%s" % self.doQuote(p.ident) for p in printers]) 896 896 if printerids : 897 self.multipleQueriesInTransaction([ 897 self.multipleQueriesInTransaction([ 898 898 "DELETE FROM printergroupsmembers WHERE groupid IN (%s) OR printerid IN (%s)" % (printerids, printerids), 899 899 "DELETE FROM jobhistory WHERE printerid IN (%s)" % printerids, … … 901 901 "DELETE FROM userpquota WHERE printerid IN (%s)" % printerids, 902 902 "DELETE FROM printers WHERE id IN (%s)" % printerids,]) 903 904 def deleteManyUserPQuotas(self, printers, users) : 903 904 def deleteManyUserPQuotas(self, printers, users) : 905 905 """Deletes many user print quota entries.""" 906 906 printerids = ", ".join(["%s" % self.doQuote(p.ident) for p in printers]) 907 907 userids = ", ".join(["%s" % self.doQuote(u.ident) for u in users]) 908 908 if userids and printerids : 909 self.multipleQueriesInTransaction([ 909 self.multipleQueriesInTransaction([ 910 910 "DELETE FROM jobhistory WHERE userid IN (%s) AND printerid IN (%s)" \ 911 911 % (userids, printerids), 912 912 "DELETE FROM userpquota WHERE userid IN (%s) AND printerid IN (%s)" \ 913 913 % (userids, printerids),]) 914 914 915 915 def deleteManyGroupPQuotas(self, printers, groups) : 916 916 """Deletes many group print quota entries.""" … … 918 918 groupids = ", ".join(["%s" % self.doQuote(g.ident) for g in groups]) 919 919 if groupids and printerids : 920 self.multipleQueriesInTransaction([ 920 self.multipleQueriesInTransaction([ 921 921 "DELETE FROM grouppquota WHERE groupid IN (%s) AND printerid IN (%s)" \ 922 922 % (groupids, printerids),]) 923 924 def deleteUserPQuota(self, upquota) : 923 924 def deleteUserPQuota(self, upquota) : 925 925 """Completely deletes an user print quota entry from the database.""" 926 for q in [ 926 for q in [ 927 927 "DELETE FROM jobhistory WHERE userid=%s AND printerid=%s" \ 928 928 % (self.doQuote(upquota.User.ident), self.doQuote(upquota.Printer.ident)), … … 930 930 ] : 931 931 self.doModify(q) 932 933 def deleteGroupPQuota(self, gpquota) : 932 933 def deleteGroupPQuota(self, gpquota) : 934 934 """Completely deletes a group print quota entry from the database.""" 935 for q in [ 935 for q in [ 936 936 "DELETE FROM grouppquota WHERE id=%s" % self.doQuote(gpquota.ident), 937 937 ] : 938 938 self.doModify(q) 939 940 def deleteGroup(self, group) : 939 940 def deleteGroup(self, group) : 941 941 """Completely deletes a group from the database.""" 942 942 for q in [ … … 944 944 "DELETE FROM grouppquota WHERE groupid=%s" % self.doQuote(group.ident), 945 945 "DELETE FROM groups WHERE id=%s" % self.doQuote(group.ident), 946 ] : 946 ] : 947 947 self.doModify(q) 948 949 def deletePrinter(self, printer) : 948 949 def deletePrinter(self, printer) : 950 950 """Completely deletes a printer from the database.""" 951 for q in [ 951 for q in [ 952 952 "DELETE FROM printergroupsmembers WHERE groupid=%s OR printerid=%s" % (self.doQuote(printer.ident), self.doQuote(printer.ident)), 953 953 "DELETE FROM jobhistory WHERE printerid=%s" % self.doQuote(printer.ident), … … 957 957 ] : 958 958 self.doModify(q) 959 960 def deleteBillingCode(self, code) : 959 960 def deleteBillingCode(self, code) : 961 961 """Completely deletes a billing code from the database.""" 962 962 for q in [ 963 963 "DELETE FROM billingcodes WHERE id=%s" % self.doQuote(code.ident), 964 ] : 964 ] : 965 965 self.doModify(q) 966 966