B
    .²ô`Üµ  ã               @   sì   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 ddlm
Z
 dd	lmZ d
dlmZ d
dlmZ d
dlmZ G dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZeee
ee	eiZdS )zRelationship dependencies.

é   )Ú
attributes)Úexc)Úsync)Ú
unitofwork)Úutil)Ú
MANYTOMANY)Ú	MANYTOONE)Ú	ONETOMANYé   )Úsqlc               @   sš   e Zd Zdd„ Zedd„ ƒZdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd%dd„Zd d!„ Zd"d#„ Zd$S )&ÚDependencyProcessorc             C   s¢   || _ |j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j	| _	| jr^t
j| _nt
j| _| jrvt
j| _nt
j| _|j| _| j jsžt d| j  ¡‚d S )Nz|Can't build a DependencyProcessor for relationship %s. No target attributes to populate between parent and child are present)ÚpropÚcascadeÚmapperÚparentÚ	secondaryÚ	directionÚpost_updateÚpassive_deletesÚpassive_updatesÚenable_typechecksr   ÚPASSIVE_NO_INITIALIZEÚ_passive_delete_flagÚPASSIVE_OFFÚ_passive_update_flagÚkeyÚsynchronize_pairsÚsa_excÚArgumentError)Úselfr   © r    úH/home/dcms/DCMS/lib/python3.7/site-packages/sqlalchemy/orm/dependency.pyÚ__init__   s*    

zDependencyProcessor.__init__c             C   s   t |j |ƒS )N)Ú_direction_to_processorr   )Úclsr   r    r    r!   Úfrom_relationship6   s    z%DependencyProcessor.from_relationshipc             C   s   | j j | j¡ |¡S )z¤return True if the given object instance has a parent,
        according to the ``InstrumentedAttribute`` handled by this
        ``DependencyProcessor``.

        )r   Zclass_managerÚget_implr   Ú	hasparent)r   Ústater    r    r!   r'   :   s    zDependencyProcessor.hasparentc             C   s   |  | d¡ dS )z•establish actions and dependencies related to a flush.

        These actions will operate on all relevant states in
        the aggregate.

        TN)Úregister_preprocessor)r   Úuowr    r    r!   Úper_property_preprocessorsB   s    z.DependencyProcessor.per_property_preprocessorsc          	   C   sz   t  || dd¡}t  || dd¡}t  || jj¡}t  || jj¡}t  || jj¡}t  || jj¡}|  |||||||¡ d S )NFT)r   Ú
ProcessAllÚSaveUpdateAllr   Úprimary_base_mapperr   Ú	DeleteAllÚper_property_dependencies)r   r*   Ú
after_saveÚbefore_deleteÚparent_savesÚchild_savesÚparent_deletesÚchild_deletesr    r    r!   Úper_property_flush_actionsK   s$    z.DependencyProcessor.per_property_flush_actionsc             C   s  | j j}t ||¡}t ||¡}|r<t || dd¡}d|_nt || dd¡}d|_||jkr€||jksjt‚|df|dfg}	d}
nd}
|s°t || j	j
¡}d }}||jkrÖd}n&t || j	j
¡}d }}||jkrÖd}x&|D ]}|j| j j ||j|r| jntj¡}|sqÞ|r>t || d|¡}|r`t ||¡}n"t || d|¡}|r`t ||¡}|
rÐg }	xd|D ]\\}}||jkrŠd}n6|j| \}}|r°t ||¡df}nt ||¡df}|	 |¡ qpW x*|	D ]"\}}|  ||||||||¡ qÖW qÞW dS )zèestablish actions and dependencies related to a flush.

        These actions will operate on all relevant states
        individually.    This occurs only if there are cycles
        in the 'aggregated' version of events.

        TFN)NN)r   r.   r   r-   r/   r,   ÚdisabledZcyclesÚAssertionErrorr   Úbase_mapperÚmanagerr   ÚimplZget_all_pendingÚdictr   r   r   ZProcessStateZDeleteStateZSaveUpdateStateÚstatesÚappendÚper_state_dependencies)r   r*   r>   ÚisdeleteZchild_base_mapperr4   r6   r2   r1   Zchild_actionsZchild_in_cyclesr3   r5   Zparent_in_cyclesr(   Zsum_Zchild_stateÚchildÚchild_actionÚdeletedZlistonlyÚchildisdeleter    r    r!   Úper_state_flush_actionsg   sx    	




z+DependencyProcessor.per_state_flush_actionsc             C   s   dS )NFr    )r   Ú	uowcommitr>   r    r    r!   Úpresort_deletes×   s    z#DependencyProcessor.presort_deletesc             C   s   dS )NFr    )r   rG   r>   r    r    r!   Úpresort_savesÚ   s    z!DependencyProcessor.presort_savesc             C   s   d S )Nr    )r   rG   r>   r    r    r!   Úprocess_deletesÝ   s    z#DependencyProcessor.process_deletesc             C   s   d S )Nr    )r   rG   r>   r    r    r!   Úprocess_savesà   s    z!DependencyProcessor.process_savesc             C   sv   |r
| j rtj}n| jtkr$tj}ntj}xF|D ]$}| || j|¡}|r0| 	¡ s0dS q0W |op| j
j op| j|jkS d S )NT)r   r   r   r   r   ZPASSIVE_NO_FETCH_RELATEDr   Úget_attribute_historyr   Úemptyr   Z_is_self_referentialr   Zmappers)r   rG   r>   rA   ÚpassiveÚsÚhistoryr    r    r!   Úprop_has_changesã   s    



