U
    ÌZj‹·  ã                   @   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| _d| jj|jf | _|j| _| j js²t d| j  ¡‚d S )Nz%s_%sz|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Ú	_sort_keyÚkeyÚsort_keyÚsynchronize_pairsÚsa_excÚArgumentError)Úselfr   © r"   ú\/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/sqlalchemy/orm/dependency.pyÚ__init__   s0    

þÿzDependencyProcessor.__init__c                 C   s   t |j |ƒS ©N)Ú_direction_to_processorr   )Úclsr   r"   r"   r#   Úfrom_relationship7   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_preprocessorsC   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_actionsL   s6     ÿ ÿ ÿ ÿù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}|D �]}|j| j j ||j|rþ| jntj¡}|�sqÚ|�r8t || d|¡}|�rZt ||¡}n"t || d|¡}|�rZt ||¡}|
�rÆg }	|D ]\\}}||jk�r‚d}n6|j| \}}|�r¨t ||¡df}nt ||¡df}|	 |¡ �qh|	D ]"\}}|  ||||||||¡ �qÊqÚ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   r4   r   r3   r5   r2   ÚdisabledZcyclesÚAssertionErrorr   Úbase_mapperÚmanagerr   ÚimplZget_all_pendingÚdictr   r   r   ZProcessStateZDeleteStateZSaveUpdateStateÚstatesÚappendÚper_state_dependencies)r!   r/   rD   ÚisdeleteZchild_base_mapperr:   r<   r8   r7   Zchild_actionsZchild_in_cyclesr9   r;   Zparent_in_cyclesr,   Zsum_Zchild_stateÚchildÚchild_actionÚdeletedZlistonlyÚchildisdeleter"   r"   r#   Úper_state_flush_actionsh   s†    	
 ÿ


