o
    Šågº  ã                   @  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 ddlmZ G dd„ dƒ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.

é    )Úannotationsé   )Ú
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r;t
j| _nt
j| _d| jj|jf | _|j| _| j jsYt 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$   úU/var/www/html/flaskapp/venv/lib/python3.10/site-packages/sqlalchemy/orm/dependency.pyÚ__init__   s2   

þÿÿzDependencyProcessor.__init__c                 C  s   t |j |ƒS ©N)Ú_direction_to_processorr   )Úclsr   r$   r$   r%   Úfrom_relationship;   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   Ú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_preprocessorsG   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#   r2   Ú
after_saveÚbefore_deleteÚparent_savesÚchild_savesÚparent_deletesÚchild_deletesr$   r$   r%   Úper_property_flush_actionsP   s.   ÿÿÿÿùz.DependencyProcessor.per_property_flush_actionsc                 C  sà  | j j}t ||¡}t ||¡}|rt || dd¡}d|_nt || dd¡}d|_||jvr@||jvs5J ‚|df|dfg}	d}
nd}
|sXt || jj	¡}d }}||jv rWd}nt || jj	¡}d }}||jv rkd}|D ]€}|j
| j j ||j|r~| jntj¡}|s…qm|r˜t || d|¡}|r—t ||¡}nt || d|¡}|r¨t ||¡}|
rÚg }	|D ]+\}}||jvrºd}n|j| \}}|rÌt ||¡df}nt ||¡df}|	 |¡ q®|	D ]\}}|  ||||||||¡ qÜqmd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   r7   r   r6   r8   r5   ÚdisabledÚcyclesr   Úbase_mapperÚmanagerr   ÚimplÚget_all_pendingÚdictr   r   r   ÚProcessStateÚDeleteStateÚSaveUpdateStateÚstatesÚappendÚper_state_dependencies)r#   r2   rK   ÚisdeleteÚchild_base_mapperr=   r?   r;   r:   Úchild_actionsÚchild_in_cyclesr<   r>   Úparent_in_cyclesr/   Úsum_Úchild_stateÚchildÚchild_actionÚdeletedÚlistonlyÚchildisdeleter$   r$   r%   Úper_state_flush_actionsl   sŒ   	
ÿ
€
ÿú
€

þ
þøÿÑz+DependencyProcessor.per_state_flush_actionsc                 C  ó   dS ©NFr$   ©r#   Ú	uowcommitrK   r$   r$   r%   Úpresort_deletesÞ   ó   z#DependencyProcessor.presort_deletesc                 C  r[   r\   r$   r]   r$   r$   r%   Úpresort_savesá   r`   z!DependencyProcessor.presort_savesc                 C  ó   d S r'   r$   r]   r$   r$   r%   Úprocess_deletesä   r`   z#DependencyProcessor.process_deletesc                 C  rb   r'   r$   r]   r$   r$   r%   Úprocess_savesç   r`   z!DependencyProcessor.process_savesc                 C  s|   |r| j rtjtjB }n| jtu rtj}ntjtjB }|D ]}| || j	|¡}|r0| 
¡ s0 dS q|o=| jj o=| j|jv S )NT)r   r   r   ÚINCLUDE_PENDING_MUTATIONSr   r
   ÚPASSIVE_NO_FETCH_RELATEDr   Úget_attribute_historyr   Úemptyr   Ú_is_self_referentialr   Úmappers)r#   r^   rK   rN   ÚpassiveÚsÚhistoryr$   r$   r%   Úprop_has_changesê   s&   
ÿÿ

ÿ€ÿ
ýz$DependencyProcessor.prop_has_changesc                 C  s–   | j jr|d u rt d| j f ¡‚|d urG| jj|| j d�sI| jj|dd�r8t d|j| j | jj| jdœ ¡‚t d|j| j | jjdœ ¡‚d S d S )Nz-Can't flush None value found in collection %s)Ú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ÚzÚ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.)rp   rq   rr   )r   Úuselistr   Ú
FlushErrorr   Ú_canloadr   Úclass_r.   r$   r$   r%   Ú_verify_canload
  s8   ÿÿÿ