z$DependencyProcessor.prop_has_changesc             C   s–   | j jr$|d kr$t d| j f ¡‚nn|d k	r’| jj|| j ds’| jj|ddrtt d|j| j | jj| jdœ ¡‚nt d|j| j | jjdœ ¡‚d S )Nz-Can't flush None value found in collection %s)Zallow_subtypesTaE  Attempting to flush an item of type %(x)s as a member of collection "%(y)s". Expected an object of type %(z)s or a polymorphic subclass of this type. If %(x)s is a subclass of %(z)s, configure mapper "%(zm)s" to load this subtype polymorphically, or set enable_typechecks=False to allow any subtype to be accepted for flush. )ÚxÚyÚzZzmz•Attempting to flush an item of type %(x)s as a member of collection "%(y)s". Expected an object of type %(z)s or a polymorphic subclass of this type.)rR   rS   rT   )r   Úuselistr   Z
FlushErrorr   Z_canloadr   Úclass_)r   r(   r    r    r!   Ú_verify_canloadù   s$    
z#DependencyProcessor._verify_canloadc             C   s
   t ƒ ‚d S )N)ÚNotImplementedError)r   r(   rB   ÚassociationrowÚ	clearkeysrG   r    r    r!   Ú_synchronize"  s    z DependencyProcessor._synchronizec             C   s>   | j jsd S tt| jgdd„ | j jD ƒ ƒƒ}| d|ft¡S )Nc             S   s   g | ]
}|j ‘qS r    )r   )Ú.0Úpr    r    r!   ú
<listcomp>*  s    zCDependencyProcessor._get_reversed_processed_set.<locals>.<listcomp>Zreverse_key)r   Ú_reverse_propertyÚtupleÚsortedr   ÚmemoÚset)r   r*   Zprocess_keyr    r    r!   Ú_get_reversed_processed_set%  s
     z/DependencyProcessor._get_reversed_processed_setFc             C   s:   x4|D ],}|r|d k	r|  |dd„ | jjD ƒ¡ P qW d S )Nc             S   s   g | ]\}}|‘qS r    r    )r\   ÚlÚrr    r    r!   r^   2  s    z4DependencyProcessor._post_update.<locals>.<listcomp>)Zregister_post_updater   r   )r   r(   rG   ÚrelatedÚis_m2o_deleterR   r    r    r!   Ú_post_update.  s
    
z DependencyProcessor._post_updatec             C   s
   t ƒ ‚d S )N)rX   )r   rG   r(   r    r    r!   Ú_pks_changed6  s    z DependencyProcessor._pks_changedc             C   s   d| j j| jf S )Nz%s(%s))Ú	__class__Ú__name__r   )r   r    r    r!   Ú__repr__9  s    zDependencyProcessor.__repr__N)F)rl   Ú