ÿû
þ
þøz+DependencyProcessor.per_state_flush_actionsc                 C   s   dS ©NFr"   ©r!   Ú	uowcommitrD   r"   r"   r#   Úpresort_deletesØ   s    z#DependencyProcessor.presort_deletesc                 C   s   dS rM   r"   rN   r"   r"   r#   Úpresort_savesÛ   s    z!DependencyProcessor.presort_savesc                 C   s   d S r%   r"   rN   r"   r"   r#   Úprocess_deletesÞ   s    z#DependencyProcessor.process_deletesc                 C   s   d S r%   r"   rN   r"   r"   r#   Úprocess_savesá   s    z!DependencyProcessor.process_savesc                 C   sp   |r
| j rtj}n| jtkr$tj}ntj}|D ]&}| || j|¡}|r.| 	¡ s. dS q.|on| j
j on| j|jkS )NT)r   r   r   r   r   ZPASSIVE_NO_FETCH_RELATEDr   Úget_attribute_historyr   Úemptyr   Z_is_self_referentialr   Zmappers)r!   rO   rD   rG   Ú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.)rZ   r[   r\   )r   Úuselistr   Z
FlushErrorr   Z_canloadr   Úclass_r+   r"   r"   r#   Ú_verify_canloadÿ   s8    ÿÿ ÿ
ü÷ÿýûÿz#DependencyProcessor._verify_canloadc                 C   s
   t ƒ ‚d S r%   ©ÚNotImplementedError)r!   r,   rH   ÚassociationrowÚ	clearkeysrO   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>0  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   s8   |D ].}|r|d k	r|  |dd„ | jjD ƒ¡  q4qd S )Nc                 S   s   g | ]\}}|‘qS r"   r"   )re   ÚlÚrr"   r"   r#   rg   8  s     z4DependencyProcessor._post_update.<locals>.<listcomp>)Zregister_post_updater   r   )r!   r,   rO   ÚrelatedÚis_m2o_deleterZ   r"   r"   r#   Ú_post_update4  s     ÿz DependencyProcessor._post_updatec                 C   s
   t ƒ ‚d S r%   r`   ©r!   rO   r,   r"   r"   r#   Ú_pks_changed<  s    z DependencyProcessor._pks_changedc                 C   s   d| j j| jf S )Nz%s(%s))Ú	__class__Ú__name__r   )r!   r"   r"   r#   Ú__repr__?  s    zDependencyProcessor.__repr__N)F)rv   Ú
__module__Ú__qualname__r$   Úclassmethodr(   r*   r0   r=   rL   rP   rQ   rR   rS   rY   r_   rd   rm   rr   rt   rw   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 r1   ©r   r   ÚPostUpdateAllr   r4   ÚdependenciesÚupdate)
r!   r/   r9   r:   r;   r<   r7   r8   Úchild_post_updatesÚchild_pre_updatesr"   r"   r#   r6   D  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 r1   r|   )r!   r/   Úsave_parentÚdelete_parentrI   r7   r8   rG   rK   r€   r�   r"   r"   r#   rF   m  sZ      ÿ  ÿþÿýÿþÿþÿýÿÿz"OneToManyDP.per_state_dependenciesc                 C   s¨   | j j o| jdk }|D ]ˆ}| || j| j¡}|r|jD ]<}|d k	r:|  |¡dkr:| j jrl|j	|dd� q:| 	|¡ q:|r|j
D ]}|d k	r‚|j	|d| jd� q‚qd S )NÚallFT©rG   Údelete©Ú	operationr   )r   r†   r   rT   r   r   rJ   r*   Údelete_orphanÚregister_objectÚ	unchangedr   ©r!   rO   rD   Úshould_null_fksr,   rX   rH   r"   r"   r#   rP   °  s,    ÿ  ÿ

  ÿzOneToManyDP.presort_deletesc              	   C   sV  |  d| ft¡}| jj o$| jdk }|D �]$}|  ||¡}|rF| jrNtj}ntj	}| 
|| j|¡}|�r|jD ] }	|	d k	rp|j|	dd| jd� qp| |j¡ |jD ]r}	| jjsÊ|rÈ|j|	dd| jd� q¤|  |	¡dkr¤|j|	dd| jd� | j d|	¡D ]\}
}}}|j|dd	� qúq¤|r*|r*|jD ](}	|	d k	�r&|j|	d| jd
| jd� �q&q*d S )NÚchildren_addedr„   TÚadd)Zcancel_deleterˆ   r   Fr†   ©rG   rˆ   r   r…   z	pk changer‡   )rk   rl   r   r‰   r   rt   r   r   r   r   rT   r   ÚaddedrŠ   r   r   rJ   r*   r   Úcascade_iteratorr‹   )r!   rO   rD   rŽ   r�   r,   Úpks_changedrV   rX   rH   ÚcÚmÚst_Údct_r"   r"   r#   rQ   Ë  sh    

þ


ü
üü ÿ

ûzOneToManyDP.presort_savesc              
   C   sî   | j s| jdksê| d| ft¡}|D ]Ä}| || j| j¡}|r$|jD ]H}|d k	rD|  |¡dkrD|  	||d d|d¡ | j rD|rD|  
|||g¡ qD| j sœ| jjs$t|jƒ |¡D ]:}|d k	r¬|  	||d d|d¡ | j r¬|r¬|  
|||g¡ q¬q$d S )Nr„   rŽ   FT)r   r   rk   rl   rT   r   r   rJ   r*   rd   rr   r   r†   r‹   Ú
difference)r!   rO   rD   rŽ   r,   rX   rH   r"   r"   r#   rR   	  sV      ÿ
ÿþ     ÿ

ÿ     ÿ
  ÿzOneToManyDP.process_deletesc              
   C   sÚ   | j j o| jdk }|D ]º}| || jtj¡}|r|jD ]6}|  ||d d|d¡ |d k	r:| j	r:|  
|||g¡ q:|jD ].}|rx| j jsx|  |¡sx|  ||d d|d¡ qx|  ||¡r|jD ]}|  ||d d|d¡ qºqd S )Nr„   FT)r   r‰   r   rT   r   r   r   r‘   rd   r   rr   rJ   r*   rt   r‹   rŒ   r"   r"   r#   rS   5  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 r%   )r_   r   Ú
is_deletedr   Úclearr   r   r   Úpopulater   r   )	r!   r,   rH   rb   rc   rO   r“   ÚsourceÚdestr"   r"   r#   rd   W  s(    
ÿÿùzOneToManyDP._synchronizec                 C   s   t  ||| j| jj¡S r%   ©r   Úsource_modifiedr   r   r   rs   r"   r"   r#   rt   n  s       ÿzOneToManyDP._pks_changedN)rv   rx   ry   r6   rF   rP   rQ   rR   rS   rd   rt   r"   r"   r"   r#   r{   C  s   )C>,"r{   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   s.   t  | |¡ | jjD ]}|j t|ƒ¡ qd S r%   )r   r$   r   Zself_and_descendantsZ_dependency_processorsrE   ÚDetectKeySwitch)r!   r   r   r"   r"   r#   r$   u  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 r1   ©r   r   r}   r   r4   r~   r   )
r!   r/   r9   r:   r;   r<   r7   r8   Úparent_post_updatesÚparent_pre_updatesr"   r"   r#   r6   z  s8      ÿ  ÿùÿüÿ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 r1   r¢   )r!   r/   r‚   rƒ   rI   r7   r8   rG   rK   r£   r¤   r"   r"   r#   rF   ¢  sL      ÿþÿýÿ  ÿýÿÿz"ManyToOneDP.per_state_dependenciesc                 C   s¤   | j js| j jr |D ]Š}| || j| j¡}|r| j jr@| ¡ }n| ¡ }|D ]P}|d krZqL|j|dd| j	d� | j
 d|¡}|D ]\}}	}
}|j|
dd� q€qLqd S )NTr†   r�   r…   )r   r†   r‰   rT   r   r   ÚsumZnon_deletedrŠ   r   r   r’   )r!   rO   rD   r,   rX   ZtodeleterH   Útr”   r•   r–   r—   r"   r"   r#   rP   Ü  s.      ÿ
üzManyToOneDP.presort_deletesc                 C   sš   |D ]�}|j |d| jd� | jjr| || j| j¡}|r|jD ]T}|  |¡dkr>|j |dd| jd� | j	 
d|¡}|D ]\}}}	}
|j |	dd� qvq>qd S )Nr�   r‡   FTr†   r�   r…   )rŠ   r   r   r‰   rT   r   r   rJ   r*   r   r’   )r!   rO   rD   r,   rX   rH   r¦   r”   r•   r–   r—   r"   r"   r#   rQ   ô  s(      ÿ
üzManyToOneDP.presort_savesc                 C   sn   | j rj| jjsj| jdksj|D ]L}|  |d d d|¡ |r| j r| || j| j¡}|r| j||| 	¡ dd� qd S )Nr„   T)rq   )
r   r   r‰   r   rd   rT   r   r   rr   r¥   )r!   rO   rD   r,   rX   r"   r"   r#   rR   	  s*    ÿþý	
  ÿ   ÿzManyToOneDP.process_deletesc              
   C   s~   |D ]t}|  || jtj¡}|r|jrF|jD ]}|  ||d d|d¡ q*n|jr`|  |d d d|d¡ | jr|  ||| 	¡ ¡ qd S )NFr�   Tr†   )