ü÷ÿýûÿêz#DependencyProcessor._verify_canloadc                 C  ó   t ƒ ‚r'   ©ÚNotImplementedError)r#   r/   rU   ÚassociationrowÚ	clearkeysr^   r$   r$   r%   Ú_synchronize3  ó   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>Úreverse_key)r   Ú_reverse_propertyÚtupleÚsortedr   ÚmemoÚset)r#   r2   Úprocess_keyr$   r$   r%   Ú_get_reversed_processed_set6  s   ÿz/DependencyProcessor._get_reversed_processed_setFc                 C  s:   |D ]}|r
|d ur|  |dd„ | jjD ƒ¡  d S qd S )Nc                 S  s   g | ]\}}|‘qS r$   r$   )r€   ÚlÚrr$   r$   r%   r‚   C  s    z4DependencyProcessor._post_update.<locals>.<listcomp>)Úregister_post_updater   r    )r#   r/   r^   ÚrelatedÚis_m2o_deleterp   r$   r$   r%   Ú_post_update?  s   ÿüÿz DependencyProcessor._post_updatec                 C  ry   r'   rz   ©r#   r^   r/   r$   r$   r%   Ú_pks_changedG  r   z DependencyProcessor._pks_changedc                 C  s   d| j j| jf S )Nz%s(%s))Ú	__class__Ú__name__r   )r#   r$   r$   r%   Ú__repr__J  s   zDependencyProcessor.__repr__N)F)r”   Ú
__module__Ú__qualname__r&   Úclassmethodr*   r-   r3   r@   rZ   r_   ra   rc   rd   rn   rx   r~   rŠ   r�   r’   r•   r$   r$   r$   r%   r      s&    
	r )
	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¡ d S |j ||f||f||f||f||f||f||fg¡ d S r4   ©r   r   ÚPostUpdateAllr   r7   ÚdependenciesÚupdate)
r#   r2   r<   r=   r>   r?   r:   r;   Úchild_post_updatesÚchild_pre_updatesr$   r$   r%   r9   O  s4   

ÿ
ÿúÿùÿz%OneToManyDP.per_property_dependenciesc	                 C  sî   | j rVt || jjd¡}	t || jjd¡}
|s8|r'|j ||f||	fg¡ d S |j ||f||f||	fg¡ d S |rH|j ||
f|
|fg¡ d S |j ||
f|
|fg¡ d S |si|j ||f||f||fg¡ d S |j ||f||fg¡ d S r4   rš   )r#   r2   Úsave_parentÚdelete_parentrV   r:   r;   rN   rY   rž   rŸ   r$   r$   r%   rM   x  sR   
ÿ
ÿþÿýÿþÿþÿýÿÿz"OneToManyDP.per_state_dependenciesc                 C  s¨   | j j o
| jdk }|D ]D}| || j| j¡}|rQ|jD ]}|d ur;|  |¡du r;| j jr6|j	|dd� q| 	|¡ q|rQ|j
D ]}|d urP|j	|d| jd� qAqd S )NÚallFT©rN   Údelete©Ú	operationr   )r   r¤   r   rg   r   r   rW   r-   Údelete_orphanÚregister_objectÚ	unchangedr   ©r#   r^   rK   Úshould_null_fksr/   rm   rU   r$   r$   r%   r_   ¹  s*   ÿ
ÿ

€
ÿ€ñzOneToManyDP.presort_deletesc              	   C  sZ  |  d| ft¡}| jj o| jdk }|D ]•}|  ||¡}|r"| jr)tjtj	B }ntj
tj	B }| || j|¡}|r�|jD ]}	|	d urL|j|	dd| jd� q<| |j¡ |jD ]9}	| jjsi|rh|j|	dd| jd� qV|  |	¡du r�|j|	dd| jd� | j d|	¡D ]\}
}}}|j|dd	� q�qV|rª|rª|jD ]}	|	d ur©|j|	d| jd
| jd� q—qd S )NÚchildren_addedr¢   TÚadd)Úcancel_deleter¦   r   Fr¤   ©rN   r¦   r   r£   z	pk changer¥   )r‡   rˆ   r   r§   r   r’   r   r   r   re   r   rg   r   Úaddedr¨   r   r�   rW   r-   r   Úcascade_iteratorr©   )r#   r^   rK   r¬   r«   r/   Úpks_changedrk   rm   rU   ÚcÚmÚst_Údct_r$   r$   r%   ra   Ô  s|   

