def restoreTo(self, sParentId, trans):
        """
        Restores the deleted object to the specified container.
        
        @param sParentId: The ID of the container in which
            the item will be restored
        @type sParentId: str    
        
        @param trans: A valid transaction handle
            
        @return: None
        """
        trans.actions.append( (self.restoreTo, (sParentId, trans)) )
        try:
            ## TODO: check if oDeleted exists
            oDeleted = db.getDeletedItem(self._deletedId, trans)
            oParent = db.getItem(sParentId, trans)
            
            if not(oDeleted.getContentclass() in oParent.containment):
                raise serverExceptions.ContainmentError
            
            # try to restore original item
            self._restore(oDeleted, oParent, trans)
            
            self.delete(trans, False)
            
            # update container
            oParent._addItemReference(oDeleted)
            db.putItem(oParent, trans)

        except serverExceptions.DBTransactionIncomplete:
            trans.retry()  
 def restore(self, trans):
     """
     Restores the deleted item to its original location, if
     it still exists.
     
     @param trans: A valid transaction handle
     
     @return: None
     
     @raise porcupine.serverExceptions.DBItemNotFound:
         If the original location no longer exists.
     """
     trans.actions.append( (self.restore, (trans, )) )
     try:
         ## TODO: check if oDeleted exists
         oDeleted = db.getDeletedItem(self._deletedId, trans)
         oOriginalParent = db.getItem(oDeleted._parentid, trans)
         
         # try to restore original item
         self._restore(oDeleted, oOriginalParent, trans)
 
         self.delete(trans, False)
         
         # update container
         oOriginalParent._addItemReference(oDeleted)
         db.putItem(oOriginalParent, trans)
     
     except serverExceptions.DBTransactionIncomplete:
         trans.retry()        
 def getDeletedItem(self):
     """
     Use this method to get the item that was logically deleted.
         
     @return: the deleted item
     @rtype: type
     """
     oDeleted = db.getDeletedItem(self._deletedId)
     return(oDeleted)
    def _undelete(self, deletedItem, trans):
        """
        Undeletes a logically deleted item.
        
        Returns: None
        """
        db.handle_update(deletedItem, None, trans)
        deletedItem._isDeleted = False
        
        if deletedItem.isCollection:
            lstChildren = deletedItem._items.values() + deletedItem._subfolders.values()
            for sID in lstChildren:
                oChild = db.getDeletedItem(sID, trans)
                self._undelete(oChild, trans)

        db.putItem(deletedItem, trans)
 def delete(self, trans, _removeDeleted=True):
     """
     Deletes the deleted object permanently.
     
     @param trans: A valid transaction handle
     @param _removeDeleted: Leave as is
         
     @return: None
     """
     Removeable.delete(self, trans)
     if _removeDeleted:
         # we got a direct call. remove deleted item
         ## TODO: check if oDeleted exists
         oDeleted = db.getDeletedItem(self._deletedId, trans)
         db.removeDeletedItem(oDeleted, trans)
     else:
         # we got a call from "restore" or "restoreTo"
         # do not replay in case of txn abort
         del trans.actions[-1]
 def on_create(item, attr, trans):
     if item._isDeleted:
         attr.value = [db.getDeletedItem(sID, trans) for sID in attr.value]
     CompositionEventHandler.on_update(item, attr, None, trans)