rT   r   r   r   r‘   rd   rJ   r   rr   r¥   )r!   rO   rD   r,   rX   rH   r"   r"   r#   rS     s8      ÿ
     ÿ     ÿ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 )NúGObject 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   r_   r›   r   ©r!   r,   rH   rb   rc   rO   rˆ   r"   r"   r#   rd   0  s<    	ÿÿÿþ
ýþÿ
ùzManyToOneDP._synchronize)N)rv   rx   ry   r$   r6   rF   rP   rQ   rR   rS   rd   r"   r"   r"   r#   r    t  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 r%   )r   )re   r   r"   r"   r#   Ú	<genexpr>j  s   ÿz=DetectKeySwitch.per_property_preprocessors.<locals>.<genexpr>)r   rh   r   r-   r.   r"   r"   r#   r0   e  s    þz*DetectKeySwitch.per_property_preprocessorsc                 C   s6   t  || jj¡}t  || dd¡}|j ||fg¡ d S rM   )r   r3   r   r@   r2   r~   r   )r!   r/   r9   r7   r"   r"   r#   r=   r  s    z*DetectKeySwitch.per_property_flush_actionsc                 C   s   d S r%   r"   )r!   r/   rD   rG   r"   r"   r#   rL   w  s    z'DetectKeySwitch.per_state_flush_actionsc                 C   s   d S r%   r"   rN   r"   r"   r#   rP   z  s    zDetectKeySwitch.presort_deletesc                 C   s   | j s|  ||¡ d S r%   )r   Ú_process_key_switches)r!   r/   rD   r"   r"   r#   rQ   }  s    zDetectKeySwitch.presort_savesc                 C   s"   |s| j r|  ||¡}t|ƒS dS rM   )r   Ú_key_switchersÚbool)r!   r/   rD   rG   Údr"   r"   r#   rY   ƒ  s    
z DetectKeySwitch.prop_has_changesc                 C   s   dst ‚d S rM   )r?   rN   r"   r"   r#   rR   Š  s    zDetectKeySwitch.process_deletesc                 C   s   | j s
t‚|  ||¡ d S r%   )r   r?   r¯   rN   r"   r"   r#   rS   �  s    
zDetectKeySwitch.process_savesc                 C   sZ   |  d| fdd„ ¡\}}| |¡}|D ].}||kr&|  ||¡rJ| |¡ q&| |¡ q&|S )NZpk_switchersc                   S   s   t ƒ t ƒ fS r%   )rl   r"   r"   r"   r#   Ú<lambda>—  ó    z0DetectKeySwitch._key_switchers.<locals>.<lambda>)rk   Úunionrt   r�   )r!   r/   rD   ZswitchedZnotswitchedZ	allstatesrW   r"   r"   r#   r°   •  s     ÿ
zDetectKeySwitch._key_switchersc           	   
   C   sÈ   |   ||¡}|rÄ|jj ¡ D ]¦}t|j| jjƒs2q|j}| | j	¡j
