Modify address check query to obtain well-defined result
The way in which UNION does not yield the desired result, because (a) UNION
merges results and (b) the result order is undefined. This patch changes the
query to select the counts as columns and hence provides a well-defined order.
# -*- coding: UTF-8 -*-# Copyright (c) 2008 - 2011, Pascal Volk# See COPYING for distribution information.""" VirtualMailManager.relocated ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Virtual Mail Manager's Relocated class to handle relocated users."""fromVirtualMailManager.domainimportget_gidfromVirtualMailManager.emailaddressimportEmailAddress, \DestinationEmailAddressfromVirtualMailManager.errorsimportRelocatedErrorasRErrfromVirtualMailManager.constantsimportDOMAIN_INVALID,NO_SUCH_DOMAIN, \NO_SUCH_RELOCATED,RELOCATED_ADDR_DEST_IDENTICAL,RELOCATED_EXISTS_=lambdamsg:msgclassRelocated(object):"""Class to handle e-mail addresses of relocated users."""__slots__=('_addr','_dest','_gid','_dbh')def__init__(self,dbh,address):"""Creates a new *Relocated* instance. The ``address`` is the old e-mail address of the user. Use `setDestination()` to set/update the new address, where the user has moved to. """assertisinstance(address,EmailAddress)self._addr=addressself._dbh=dbhself._gid=get_gid(self._dbh,self._addr.domainname)ifnotself._gid:raiseRErr(_(u"The domain '%s' does not exist.")%self._addr.domainname,NO_SUCH_DOMAIN)self._dest=Noneself._load()def__nonzero__(self):"""Returns `True` if the Relocated is known, `False` if it's new."""returnself._destisnotNonedef_load(self):"""Loads the destination address from the database into the `_dest` attribute. """dbc=self._dbh.cursor()dbc.execute('SELECT destination FROM relocated WHERE gid = %s AND ''address = %s',(self._gid,self._addr.localpart))destination=dbc.fetchone()dbc.close()ifdestination:destination=DestinationEmailAddress(destination[0],self._dbh)ifdestination.at_localhost:raiseRErr(_(u"The destination address' domain name must not "u"be localhost."),DOMAIN_INVALID)self._dest=destination@propertydefaddress(self):"""The Relocated's EmailAddress instance."""returnself._addrdefset_destination(self,destination):"""Sets/updates the new address of the relocated user."""update=Falseassertisinstance(destination,DestinationEmailAddress)ifdestination.at_localhost:raiseRErr(_(u"The destination address' domain name must not be "u"localhost."),DOMAIN_INVALID)ifself._addr==destination:raiseRErr(_(u'Address and destination are identical.'),RELOCATED_ADDR_DEST_IDENTICAL)ifself._dest:ifself._dest==destination:raiseRErr(_(u"The relocated user '%s' already exists.")%self._addr,RELOCATED_EXISTS)else:self._dest=destinationupdate=Trueelse:self._dest=destinationdbc=self._dbh.cursor()ifnotupdate:dbc.execute('INSERT INTO relocated (gid, address, destination) ''VALUES (%s, %s, %s)',(self._gid,self._addr.localpart,str(self._dest)))else:dbc.execute('UPDATE relocated SET destination = %s WHERE gid = %s ''AND address = %s',(str(self._dest),self._gid,self._addr.localpart))self._dbh.commit()dbc.close()defget_info(self):"""Returns the address to which mails should be sent."""ifnotself._dest:raiseRErr(_(u"The relocated user '%s' does not exist.")%self._addr,NO_SUCH_RELOCATED)returnself._destdefdelete(self):"""Deletes the relocated entry from the database."""ifnotself._dest:raiseRErr(_(u"The relocated user '%s' does not exist.")%self._addr,NO_SUCH_RELOCATED)dbc=self._dbh.cursor()dbc.execute('DELETE FROM relocated WHERE gid = %s AND address = %s',(self._gid,self._addr.localpart))ifdbc.rowcount>0:self._dbh.commit()dbc.close()self._dest=Nonedel_