__module__Ú__qualname__r"   Úclassmethodr%   r'   r+   r7   rF   rH   rI   rJ   rK   rQ   rW   r[   rd   ri   rj   rm   r    r    r    r!   r      s"   	p)	
r   c               @   sL   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dS )ÚOneToManyDPc       
   
   C   s–   | j r\t || jjd¡}t || jjd¡}	|j ||f||f||f||	f|	|f|	|fg¡ n6|j ||f||f||f||f||f||f||fg¡ d S )NFT)r   r   ÚPostUpdateAllr   r.   ÚdependenciesÚupdate)
r   r*   r3   r4   r5   r6   r1   r2   Úchild_post_updatesÚchild_pre_updatesr    r    r!   r0   >  s(    
z%OneToManyDP.per_property_dependenciesc	             C   sä   | j r¤t || jjd¡}	t || jjd¡}
|sl|rL|j ||f||	fg¡ q¢|j ||f||f||	fg¡ qà|rŠ|j ||
f|
|fg¡ qà|j ||
f|
|fg¡ n<|sÈ|j ||f||f||fg¡ n|j ||f||fg¡ d S )NFT)r   r   rr   r   r.   rs   rt   )r   r*   Úsave_parentÚdelete_parentrC   r1   r2   rA   rE   ru   rv   r    r    r!   r@   g  s8    z"OneToManyDP.per_state_dependenciesc             C   s´   | j j o| jdk }x˜|D ]}| || j| j¡}|rxF|jD ]<}|d k	r>|  |¡dkr>| j jrp|j	|dd q>| 	|¡ q>W |rx(|j
D ]}|d k	rŠ|j	|d| jd qŠW qW d S )NÚallFT)rA   Údelete)Ú	operationr   )r   rz   r   rL   r   r   rD   r'   Údelete_orphanÚregister_objectÚ	unchangedr   )r   rG   r>   Úshould_null_fksr(   rP   rB   r    r    r!   rH   ª  s    
zOneToManyDP.presort_deletesc          	   C   sn  |  d| ft¡}| jj o$| jdk }x@|D ]6}|  ||¡}|rJ| jrRtj}ntj	}| 
|| j|¡}|r*x*|jD ] }	|	d k	rv|j|	dd| jd qvW | |j¡ x‚|jD ]x}	| jjsÔ|rÒ|j|	dd| jd q®|  |	¡dkr®|j|	dd| jd x.| j d|	¡D ]\}
}}}|j|dd	 qW q®W |r.|r.x2|jD ](}	|	d k	r:|j|	d| jd
| jd q:W q.W d S )NÚchildren_addedry   TÚadd)Zcancel_deleter{   r   Frz   )rA   r{   r   )rA   z	pk change)r{   r   )rb   rc   r   r|   r   rj   r   r   r   r   rL   r   Úaddedr}   r   rt   rD   r'   r   Úcascade_iteratorr~   )r   rG   r>   r€   r   r(   Úpks_changedrN   rP   rB   ÚcÚmÚst_Údct_r    r    r!   rI   Å  sZ    



zOneToManyDP.presort_savesc          
   C   sú   | j s| jdksö| d| ft¡}xÔ|D ]Ì}| || j| j¡}|r&xR|jD ]H}|d k	rH|  |¡dkrH|  	||d d|d¡ | j rH|rH|  
