
 X5                 @   s   d  d l  m Z m Z d  d l m Z d  d l m Z m Z m Z d  d l	 m
 Z
 m Z d  d l m Z Gd d   d e  Z d d	   Z d
 d   Z d d   Z d d   Z d d   Z d d   Z d d   Z Gd d   d e  Z d S)    )CounterOrderedDict)
attrgetter)IntegrityErrorconnectionstransaction)signalssql)sixc                   s"   e  Z d  Z   f d d   Z   S)ProtectedErrorc                s&   | |  _  t t |   j | |  d  S)N)protected_objectssuperr   __init__)selfmsgr   )	__class__ G/home/ubuntu/projects/ifolica/build/django/django/db/models/deletion.pyr   
   s    	zProtectedError.__init__)__name__
__module____qualname__r   r   r   )r   r   r   	   s   r   c             C   s_   |  j  | d | j j d | j d | j | j r[ t | j j r[ |  j | d  |  n  d  S)Nsourcesource_attrnullable)	collectremote_fieldmodelnamenullr   featuresZcan_defer_constraint_checksadd_field_update)	collectorfieldsub_objsusingr   r   r   CASCADE   s    r%   c             C   s6   t  d | j j j | d j j | j f |   d  S)NzoCannot delete some instances of model '%s' because they are referenced through a protected foreign key: '%s.%s'r   )r   r   r   r   r   r   )r!   r"   r#   r$   r   r   r   PROTECT   s    #r&   c                sL   t     r!   f d d   } n   f d d   }   f d d   | _ | S)Nc                s   |  j  |     |  d  S)N)r    )r!   r"   r#   r$   )valuer   r   set_on_delete"   s    zSET.<locals>.set_on_deletec                s   |  j  |   |  d  S)N)r    )r!   r"   r#   r$   )r'   r   r   r(   %   s    c                  s   d   f i  f S)Nzdjango.db.models.SETr   r   )r'   r   r   <lambda>'   s    zSET.<locals>.<lambda>)callableZdeconstruct)r'   r(   r   )r'   r   SET    s
    r+   c             C   s   |  j  | d  |  d  S)N)r    )r!   r"   r#   r$   r   r   r   SET_NULL+   s    r,   c             C   s   |  j  | | j   |  d  S)N)r    Zget_default)r!   r"   r#   r$   r   r   r   SET_DEFAULT/   s    r-   c             C   s   d  S)Nr   )r!   r"   r#   r$   r   r   r   
DO_NOTHING3   s    r.   c             C   s   d d   |  j  d d  D S)Nc             s   s:   |  ]0 } | j  r | j r | j s. | j r | Vq d  S)N)auto_createdZconcreteZ
one_to_oneZone_to_many).0fr   r   r   	<genexpr>;   s    z4get_candidate_relations_to_delete.<locals>.<genexpr>Zinclude_hiddenT)Z
get_fields)optsr   r   r   !get_candidate_relations_to_delete7   s    r4   c               @   s   e  Z d  Z d d   Z d d d d d  Z d d   Z d d	 d
  Z d d   Z d d d d d d d d  Z d d   Z	 d d   Z
 d d   Z d d   Z d S)	Collectorc             C   s4   | |  _  t   |  _ i  |  _ g  |  _ i  |  _ d  S)N)r$   r   datafield_updatesfast_deletesdependencies)r   r$   r   r   r   r   A   s
    			zCollector.__init__NFc       	      C   s   | s
 g  Sg  } | d j  } |  j j | t    } x* | D]" } | | k r< | j |  q< q< W| j |  | d k	 r | r | r | | } } n  |  j j | j j t    j	 | j j  n  | S)a9  
        Adds 'objs' to the collection of objects to be deleted.  If the call is
        the result of a cascade, 'source' should be the model that caused it,
        and 'nullable' should be set to True if the relation can be null.

        Returns a list of all objects that were not already collected.
        r   N)