þ
ÿÿÿÿ
ü€
ü€üÿ€
û€ÌzOneToManyDP.presort_savesc              
   C  sò   | j s| jdksu| d| ft¡}|D ]d}| || j| j¡}|rt|jD ]$}|d urF|  |¡du rF|  	||d d|d¡ | j rF|rF|  
|||g¡ q"| j sN| jjstt|jƒ |¡D ]}|d urs|  	||d d|d¡ | j rs|rs|  
|||g¡ qVqd S d S )Nr¢   r¬   FT)r   r   r‡   rˆ   rg   r   r   rW   r-   r~   r�   r   r¤   r©   Ú
difference)r#   r^   rK   r¬   r/   rm   rU   r$   r$   r%   rc     s>   
ÿ
ÿ
€
ÿÿ
ÿ€äzOneToManyDP.process_deletesc              
   C  sÚ   | j j o
| jdk }|D ]]}| || jtj¡}|rj|jD ]}|  ||d d|d¡ |d ur8| j	r8|  
|||g¡ q|jD ]}|rS| j jsS|  |¡sS|  ||d d|d¡ q<|  ||¡rj|jD ]}|  ||d d|d¡ q]qd S )Nr¢   FT)r   r§   r   rg   r   r   r   r°   r~   r   r�   rW   r-   r’   r©   rª   r$   r$   r%   rd   D  sB   

þ
ÿ
ÿ€
ÿþýÿ€
ÿ€èzOneToManyDP.process_savesc           	   	   C  sr   |}|}|   |¡ |d u s| js| |¡rd S |r%t || j| jj¡ d S t || j	|| j| jj|| j
o5|¡ d S r'   )rx   r   Ú
is_deletedr   Úclearr   r   r    Úpopulater   r   )	r#   r/   rU   r|   r}   r^   r²   ÚsourceÚdestr$   r$   r%   r~   f  s(   
ÿÿùzOneToManyDP._synchronizec                 C  ó   t  ||| j| jj¡S r'   ©r   Úsource_modifiedr   r   r    r‘   r$   r$   r%   r’   }  ó   ÿzOneToManyDP._pks_changedN)r”   r–   r—   r9   rM   r_   ra   rc   rd   r~   r’   r$   r$   r$   r%   r™   N  s    )AD,"r™   c                   @  sP   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   Úself_and_descendantsÚ_dependency_processorsrL   ÚDetectKeySwitch)r#   r   r   r$   r$   r%   r&   „  s   ÿzManyToOneDP.__init__c           
   
   C  sŒ   | j r2t || jjd¡}t || jjd¡}	|j ||f||f||f||	f||	f|	|f|	|fg¡ d S |j ||f||f||f||fg¡ d S r4   ©r   r   r›   r   r7   rœ   r�   )
r#   r2   r<   r=   r>   r?   r:   r;   Úparent_post_updatesÚparent_pre_updatesr$   r$   r%   r9   ‰  s0   