|||g¡ qHW | j s¢| jjs&xNt|jƒ |¡D ]:}|d k	r´|  	||d d|d¡ | j r´|r´|  
|||g¡ q´W q&W d S )Nry   r€   FT)r   r   rb   rc   rL   r   r   rD   r'   r[   ri   r   rz   r~   Ú
difference)r   rG   r>   r€   r(   rP   rB   r    r    r!   rJ     s,    



zOneToManyDP.process_deletesc          
   C   sê   | j j o| jdk }xÎ|D ]Æ}| || jtj¡}|rx@|jD ]6}|  ||d d|d¡ |d k	r>| j	r>|  
|||g¡ q>W x8|jD ].}|r€| j js€|  |¡s€|  ||d d|d¡ q€W |  ||¡rx"|jD ]}|  ||d d|d¡ qÆW qW d S )Nry   FT)r   r|   r   rL   r   r   r   r‚   r[   r   ri   rD   r'   rj   r~   )r   rG   r>   r   r(   rP   rB   r    r    r!   rK   /  s*    


zOneToManyDP.process_savesc       	   	   C   sp   |}|}|   |¡ |d ks*| js.| |¡r.d S |rHt || j| jj¡ n$t || j	|| j| jj|| j
oh|¡ d S )N)rW   r   Ú
is_deletedr   Úclearr   r   r   Úpopulater   r   )	r   r(   rB   rY   rZ   rG   r„   ÚsourceÚdestr    r    r!   r[   Q  s     
zOneToManyDP._synchronizec             C   s   t  ||| j| jj¡S )N)r   Úsource_modifiedr   r   r   )r   rG   r(   r    r    r!   rj   h  s    zOneToManyDP._pks_changedN)rl   rn   ro   r0   r@   rH   rI   rJ   rK   r[   rj   r    r    r    r!   rq   =  s   )C>,"rq   c               @   sN   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	ddd„Z
dS )ÚManyToOneDPc             C   s2   t  | |¡ x | jjD ]}|j t|ƒ¡ qW d S )N)r   r"   r   Zself_and_descendantsZ_dependency_processorsr?   ÚDetectKeySwitch)r   r   r   r    r    r!   r"   o  s    zManyToOneDP.__init__c       
   
   C   sŠ   | j rbt || jjd¡}t || jjd¡}	|j ||f||f||f||	f||	f|	|f|	|fg¡ n$|j ||f||f||f||fg¡ d S )NFT)r   r   rr   r   r.   rs   rt   )
r   r*   r3   r4   r5   r6   r1   r2   Úparent_post_updatesÚparent_pre_updatesr    r    r!   r0   t  s$    z%ManyToOneDP.per_property_dependenciesc	             C   sÜ   | j rŒ|sZt || jjd¡}	|r:|j ||	f|	|fg¡ qŠ|j ||f||f||	fg¡ qØt || jjd¡}
|j ||
f|
|f|
|fg¡ nL|sÂ|s®|j ||f||fg¡ qØ|j ||fg¡ n|rØ|j ||fg¡ d S )NFT)r   r   rr   r   r.   rs   rt   )r   r*   rw   rx   rC   r1   r2   rA   rE   r’   r“   r    r    r!   r@   œ  s2    z"ManyToOneDP.per_state_dependenciesc             C   s°   | j js| j jr¬xš|D ]’}| || j| j¡}|r| j jrB| ¡ }n| ¡ }x\|D ]T}|d kr^qP|j|dd| j	d | j
 d|¡}x"|D ]\}}	}
}|j|
dd q†W qPW qW d S )NTrz   )rA   r{   r   )rA   )r   rz   r|   rL   r   r   ÚsumZnon_deletedr}   r   r   rƒ   )r   rG   r>   r(   rP   ZtodeleterB   Útr…   r†   r‡   rˆ   r    r    r!   rH   Ö  s&    



zManyToOneDP.presort_deletesc             C   s¦   x |D ]˜}|j |d| jd | jjr| || j| j¡}|rxb|jD ]X}|  |¡dkrB|j |dd| jd | j	 
d|¡}x"|D ]\}}}	}
|j |	dd q|W qBW qW d S )Nr   )r{   r   FTrz   )rA   r{   r   )rA   )r}   r   r   r|   rL   r   r   rD   r'   r   rƒ   )r   rG   r>   r(   rP   rB   r•   r…   r†   r‡   rˆ   r    r    r!   rI   î  s     