||| jd�}|tjk	r|d k	r| jjr||srq|d }n|}t |¡}||kr| |d| j¡ t || j|| j| jj|| j¡ qd S )N)rV   é    F)r°   r¨   Zidentity_mapZ
all_statesÚ
issubclassr^   r   rC   r)   r   Úgetr   r   ZPASSIVE_NO_RESULTr   r]   Zinstance_staterŠ   r   r   r›   r   r   )	r!   ZdeplistrO   Z	switchersr,   Zdict_rp   Zrelated_objZrelated_stater"   r"   r#   r¯   £  sH      ÿÿþ

  ÿùz%DetectKeySwitch._process_key_switchesc                 C   s    t |jƒot ||| j| jj¡S r%   )r±   r   r   rŸ   r   r   r   rs   r"   r"   r#   rt   È  s       ÿzDetectKeySwitch._pks_changedN)rv   rx   ry   Ú__doc__r0   r=   rL   rP   rQ   rY   rR   rS   r°   r¯   rt   r"   r"   r"   r#   r¡   Y  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 r%   ©r~   r   )r!   r/   r9   r:   r;   r<   r7   r8   r"   r"   r#   r6   Ï  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 r%   r»   )	r!   r/   r‚   rƒ   rI   r7   r8   rG   rK   r"   r"   r#   rF   ë  s    ÿÿÿz#ManyToManyDP.per_state_dependenciesc                 C   s&   | j s"|D ]}| || j| j¡ q
d S r%   )r   rT   r   r   )r!   rO   rD   r,   r"   r"   r#   rP     s      ÿzManyToManyDP.presort_deletesc           
      C   s¶   | j s.|D ]"}|  ||¡r