ÿ
ÿùÿüÿz%ManyToOneDP.per_property_dependenciesc	                 C  sê   | j rI|s/t || jjd¡}	|r|j ||	f|	|fg¡ d S |j ||f||f||	fg¡ d S t || jjd¡}
|j ||
f|
|f|
|fg¡ d S |sf|s[|j ||f||fg¡ d S |j ||fg¡ d S |rs|j ||fg¡ d S d S r4   rÅ   )r#   r2   r    r¡   rV   r:   r;   rN   rY   rÆ   rÇ   r$   r$   r%   rM   °  sF   
ÿþÿýÿ
ÿýÿÿÿz"ManyToOneDP.per_state_dependenciesc                 C  s¨   | j js| j jrP|D ]G}| || j| j¡}|rO| j jr | ¡ }n| ¡ }|D ](}|d u r-q&|j|dd| j	d� | j
 d|¡}|D ]\}}	}
}|j|
dd� q@q&q
d S d S )NTr¤   r¯   r£   )r   r¤   r§   rg   r   r   ÚsumÚnon_deletedr¨   r   r   r±   )r#   r^   rK   r/   rm   ÚtodeleterU   Útr³   r´   rµ   r¶   r$   r$   r%   r_   è  s2   
ÿ
üÿ€ìzManyToOneDP.presort_deletesc                 C  sš   |D ]H}|j |d| jd� | jjrJ| || j| j¡}|rJ|jD ]*}|  |¡du rI|j |dd| jd� | j	 
d|¡}|D ]\}}}	}
|j |	dd� q;qqd S )Nr­   r¥   FTr¤   r¯   r£   )r¨   r   r   r§   rg   r   r   rW   r-   r   r±   )r#   r^   rK   r/   rm   rU   rË   r³   r´   rµ   r¶   r$   r$   r%   ra      s(   
ÿ
ü€îzManyToOneDP.presort_savesc                 C  sz   | j r5| jjs7| jdks9|D ],}|  |d d d|¡ |r4| j r4| || j| j¡}|r4| j||| 	¡ dd� qd S d S d S d S )Nr¢   T)r�   )
r   r   r§   r   r~   rg   r   r   r�   rÈ   )r#   r^   rK   r/   rm   r$   r$   r%   rc     s&   ÿþ


ÿÿ€ñzManyToOneDP.process_deletesc              
   C  s~   |D ]:}|  || jtj¡}|r<|jr#|jD ]}|  ||d d|d¡ qn|jr0|  |d d d|d¡ | jr<|  ||| 	¡ ¡ qd S )NFr­   Tr¤   )
rg   r   r   r   r°   r~   rW   r   r�   rÈ   )r#   r^   rK   r/   rm   rU   r$   r$   r%   rd   )  s&   
ÿ
ÿÿÿ€ñzManyToOneDP.process_savesNc              	   C  s¨   |d u s| j s| |¡rd S |d ur,|d ur,|j |¡s,t dt |¡|| jf ¡ d S |s2|d u r>t	 
|| j| jj¡ d S |  |¡ 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    rx   rº   r   ©r#   r/   rU   r|   r}   r^   r¦   r$   r$   r%   r~   ;  s8   	ÿÿ
ÿþÿ
ùzManyToOneDP._synchronizer'   )r”   r–   r—   r&   r9   rM   r_   ra   rc   rd   r~   r$   r$   r$   r%   rÁ   ƒ  s    '8ù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 ƒv rd S | | d¡ d S )NFc                 s  s   � | ]}|j V  qd S r'   )r   )r€   r   r$   r$   r%   Ú	<genexpr>u  s
   € ÿ