r   r6   
setdefaultsetappendupdater9   _metaconcrete_modeladd)	r   objsr   r   reverse_dependencynew_objsr   	instancesobjr   r   r   r@   Q   s    	%zCollector.addc             C   sL   | s
 d S| d j  } |  j j | i   j | | f t    j |  d S)z
        Schedules a field update. 'objs' must be a homogeneous iterable
        collection of model instances (e.g. a QuerySet).
        Nr   )r   r7   r:   r;   r=   )r   r"   r'   rA   r   r   r   r   r    l   s    	zCollector.add_field_updatec                s    r   j  j t k	 r d St | d  o7 t | d  s> d S| j } t j j |  s} t j j |  s} t j	 j |  r d S| j
 } t   f d d   | j j
 j j   D  r d Sx- t |  D] } | j j  j t k	 r d Sq Wx' | j
 j D] } t | d  r d Sq Wd S)a  
        Determines if the objects in the given queryset-like can be
        fast-deleted. This can be done if there are no cascades, no
        parents and no signal listeners for the object class.

        The 'from_field' tells where we are coming from - we need this to
        determine if the objects are in fact to be deleted. Allows also
        skipping parent -> child -> parent chain preventing fast delete of
        the child.
        Fr   _raw_deletec             3   s   |  ] } |   k Vq d  S)Nr   )r0   link)
from_fieldr   r   r2      s    z,Collector.can_fast_delete.<locals>.<genexpr>bulk_related_objectsT)r   	on_deleter%   hasattrr   r   
pre_deleteZhas_listenerspost_deleteZm2m_changedr>   anyr?   parentsvaluesr4   r"   r.   private_fields)r   rA   rH   r   r3   relatedr"   r   )rH   r   can_fast_deletex   s&    		.zCollector.can_fast_deletec                st   t  t |  j j j | j g   d    t     k ri    f d d   t d t      D S g Sd S)zU
        Returns the objs in suitably sized batches for the used connection.
           c                s$   g  |  ] }  | |     q Sr   r   )r0   i)conn_batch_sizerA   r   r   
<listcomp>   s   	z-Collector.get_del_batches.<locals>.<listcomp>r   N)maxr   r$   opsZbulk_batch_sizer   lenrange)r   rA   r"   r   )rV   rA   r   get_del_batches   s    (zCollector.get_del_batchesTc                s  |  j  |  r# |  j j |  d S|  j | | | d | } | sH d S| d j }	 | s |	 j j }
 xm t j |
 j j	  D]S     r}   f d d   | D } |  j
 | d |	 d   j j d d	 d d
 q} q} Wn  | rx t |	 j  D] } | j } | j j t k rq n  |  j | |  } xm | D]e } |  j | |  } |  j  | d | rm|  j j |  q-| r-| j j |  | | |  j  q-q-Wq WxW |	 j j D]F } t | d  r| j | |  j  } |  j
 | d |	 d d
 qqWn  d S)a]  
        Adds 'objs' to the collection of objects to be deleted as well as all
        parent instances.  'objs' must be a homogeneous iterable collection of
        model instances (e.g. a QuerySet).  If 'collect_related' is True,
        related objects will be handled by their respective on_delete handler.

        If the call is the result of a cascade, 'source' should be the model
        that caused it and 'nullable' should be set to True, if the relation
        can be null.

        If 'reverse_dependency' is True, 'source' will be deleted before the
        current model, rather than after. (Needed for cascading to parent
        models, the one case in which the cascade follows the forwards
        direction of an FK rather than the reverse direction.)

        If 'keep_parents' is True, data of parent model's will be not deleted.
        NrB   r   c                s"   g  |  ] } t  |   j   q Sr   )getattrr   )r0   rE   )ptrr   r   rW      s   	 z%Collector.collect.<locals>.<listcomp>r   r   collect_relatedFTrH   rI   r   )rS   r8   r<   r@   r   r>   r?   r
   
