# HG changeset patch # User Pascal Volk # Date 1297114113 0 # Node ID 0cae9989395ba3859b0e42defed30e1120358f90 # Parent d3a97f7fb98abb56c027ba0b796bca3abfaec631 VMM/quotalimit: Added new module quotalimit to the repository. diff -r d3a97f7fb98a -r 0cae9989395b VirtualMailManager/quotalimit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VirtualMailManager/quotalimit.py Mon Feb 07 21:28:33 2011 +0000 @@ -0,0 +1,128 @@ +# -*- coding: UTF-8 -*- +# Copyright (c) 2011, Pascal Volk +# See COPYING for distribution information. +""" + VirtualMailManager.quotalimit + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Virtual Mail Manager's QuotaLimit class to manage quota limits + for domains and accounts. +""" + +from VirtualMailManager.constants import VMM_ERROR +from VirtualMailManager.errors import VMMError +from VirtualMailManager.pycompat import all + +_ = lambda msg: msg + + +class QuotaLimit(object): + """Class to handle quota limit specific data.""" + __slots__ = ('_dbh', '_qid', '_bytes', '_messages') + _kwargs = ('qid', 'bytes', 'messages') + + def __init__(self, dbh, **kwargs): + """Create a new QuotaLimit instance. + + Either the `qid` keyword or the `bytes` and `messages` keywords + must be specified. + + Arguments: + + `dbh` : pyPgSQL.PgSQL.Connection || psycopg2._psycopg.connection + A database connection for the database access. + + Keyword arguments: + + `qid` : int + The id of a quota limit + `bytes` : long + The quota limit in bytes. + `messages` : int + The quota limit in number of messages + """ + self._dbh = dbh + self._qid = 0 + self._bytes = 0 + self._messages = 0 + + for key in kwargs.iterkeys(): + if key not in self.__class__._kwargs: + raise ValueError('unrecognized keyword: %r' % key) + qid = kwargs.get('qid') + if qid is not None: + assert isinstance(qid, (int, long)) + self._load_by_qid(qid) + else: + bytes_, msgs = kwargs.get('bytes'), kwargs.get('messages') + assert all(isinstance(i, (int, long)) for i in (bytes_, msgs)) + if bytes_ < 0: + self._bytes = -bytes_ + else: + self._bytes = bytes_ + if msgs < 0: + self._messages = -msgs + else: + self._messages = msgs + self._load_by_limit() + + @property + def bytes(self): + """Quota limit in bytes.""" + return self._bytes + + @property + def messages(self): + """Quota limit in number of messages.""" + return self._messages + + @property + def qid(self): + """The quota limit's unique ID.""" + return self._qid + + def __eq__(self, other): + if isinstance(other, self.__class__): + return self._qid == other._qid + return NotImplemented + + def __ne__(self, other): + if isinstance(other, self.__class__): + return self._qid != other._qid + return NotImplemented + + def _load_by_limit(self): + """Load the quota limit by limit values from the database.""" + dbc = self._dbh.cursor() + dbc.execute('SELECT qid FROM quotalimit WHERE bytes = %s AND ' + 'messages = %s', (self._bytes, self._messages)) + res = dbc.fetchone() + dbc.close() + if res: + self._qid = res[0] + else: + self._save() + + def _load_by_qid(self, qid): + """Load the quota limit by its unique ID from the database.""" + dbc = self._dbh.cursor() + dbc.execute('SELECT bytes, messages FROM quotalimit WHERE qid = %s', + (qid,)) + res = dbc.fetchone() + dbc.close() + if not res: + raise VMMError(_(u'Unknown quota limit id specified.'), VMM_ERROR) + self._qid = qid + self._bytes, self._messages = res + + def _save(self): + """Store a new quota limit in the database.""" + dbc = self._dbh.cursor() + dbc.execute("SELECT nextval('quotalimit_id')") + self._qid = dbc.fetchone()[0] + dbc.execute('INSERT INTO quotalimit (qid, bytes, messages) VALUES ' + '(%s, %s, %s)', (self._qid, self._bytes, self._messages)) + self._dbh.commit() + dbc.close() + +del _