ÿz=DetectKeySwitch.per_property_preprocessors.<locals>.<genexpr>)r   r„   r   r0   r1   r$   r$   r%   r3   p  s   þz*DetectKeySwitch.per_property_preprocessorsc                 C  s6   t  || jj¡}t  || dd¡}|j ||fg¡ d S r\   )r   r6   r   rC   r5   rœ   r�   )r#   r2   r<   r:   r$   r$   r%   r@   }  s   z*DetectKeySwitch.per_property_flush_actionsc                 C  rb   r'   r$   )r#   r2   rK   rN   r$   r$   r%   rZ   ‚  r`   z'DetectKeySwitch.per_state_flush_actionsc                 C  rb   r'   r$   r]   r$   r$   r%   r_   …  r`   zDetectKeySwitch.presort_deletesc                 C  s   | j s|  ||¡ d S d S r'   ©r   Ú_process_key_switches)r#   r2   rK   r$   r$   r%   ra   ˆ  s   ýzDetectKeySwitch.presort_savesc                 C  s"   |s| j r|  ||¡}t|ƒS dS r\   )r   Ú_key_switchersÚbool)r#   r2   rK   rN   Údr$   r$   r%   rn   Ž  s   
z DetectKeySwitch.prop_has_changesc                 C  s   J ‚r'   r$   r]   r$   r$   r%   rc   •  r`   zDetectKeySwitch.process_deletesc                 C  s   | j sJ ‚|  ||¡ d S r'   rÔ   r]   r$   r$   r%   rd   ˜  s   
zDetectKeySwitch.process_savesc                 C  sZ   |  d| fdd„ ¡\}}| |¡}|D ]}||vr*|  ||¡r%| |¡ q| |¡ q|S )NÚpk_switchersc                   S  s   t ƒ t ƒ fS r'   )rˆ   r$   r$   r$   r%   Ú<lambda>¢  s    z0DetectKeySwitch._key_switchers.<locals>.<lambda>)r‡   Úunionr’   r­   )r#   r2   rK   ÚswitchedÚnotswitchedÚ	allstatesrl   r$   r$   r%   rÖ      s   ÿ

€zDetectKeySwitch._key_switchersc           	   
   C  sÌ   |   ||¡}|rb|jj ¡ D ]U}t|j| jjƒsq|j}| | j	¡j
||| jd�}|tjura|d ura| jjr>|s9q|d }n|}t |¡}||v ra| |d| j¡ t || j|| j| jj|| j¡ qd S d S )N)rk   r   F)rÖ   rÍ   Úidentity_mapÚ
all_statesÚ
issubclassrw   r   rG   r,   r   Úgetr   r   ÚPASSIVE_NO_RESULTr   rt   Úinstance_stater¨   r   r   rº   r   r    )	r#   Údeplistr^   Ú	switchersr/   Údict_rŽ   Úrelated_objÚrelated_stater$   r$   r%   rÕ   ®  sB   ÿ


ÿù€çz%DetectKeySwitch._process_key_switchesc                 C  s    t |jƒot ||| j| jj¡S r'   )r×   r   r   r¿   r   r   r    r‘   r$   r$   r%   r’   Ó  s   ÿzDetectKeySwitch._pks_changedN)r”   r–   r—   Ú__doc__r3   r@   rZ   r_   ra   rn   rc   rd   rÖ   rÕ   r’   r$   r$   r$   r%   rÄ   d  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#   r2   r<   r=   r>   r?   r:   r;   r$   r$   r%   r9   Ú  s   
ôÿz&ManyToManyDP.per_property_dependenciesc	           	      C  s\   |s |r|j  ||f||fg¡ d S |j  ||f||fg¡ d S |j  ||f||fg¡ d S r'   rì   )	r#   r2   r    r¡   rV   r:   r;   rN   rY   r$   r$   r%   rM   õ  s   ÿÿÿz#ManyToManyDP.per_state_dependenciesc                 C  s*   | j s|D ]}| || j| j¡ qd S d S r'   )r   rg   r   r   )r#   r^   rK   r/   r$   r$   r%   r_     s   
ÿûzManyToManyDP.presort_deletesc           
      C  s¶   | j s|D ]}|  ||¡r| || jtj¡}q| jjsd S |D ]9}| || jtj¡}|rX|j	D ](}|  
|¡du rW|j|dd| jd� | j d|¡D ]\}}}}	|j|dd� qIq/qd S )NFTr¤   r¯   r£   )r   r’   rg   r   r   r   r   r§   r   rW   r-   r¨   r   r   r±   )
r#   r^   rK   r/   rm   rU   r³   r´   rµ   r¶   r$   r$   r%   ra     s8   
ÿ€
ÿ
üÿ€ðzManyToManyDP.presort_savesc              
     sÎ   g }g }g }|   |¡}tƒ }|D ]C‰ | ˆ | j| j¡}|rS| ¡ D ]#}	|	d u s1|d ur2ˆ |	f|v r2q!i }