zManyToOneDP.presort_savesc             C   sr   | j rn| jjsn| jdksnxT|D ]L}|  |d d d|¡ |r| j r| || j| j¡}|r| j||| 	¡ dd qW d S )Nry   T)rh   )
r   r   r|   r   r[   rL   r   r   ri   r”   )r   rG   r>   r(   rP   r    r    r!   rJ     s    


zManyToOneDP.process_deletesc          
   C   s†   x€|D ]x}|  || jtj¡}|r|jrLx>|jD ]}|  ||d d|d¡ q.W n|jrf|  |d d d|d¡ | jr|  ||| 	¡ ¡ qW d S )NFr   Trz   )
rL   r   r   r   r‚   r[   rD   r   ri   r”   )r   rG   r>   r(   rP   rB   r    r    r!   rK     s    
zManyToOneDP.process_savesNc          	   C   s¦   |d ks| j s| |¡rd S |d k	rX|d k	rX|j |¡sXt dt |¡|| jf ¡ d S |sd|d krzt	 
|| j| jj¡ n(|  |¡ t	 || j|| j| jj|d¡ d S )NzGObject of type %s not in session, %s operation along '%s' won't proceedF)r   rŠ   ÚsessionÚ_contains_stater   ÚwarnÚ
mapperutilÚstate_class_strr   r   r‹   r   r   rW   rŒ   r   )r   r(   rB   rY   rZ   rG   r{   r    r    r!   r[   *  s*    	
zManyToOneDP._synchronize)N)rl   rn   ro   r"   r0   r@   rH   rI   rJ   rK   r[   r    r    r    r!   r   n  s   (:r   c               @   sh   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )r‘   a”  For many-to-one relationships with no one-to-many backref,
    searches for parents through the unit of work when a primary
    key has changed and updates them.

    Theoretically, this approach could be expanded to support transparent
    deletion of objects referenced via many-to-one as well, although
    the current attribute system doesn't do enough bookkeeping for this
    to be efficient.

    c             C   s<   | j jr,| jrd S ddd„ | j jD ƒkr,d S | | d¡ d S )NFc             s   s   | ]}|j V  qd S )N)r   )r\   r   r    r    r!   ú	<genexpr>e  s   z=DetectKeySwitch.per_property_preprocessors.<locals>.<genexpr>)r   r_   r   r)   )r   r*   r    r    r!   r+   _  s    z*DetectKeySwitch.per_property_preprocessorsc             C   s6   t  || jj¡}t  || dd¡}|j ||fg¡ d S )NF)r   r-   r   r:   r,   rs   rt   )r   r*   r3   r1   r    r    r!   r7   l  s    z*DetectKeySwitch.per_property_flush_actionsc             C   s   d S )Nr    )r   r*   r>   rA   r    r    r!   rF   q  s    z'DetectKeySwitch.per_state_flush_actionsc             C   s   d S )Nr    )r   rG   r>   r    r    r!   rH   t  s    zDetectKeySwitch.presort_deletesc             C   s   | j s|  ||¡ d S )N)r   Ú_process_key_switches)r   r*   r>   r    r    r!   rI   w  s    zDetectKeySwitch.presort_savesc             C   s"   |s| j r|  ||¡}t|ƒS dS )NF)r   Ú_key_switchersÚbool)r   r*   r>   rA   Údr    r    r!   rQ   }  s    