| || jtj¡}q
| jjs:d S |D ]r}| || jtj¡}|r>|j	D ]P}|  
|¡dkr^|j|dd| jd� | j d|¡D ]\}}}}	|j|dd� q’q^q>d S )NFTr†   r�   r…   )r   rt   rT   r   r   r   r   r‰   r   rJ   r*   rŠ   r   r   r’   )
r!   rO   rD   r,   rX   rH   r”   r•   r–   r—   r"   r"   r#   rQ     s<      ÿ  ÿ
ü ÿzManyToManyDP.presort_savesc              
      sÎ   g }g }g }|   |¡}tƒ }|D ]†‰ | ˆ | j| j¡}|r | ¡ D ]F}	|	d ksB|d k	rdˆ |	f|krdqBi }
|  ˆ |	|
d|d¡s~qB| |
¡ qB| ‡ fdd„| ¡ D ƒ¡ q |d k	rº| |¡ |  	||||¡ d S )NFr†   c                 3   s   | ]}|ˆ fV  qd S r%   r"   ©re   r”   ©r,   r"   r#   r®   Q  s     z/ManyToManyDP.process_deletes.<locals>.<genexpr>)
rm   rl   rT   r   r   Z	non_addedrd   rE   r   Ú	_run_crud)r!   rO   rD   Úsecondary_deleteÚsecondary_insertÚsecondary_updateÚ	processedÚtmprX   rH   rb   r"   r½   r#   rR   2  sN    
  ÿÿ
ÿú
   ÿzManyToManyDP.process_deletesc              
      s†  g }g }g }|   |¡}tƒ }|D �]:‰ | j o8|  |ˆ ¡}|rFtj}	ntj}	| ˆ | j|	¡}
|
r |
j	D ]>}|d k	r€ˆ |f|kr€qfi }|  
ˆ ||d|d¡sšqf| |¡ qf|
jD ]>}|d k	rÆˆ |f|krÆq¬i }|  
ˆ ||d|d¡sàq¬| |¡ q¬| ‡ fdd„|
j	|
j D ƒ¡ |r |
jD ]D}i }t ˆ | j|d| jj¡ t || j|d| jj¡ | |¡ �qq |d k	�rr| |¡ |  ||||¡ d S )NFr�   r†   c                 3   s   | ]}|ˆ fV  qd S r%   r"   r¼   r½   r"   r#   r®   „  s     z-ManyToManyDP.process_saves.<locals>.<genexpr>Úold_)rm   rl   r   rt   r   r   r   rT   r   r‘   rd   rE   rJ   r   r‹   r   r   r   r   r   Úsecondary_synchronize_pairsr¾   )r!   rO   rD   r¿   rÀ   rÁ   rÂ   rÃ   Zneed_cascade_pksrV   rX   rH   rb   r"   r½   r#   rS   Z  sŒ    

 ÿ
     ÿ
ú 
ûû

   ÿ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   Z	bindparamÚtyper¼   ©rb   r"   r#   rg   «  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#   rg   Å  s   
þzRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)ZtransactionÚ
connectionr   r   r†   Úwherer   Úand_r”   ÚexecuteZsupports_sane_multi_rowcountZrowcountÚlenr   ZStaleDataErrorÚdescriptionr   Úinsert)r!   rO   rÀ   rÁ   r¿   rË   Z	statementÚresultr"   rÊ   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 )NFr§   T)r_   r¨   r©   rJ   r   rª   r«   r¬   r   r   Zpopulate_dictr   r   r   rÅ   r­   r"   r"   r#   rd   ß  s0    
þÿ   ÿüzManyToManyDP._synchronizec                 C   s   t  ||| j| jj¡S r%   rž   rs   r"   r"   r#   rt      s       ÿzManyToManyDP._pks_changedN)rv   rx   ry   r6   rF   rP   rQ   rR   rS   r¾   rd   rt   r"   r"   r"   r#   rº   Î  s   "(H=!rº   N)r¹   Ú r   r   r   r   r   r«   Z
interfacesr   r   r	   r   r   Úobjectr   r{   r    r¡   rº   r&   r"   r"   r"   r#   Ú<module>   s<     ,  3 fu  ;   ý