itervaluesrO   r   r   Zrelated_namer4   r"   rJ   r.   r\   related_objectsr$   rQ   rK   rI   )r   rA   r   r   r_   r   rB   Zkeep_parentsrC   r   r?   Zparent_objsrR   r"   Zbatchesbatchr#   r   )r^   r   r      sB    		'zCollector.collectc             C   s0   | j  j j |  j  j i | d | j j 6  S)z^
        Gets a QuerySet of objects related to ``objs`` via the relation ``related``.
        z%s__in)Zrelated_modelZ_base_managerr$   filterr"   r   )r   rR   rA   r   r   r   ra      s    zCollector.related_objectsc             c   sC   x< t  j |  j  D]( \ } } x | D] } | | f Vq& Wq Wd  S)N)r
   	iteritemsr6   )r   r   rD   rE   r   r   r   instances_with_model   s    zCollector.instances_with_modelc                s   g  } t    } t   j  } x t |  t |  k  r d } xv | D]n } | | k r^ qF n    j j | j j  } | o | j |  sF | j	 |  | j
 | j j  d } qF qF W| s! d  Sq! Wt   f d d   | D    _ d  S)NFTc             3   s"   |  ] } |   j  | f Vq d  S)N)r6   )r0   r   )r   r   r   r2     s   z!Collector.sort.<locals>.<genexpr>)r;   listr6   rZ   r9   getr>   r?   
differencer<   r@   r   )r   Zsorted_modelsZconcrete_modelsmodelsfoundr   r9   r   )r   r   sort   s"    	zCollector.sortc             C   s4  x< |  j  j   D]+ \ } } t | d t d  |  j  | <q W|  j   t   } t j d |  j d d  xK |  j	   D]= \ } } | j
 j s{ t j j d | d | d |  j  q{ q{ Wx= |  j D]2 } | j d |  j  } | | j j
 j | 7<q Wx t j |  j  D]n \ } } t j |  } xP t j |  D]? \ \ }	 }
 } | j d d	   | D i |
 |	 j 6|  j  q:WqWx$ t j |  j   D] } | j   qWx t j |  j   D] \ } } t j |  } d
 d	   | D } | j | |  j  } | | j
 j | 7<| j
 j sx3 | D]( } t j j d | d | d |  j  q%WqqWWd  QXxj t j |  j  D]V \ } } xG t j |  D]6 \ \ }	 }
 } x! | D] } t | |	 j  |
  qWqWqqWxJ t j |  j   D]6 \ } } x' | D] } t | | j
 j! j  d   qWqWt" | j#    t$ |  f S)Nkeypkr$   Z	savepointFZsenderinstancec             S   s   g  |  ] } | j   q Sr   )rm   )r0   rE   r   r   r   rW   #  s   	 z$Collector.delete.<locals>.<listcomp>c             S   s   g  |  ] } | j   q Sr   )rm   )r0   rE   r   r   r   rW   -  s   	 )%r6   itemssortedr   rk   r   r   Zatomicr$   re   r>   r/   r   rL   sendr8   rF   r   labelr
   rd   r7   r	   ZUpdateQueryZupdate_batchr   r`   reverseZDeleteQueryZdelete_batchrM   setattrZattnamerm   sumrP   dict)r   r   rD   Zdeleted_counterrE   qscountZinstances_for_fieldvaluesqueryr"   r'   Zpk_listrn   r   r   r   delete  sH    #
	"'"!zCollector.delete)r   r   r   r   r@   r    rS   r\   r   ra   re   rk   rz   r   r   r   r   r5   @   s   $	=r5   N)collectionsr   r   operatorr   Z	django.dbr   r   r   Zdjango.db.modelsr   r	   Zdjango.utilsr
   r   r%   r&   r+   r,   r-   r.   r4   objectr5   r   r   r   r   <module>   s   
	