Changeset 2cf43b4 in indico


Ignore:
Timestamp:
05/11/11 15:27:20 (2 years ago)
Author:
Jose Benito <jose.benito.gonzalez@…>
Branches:
master, hello-world-walkthrough, ipv6, v0.98-series, v0.98.2, v0.98.3, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 0da0c1403bae8e51d8229f460181c71b9e6dda72
Children:
fb6f28
Parents:
65a469
git-author:
Alexis Castilla Hernandez <alexis.castilla.hernandez@…> (05/02/11 15:21:51)
git-committer:
Jose Benito <jose.benito.gonzalez@…> (05/11/11 15:27:20)
Message:

[IMP] Registration form performance improvement

  • Added new attribute _registrantsByEmail, it is a dictionary where the keys are the email of the registrants. It allows to check if there is a registrant with the same email that we are trying to add.
  • In ObjectHolders?.py only one line has been changed (Removed .strip() because of the performance)
  • Added check the email in the data modification methods in order to avoid an email address repeated
  • Ticket #620
Location:
indico/MaKaC
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • indico/MaKaC/common/ObjectHolders.py

    rf395ef r2cf43b4  
    1919## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
    2020 
    21 """This file contain the definition of those classes which implement the root  
    22 access to the objects in the DB. The system will fetch and add objects to the  
    23 collections (or holders) through these classes that interact directly with the  
    24 persistence layer and do the necessary operations behind to ensure the  
     21"""This file contain the definition of those classes which implement the root 
     22access to the objects in the DB. The system will fetch and add objects to the 
     23collections (or holders) through these classes that interact directly with the 
     24persistence layer and do the necessary operations behind to ensure the 
    2525persistence. 
    2626""" 
     
    3333 
    3434class ObjectHolder: 
    35     """This class provides a common entry point for accessing conferences and  
    36        other objects of the business layer encapsulating the access to the DB  
     35    """This class provides a common entry point for accessing conferences and 
     36       other objects of the business layer encapsulating the access to the DB 
    3737       so it's transparent for other objects to deal with it. 
    38        "Clients" will just instantiate this class and will retrieve the objects  
    39        they are interested in through one of its methods. The object will have  
    40        to manage to connect to the DB in the correct way and return the object  
     38       "Clients" will just instantiate this class and will retrieve the objects 
     39       they are interested in through one of its methods. The object will have 
     40       to manage to connect to the DB in the correct way and return the object 
    4141       the client asks for. 
    42        This class is actually only a wrapper for the containers of objects,  
    43        therefore it doesn't need to be persistent; it encapsulates the  
    44        recovering and storing of those containers in the DB in a transparent  
     42       This class is actually only a wrapper for the containers of objects, 
     43       therefore it doesn't need to be persistent; it encapsulates the 
     44       recovering and storing of those containers in the DB in a transparent 
    4545       way. 
    4646       Attributes: 
     
    4848            created in the DB 
    4949        idxName -- (string) Contains the name of the current index being wrapped 
    50         counterName -- (string) Name of the counter which will be used to  
     50        counterName -- (string) Name of the counter which will be used to 
    5151            generate unique identifiers for the objects stored on the current 
    5252            index. 
     
    6262 
    6363    def __init__(self): 
    64         """Class constructor. Gets an opened DB storage and initializes the  
     64        """Class constructor. Gets an opened DB storage and initializes the 
    6565           DB connection so it's available for later requests. 
    6666        """ 
     
    8282           If the key doesn't exist if creates a new tree and inserts it into the 
    8383           DB root. 
    84            BTree objects act as a dictionary but due to their data structure  
     84           BTree objects act as a dictionary but due to their data structure 
    8585           properties allow to increase the concurrency (don't need to load all 
    8686           the mapping on memory) and improves performance. 
     
    8989        """ 
    9090        root = DBMgr.getInstance().getDBConnection().root() 
    91         name =  name.strip().lower() 
     91        name =  name.lower() 
    9292        if not (name in self.__allowedIdxs): 
    9393            raise Exception( _("index name not allowed %s")%name) 
     
    9595            root[ name ] = OOBTree.OOBTree() 
    9696        return root[ name ] 
    97      
     97 
    9898    def _newId( self ): 
    9999        """ 
     
    105105            idxs[self.counterName] = Counter() 
    106106        return idxs[self.counterName].newCount() 
    107      
     107 
    108108    def getLastId(self): 
    109109        if self.counterName == None: 
     
    113113            idxs[self.counterName] = Counter() 
    114114        return idxs[self.counterName]._getCount() 
    115      
     115 
    116116    def add( self, newItem ): 
    117117        """adds an object to the index and assings it a new unique id. 
     
    134134            return 
    135135        del tree[item.getId()] 
    136      
     136 
    137137    def removeById( self, itemid ): 
    138138        """removes the specified object from the index. 
     
    142142            return 
    143143        del tree[itemid] 
    144          
     144 
    145145    def getById( self, id ): 
    146146        """returns an object from the index which id corresponds to the one 
     
    156156        """ 
    157157        return self._getIdx().values() 
    158      
     158 
    159159    def getValuesToList( self ): 
    160160        l = [] 
     
    166166class IndexHolder( ObjectHolder ): 
    167167    """Specialised ObjectHolder class which provides a wrapper for collections 
    168         based in a Catalog for indexing the objects. It allows to index some  
     168        based in a Catalog for indexing the objects. It allows to index some 
    169169        declared attributes of the stored objects and then perform SQL-like 
    170170        queries 
     
    189189        #    self._idx = Catalog( self.idxClass ) 
    190190        #    shelf.add_catalog(self._idx) 
    191      
     191 
    192192    def add( self, newItem): 
    193193        #XXX: this makes the perfomance decrease dramatically. Operations like 
    194         #   this should be avoided and the clients should now take care of  
     194        #   this should be avoided and the clients should now take care of 
    195195        #   not inserting the same user twice 
    196196        #if newItem in self.getList(): 
    197         #    return  
     197        #    return 
    198198        if newItem.getId() != None and  newItem.getId() != "": 
    199199            raise MaKaCError( _("Object %s has already an id it is probably already inserted in the holder %s")%(newItem, self.__class__)) 
     
    213213    def getList( self ): 
    214214        return self._getIdx().dump() 
    215      
     215 
    216216    def hasKey( self, id ): 
    217217        #XXX: verify how to implement it 
    218218        return False 
    219      
    220  
    221  
     219 
     220 
     221 
  • indico/MaKaC/conference.py

    r180199 r2cf43b4  
    45704570        return self._registrants 
    45714571 
     4572    def getRegistrantsByEmail(self): 
     4573        try: 
     4574            if self._registrantsByEmail: 
     4575                pass 
     4576        except AttributeError, e: 
     4577            self._registrantsByEmail = self._createRegistrantsByEmail() 
     4578            self.notifyModification() 
     4579        return self._registrantsByEmail 
     4580 
     4581    def _createRegistrantsByEmail(self): 
     4582        dicByEmail = {} 
     4583        for r in self.getRegistrantsList(): 
     4584            dicByEmail[r.getEmail()] = r 
     4585        return dicByEmail 
     4586 
    45724587    def getRegistrantsList(self, sort = False): 
    45734588        rl = self.getRegistrants().values() 
     
    45894604        self.notifyModification() 
    45904605 
     4606    def updateRegistrantIndexByEmail(self, rp, newEmail): 
     4607        oldEmail = rp.getEmail() 
     4608        if oldEmail != newEmail: 
     4609            if self.getRegistrantsByEmail().has_key(oldEmail): 
     4610                del self.getRegistrantsByEmail()[oldEmail] 
     4611            self.getRegistrantsByEmail()[newEmail] = rp 
     4612            self.notifyModification() 
     4613 
    45914614    def hasRegistrant(self,rp): 
    45924615        return rp.getConference()==self and \ 
    45934616                self.getRegistrants().has_key(rp.getId()) 
    45944617 
    4595     def hasRegistrantByEmail(self, email, registrant=None): 
    4596         # Return true if there is someone with the email of the param "email" but 
    4597         # the email has to be different to the one of the "registrant" (just in case we 
    4598         # try to modify the data of the registrant) 
    4599         for r in self.getRegistrantsList(): 
    4600             if r.getEmail().strip().lower() == email.strip().lower(): 
    4601                 if registrant is not None and registrant.getEmail().strip().lower() == email.strip().lower(): 
    4602                     continue 
    4603                 return True 
    4604         return False 
     4618    def hasRegistrantByEmail(self, email): 
     4619        # Return true if there is someone with the email of the param "email" 
     4620        return self.getRegistrantsByEmail().has_key(email) 
    46054621 
    46064622    def removeRegistrant(self, id): 
    46074623        part = self.getRegistrants()[id] 
    46084624        self._registrationForm.notifyRegistrantRemoval(self.getRegistrants()[id]) 
     4625        del self.getRegistrantsByEmail()[self.getRegistrantById(id).getEmail()] 
    46094626        del self.getRegistrants()[id] 
    46104627        if part.getAvatar() is not None: 
  • indico/MaKaC/registration.py

    r5f7a6d r2cf43b4  
    41474147 
    41484148    def setPersonalData(self, data): 
     4149 
     4150        self.getConference().updateRegistrantIndexByEmail(self, data.get("email","")) 
     4151 
    41494152        self.setTitle(data.get("title","")) 
    41504153        self.setFirstName(data.get("firstName","")) 
  • indico/MaKaC/webinterface/rh/registrantsModif.py

    r0cf3cb r2cf43b4  
    514514        for key in keys: 
    515515            if key not in params.keys() or params.get(key,"").strip() == "": 
    516                 raise FormValuesError("The field \"%s\" is mandatory and you must fill it in order to modify the registrant"%(pd.getData()[key].getName())) 
    517         self._cancel = params.has_key("cancel") 
    518  
    519     def _process( self ): 
    520         if not self._cancel: 
    521             if self._conf.hasRegistrantByEmail(self._getRequestParams().get("email",""), self._registrant): 
    522                 raise FormValuesError("There is already a user with the email \"%s\". Please choose another one"%self._getRequestParams().get("email","--no email--")) 
     516                raise FormValuesError(_("The field \"%s\" is mandatory and you must fill it in order to modify the registrant")%(pd.getData()[key].getName())) 
     517        self._cancel = params.has_key("cancel") 
     518 
     519    def _process( self ): 
     520        if not self._cancel: 
     521            if self._getRequestParams().get("email","") != self._registrant.getEmail() and self._conf.hasRegistrantByEmail(self._getRequestParams().get("email","")): 
     522                raise FormValuesError(_("There is already a user with the email \"%s\". Please choose another one")%self._getRequestParams().get("email","--no email--")) 
    523523            self._registrant.setPersonalData(self._getRequestParams()) 
    524524        self._redirect(urlHandlers.UHRegistrantModification.getURL(self._registrant)) 
  • indico/MaKaC/webinterface/rh/registrationFormDisplay.py

    r907607 r2cf43b4  
    281281            else: 
    282282                rp = self._getUser().getRegistrantById(self._conf.getId()) 
     283                # check if the email is being changed by another one that already exists 
     284                if self._getRequestParams().get("email","") != rp.getEmail() and self._conf.hasRegistrantByEmail(self._getRequestParams().get("email","")): 
     285                    raise FormValuesError(_("There is already a user with the email \"%s\". Please choose another one")%self._getRequestParams().get("email","--no email--")) 
    283286                rp.setValues(self._getRequestParams(), self._getUser()) 
    284287                # avoid multiple sending in case of db conflict 
Note: See TracChangeset for help on using the changeset viewer.