z DetectKeySwitch.prop_has_changesc             C   s   dst ‚d S )NF)r9   )r   rG   r>   r    r    r!   rJ   „  s    zDetectKeySwitch.process_deletesc             C   s   | j s
t‚|  ||¡ d S )N)r   r9   rœ   )r   rG   r>   r    r    r!   rK   ‡  s    
zDetectKeySwitch.process_savesc             C   s^   |  d| fdd„ ¡\}}| |¡}x6|D ].}||kr(|  ||¡rL| |¡ q(| |¡ q(W |S )NZpk_switchersc               S   s   t ƒ t ƒ fS )N)rc   r    r    r    r!   Ú<lambda>‘  ó    z0DetectKeySwitch._key_switchers.<locals>.<lambda>)rb   Úunionrj   r   )r   r*   r>   ZswitchedZnotswitchedZ	allstatesrO   r    r    r!   r     s    

zDetectKeySwitch._key_switchersc       	   
   C   sÌ   |   ||¡}|rÈx¶|jj ¡ D ]¦}t|j| jjƒs4q|j}| | j	¡j
||| jd}|tjk	r|d k	r| jjr~|stq|d }n|}t |¡}||kr| |d| j¡ t || j|| j| jj|| j¡ qW d S )N)rN   é    F)r   r–   Zidentity_mapZ
all_statesÚ
issubclassrV   r   r=   r&   r   Úgetr   r   ZPASSIVE_NO_RESULTr   rU   Zinstance_stater}   r   r   rŒ   r   r   )	r   ZdeplistrG   Z	switchersr(   Zdict_rg   Zrelated_objZrelated_stater    r    r!   rœ     s6    


z%DetectKeySwitch._process_key_switchesc             C   s    t |jƒot ||| j| jj¡S )N)rž   r   r   r   r   r   r   )r   rG   r(   r    r    r!   rj   Â  s    zDetectKeySwitch._pks_changedN)rl   rn   ro   Ú__doc__r+   r7   rF   rH   rI   rQ   rJ   rK   r   rœ   rj   r    r    r    r!   r‘   S  s   
%r‘   c               @   sT   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚManyToManyDPc          
   C   s:   |j  ||f||f||f||f||f||f||fg¡ d S )N)rs   rt   )r   r*   r3   r4   r5   r6   r1   r2   r    r    r!   r0   É  s    z&ManyToManyDP.per_property_dependenciesc	       	      C   sX   |s<|r"|j  ||f||fg¡ qT|j  ||f||fg¡ n|j  ||f||fg¡ d S )N)rs   rt   )	r   r*   rw   rx   rC   r1   r2   rA   rE   r    r    r!   r@   å  s    z#ManyToManyDP.per_state_dependenciesc             C   s*   | j s&x|D ]}| || j| j¡ qW d S )N)r   rL   r   r   )r   rG   r>   r(   r    r    r!   rH   þ  s    
zManyToManyDP.presort_deletesc       
      C   sÆ   | j s2x*|D ]"}|  ||¡r| || jtj¡}qW | jjs>d S x‚|D ]z}| || jtj¡}|rDx^|j	D ]T}|  
|¡dkrf|j|dd| jd x,| j d|¡D ]\}}}}	|j|dd qœW qfW qDW d S )NFTrz   )rA   r{   r   )rA   )r   rj   rL   r   r   r   r   r|   r   rD   r'   r}   r   r   rƒ   )
r   rG   r>   r(   rP   rB   r…   r†   r‡   rˆ   r    r    r!   rI   
  s*    


zManyToManyDP.presort_savesc          
      sÖ   g }g }g }|   |¡}tƒ }x’|D ]Š‰ | ˆ | j| j¡}|r"xR| ¡ D ]F}	|	d ksF|d k	rhˆ |	f|krhqFi }
|  ˆ |	|
d|d¡s‚qF| |
¡ qFW | ‡ fdd„| ¡ D ƒ¡ q"W |d k	rÂ| |¡ |  	||||¡ d S )NFrz   c             3   s   | ]}|ˆ fV  qd S )Nr    )r\   r…   )r(   r    r!   r›   K  s    z/ManyToManyDP.process_deletes.<locals>.<genexpr>)
rd   rc   rL   r   r   Z	non_addedr[   r?   rt   Ú	_run_crud)r   rG   r>   Úsecondary_deleteÚsecondary_insertÚsecondary_updateÚ	processedÚtmprP   rB   rY   r    )r(   r!   rJ   ,  s8    

 
zManyToManyDP.process_deletesc          
      s˜  g }g }g }|   |¡}tƒ }xP|D ]F‰ | j o<|  |ˆ ¡}|rJtj}	ntj}	| ˆ | j|	¡}