|  ˆ |	|
d|d¡s?q!| |
¡ q!| ‡ fdd„| ¡ D ƒ¡ q|d ur]| |¡ |  	||||¡ d S )NFr¤   c                 3  ó   � | ]}|ˆ fV  qd S r'   r$   ©r€   r³   ©r/   r$   r%   rÓ   [  ó   € z/ManyToManyDP.process_deletes.<locals>.<genexpr>)
rŠ   rˆ   rg   r   r   Ú	non_addedr~   rL   r�   Ú	_run_crud)r#   r^   rK   Úsecondary_deleteÚsecondary_insertÚsecondary_updateÚ	processedÚtmprm   rU   r|   r$   rï   r%   rc   <  s@   

ÿú€
ÿzManyToManyDP.process_deletesc              
     sŒ  g }g }g }|   |¡}tƒ }|D ]¢‰ | j o|  |ˆ ¡}|r%tjtjB }	ntjtjB }	| ˆ | j	|	¡}
|
r²|
j
D ]}|d urEˆ |f|v rEq8i }|  ˆ ||d|d¡sRq8| |¡ q8|
jD ]}|d urhˆ |f|v rhq[i }|  ˆ ||d|d¡suq[| |¡ q[| ‡ fdd„|
j
|
j D ƒ¡ |r²|
jD ]!}i }t ˆ | j|d| jj¡ t || j|d| jj¡ | |¡ q�q|d ur¼| |¡ |  ||||¡ d S )NFr­   r¤   c                 3  rí   r'   r$   rî   rï   r$   r%   rÓ   ”  rð   z-ManyToManyDP.process_saves.<locals>.<genexpr>Úold_)rŠ   rˆ   r   r’   r   r   re   r   rg   r   r°   r~   rL   rW   r�   r©   r   r   r   r    r   Úsecondary_synchronize_pairsrò   )r#   r^   rK   ró   rô   rõ   rö   r÷   Úneed_cascade_pksrk   rm   rU   r|   r$   rï   r%   rd   d  sˆ   
ÿÿÿÿÿ
ÿ
ú 
ûû€
ÿzManyToManyDP.process_savesc                   s  |j  | j¡}|rA|d ‰ | j ¡  tj‡ fdd„| jjD ƒŽ ¡}| 	||¡}| 
¡ rA|jt|ƒkrAt 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 d S )Nr   c                   s,   g | ]}|j ˆ v r|tj|j |jd �k‘qS )©Útype_©r   r   Ú	bindparamÚtyperî   ©r|   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 ˆ v r|tjd |j  |jd�k‘qS )rø   rû   rý   rî   r   r$   r%   r‚   Ô  s
    
þzRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)ÚtransactionÚ
connectionr   r   r¤   Úwherer   Úand_r³   ÚexecuteÚsupports_sane_multi_rowcountÚrowcountÚlenr   ÚStaleDataErrorÚdescriptionr�   Úinsert)r#   r^   rô   rõ   ró   r  Ú	statementÚresultr$   r   r%   rò   ±  s^   

þÿÿ	ÿýþÿ


þÿÿ	ÿýþÿ

þzManyToManyDP._run_crudc                 C  s€   |   |¡ |d u rdS |d ur(|j |¡s(|js&t dt |¡|| jf ¡ dS t	 
|| j|| jj¡ t	 
|| j|| jj¡ dS )NFrÌ   T)rx   rÍ   rÎ   rW   r   rÏ   rÐ   rÑ   r   r   Úpopulate_dictr   r    r   rù   rÒ   r$   r$   r%   r~   î  s*   
þÿÿüzManyToManyDP._synchronizec                 C  r½   r'   r¾   r‘   r$   r$   r%   r’     rÀ   zManyToManyDP._pks_changedN)r”   r–   r—   r9   rM   r_   ra   rc   rd   rò   r~   r’   r$   r$   r$   r%   rë   Ù  s    "(M= rë   N)rê   Ú
__future__r   Ú r   r   r   r   r   rÐ   Ú
interfacesr	   r
   r   r!   r   r   r™   rÁ   rÄ   rë   r(   r$   r$   r$   r%   Ú<module>   s:   	  3  7 bu  >ý