|
r$xH|
j	D ]>}|d k	r†ˆ |f|kr†qli }|  
ˆ ||d|d¡s ql| |¡ qlW xH|
jD ]>}|d k	rÐˆ |f|krÐq¶i }|  
ˆ ||d|d¡sêq¶| |¡ q¶W | ‡ fdd„|
j	|
j D ƒ¡ |r$xN|
jD ]D}i }t ˆ | j|d| jj¡ t || j|d| jj¡ | |¡ q$W q$W |d k	r„| |¡ |  ||||¡ d S )NFr   rz   c             3   s   | ]}|ˆ fV  qd S )Nr    )r\   r…   )r(   r    r!   r›   ~  s    z-ManyToManyDP.process_saves.<locals>.<genexpr>Úold_)rd   rc   r   rj   r   r   r   rL   r   r‚   r[   r?   rD   rt   r~   r   r   r   r   r   Úsecondary_synchronize_pairsr¨   )r   rG   r>   r©   rª   r«   r¬   r­   Zneed_cascade_pksrN   rP   rB   rY   r    )r(   r!   rK   T  sn    
 



zManyToManyDP.process_savesc                s  |j  | j¡}|r~|d ‰ | j tj‡ fdd„| jjD ƒŽ ¡}| ||¡}| 	¡ r~|j
t|ƒkr~t d| jjt|ƒ|j
f ¡‚|rî|d ‰ | j tj‡ fdd„| jjD ƒŽ ¡}| ||¡}| 	¡ rî|j
t|ƒkrît d| jjt|ƒ|j
f ¡‚|r
| j ¡ }| ||¡ d S )Nr£   c                s,   g | ]$}|j ˆ kr|tj|j |jd k‘qS ))Útype_)r   r   Ú	bindparamÚtype)r\   r…   )rY   r    r!   r^   ¦  s   z*ManyToManyDP._run_crud.<locals>.<listcomp>zRDELETE statement on table '%s' expected to delete %d row(s); Only %d were matched.c                s0   g | ](}|j ˆ kr|tjd |j  |jdk‘qS )r®   )r°   )r   r   r±   r²   )r\   r…   )rY   r    r!   r^   À  s   zRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)ZtransactionÚ
connectionr   r   rz   r   Úand_r…   ÚexecuteZsupports_sane_multi_rowcountZrowcountÚlenr   ZStaleDataErrorÚdescriptionrt   Úinsert)r   rG   rª   r«   r©   r³   Z	statementÚresultr    )rY   r!   r¨   œ  s@    


zManyToManyDP._run_crudc             C   s€   |   |¡ |d krdS |d k	rP|j |¡sP|jsLt dt |¡|| jf ¡ dS t	 
|| j|| jj¡ t	 
|| j|| jj¡ dS )NFzGObject of type %s not in session, %s operation along '%s' won't proceedT)rW   r–   r—   rD   r   r˜   r™   rš   r   r   Zpopulate_dictr   r   r   r¯   )r   r(   rB   rY   rZ   rG   r{   r    r    r!   r[   Ù  s"    

zManyToManyDP._synchronizec             C   s   t  ||| j| jj¡S )N)r   r   r   r   r   )r   rG   r(   r    r    r!   rj   ú  s    zManyToManyDP._pks_changedN)rl   rn   ro   r0   r@   rH   rI   rJ   rK   r¨   r[   rj   r    r    r    r!   r§   È  s   "(H=!r§   N)r¦   Ú r   r   r   r   r   r™   Z
interfacesr   r   r	   r   r   Úobjectr   rq   r   r‘   r§   r#   r    r    r    r!   Ú<module>
   s4     &  3 fu  ;