U
    x^ܵ                     @   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st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    A/tmp/pip-install-dq5v43_d/SQLAlchemy/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 )zreturn 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 )zestablish 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   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}
|st|| j	j
}d }}||jkrd}n&t|| j	j
}d }}||jkrd}|D ]}|j| j j||j|r| jntj}|sq|r8t|| d|}|rZt||}n"t|| d|}|rZt||}|
rg }	|D ]\\}}||jkrd}n6|j| \}}|rt||df}nt||df}|	| qh|	D ]"\}}| |||||||| qqdS )zestablish 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   r2   r   r1   r3   r0   disabledZcyclesAssertionErrorr   base_mappermanagerr   implZget_all_pendingdictr   r   r   ZProcessStateZDeleteStateZSaveUpdateStatestatesappendper_state_dependencies)r   r-   rB   isdeleteZchild_base_mapperr8   r:   r6   r5   Zchild_actionsZchild_in_cyclesr7   r9   Zparent_in_cyclesr*   Zsum_Zchild_statechildchild_actiondeletedZlistonlychildisdeleter    r    r!   per_state_flush_actionsg   s    	
 




z+DependencyProcessor.per_state_flush_actionsc                 C   s   dS NFr    r   	uowcommitrB   r    r    r!   presort_deletes   s    z#DependencyProcessor.presort_deletesc                 C   s   dS rK   r    rL   r    r    r!   presort_saves   s    z!DependencyProcessor.presort_savesc                 C   s   d S r#   r    rL   r    r    r!   process_deletes   s    z#DependencyProcessor.process_deletesc                 C   s   d S r#   r    rL   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   rM   rB   rE   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zmzAttempting 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.)rX   rY   rZ   )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*   rF   associationrow	clearkeysrM   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   s8   |D ].}|r|d k	r| |dd | jjD   q4qd S )Nc                 S   s   g | ]\}}|qS r    r    )rc   lrr    r    r!   re   2  s     z4DependencyProcessor._post_update.<locals>.<listcomp>)Zregister_post_updater   r   )r   r*   rM   relatedis_m2o_deleterX   r    r    r!   _post_update.  s     z DependencyProcessor._post_updatec                 C   s
   t  d S r#   r^   r   rM   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)rt   
__module____qualname__r"   classmethodr&   r(   r.   r;   rJ   rN   rO   rP   rQ   rW   r]   rb   rk   rp   rr   ru   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 r/   r   r   PostUpdateAllr   r2   dependenciesupdate)
r   r-   r7   r8   r9   r:   r5   r6   child_post_updateschild_pre_updatesr    r    r!   r4   >  s<    
    z%OneToManyDP.per_property_dependenciesc	                 C   s   | j rt|| 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 r/   rz   )r   r-   save_parentdelete_parentrG   r5   r6   rE   rI   r~   r   r    r    r!   rD   g  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 qqd S )NallFTrE   delete	operationr   )r   r   r   rR   r   r   rH   r(   delete_orphanregister_object	unchangedr   r   rM   rB   should_null_fksr*   rV   rF   r    r    r!   rN     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	 qq|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   rE   r   r   r   z	pk changer   )ri   rj   r   r   r   rr   r   r   r   r   rR   r   addedr   r   r}   rH   r(   r   cascade_iteratorr   )r   rM   rB   r   r   r*   pks_changedrT   rV   rF   cmst_dct_r    r    r!   rO     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 qq$d S )Nr   r   FT)r   r   ri   rj   rR   r   r   rH   r(   rb   rp   r   r   r   
difference)r   rM   rB   r   r*   rV   rF   r    r    r!   rP     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 qqd S )Nr   FT)r   r   r   rR   r   r   r   r   rb   r   rp   rH   r(   rr   r   r   r    r    r!   rQ   /  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*   rF   r`   ra   rM   r   sourcedestr    r    r!   rb   Q  s(    
zOneToManyDP._synchronizec                 C   s   t ||| j| jjS r#   r   source_modifiedr   r   r   rq   r    r    r!   rr   h  s       zOneToManyDP._pks_changedN)rt   rv   rw   r4   rD   rN   rO   rP   rQ   rb   rr   r    r    r    r!   ry   =  s   )C>,"ry   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_processorsrC   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 r/   r   r   r{   r   r2   r|   r}   )
r   r-   r7   r8   r9   r:   r5   r6   parent_post_updatesparent_pre_updatesr    r    r!   r4   t  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 qt|| 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 r/   r   )r   r-   r   r   rG   r5   r6   rE   rI   r   r   r    r    r!   rD     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 qqLqd S )NTr   r   r   )r   r   r   rR   r   r   sumZnon_deletedr   r   r   r   )r   rM   rB   r*   rV   ZtodeleterF   tr   r   r   r   r    r    r!   rN     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   rR   r   r   rH   r(   r   r   )r   rM   rB   r*   rV   rF   r   r   r   r   r   r    r    r!   rO     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)ro   )
r   r   r   r   rb   rR   r   r   rp   r   )r   rM   rB   r*   rV   r    r    r!   rP     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   )
rR   r   r   r   r   rb   rH   r   rp   r   )r   rM   rB   r*   rV   rF   r    r    r!   rQ     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 )NGObject 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*   rF   r`   ra   rM   r   r    r    r!   rb   *  s<    	

zManyToOneDP._synchronize)N)rt   rv   rw   r"   r4   rD   rN   rO   rP   rQ   rb   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 r#   )r   )rc   r   r    r    r!   	<genexpr>d  s   z=DetectKeySwitch.per_property_preprocessors.<locals>.<genexpr>)r   rf   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 rK   )r   r1   r   r>   r0   r|   r}   )r   r-   r7   r5   r    r    r!   r;   l  s    z*DetectKeySwitch.per_property_flush_actionsc                 C   s   d S r#   r    )r   r-   rB   rE   r    r    r!   rJ   q  s    z'DetectKeySwitch.per_state_flush_actionsc                 C   s   d S r#   r    rL   r    r    r!   rN   t  s    zDetectKeySwitch.presort_deletesc                 C   s   | j s| || d S r#   )r   _process_key_switches)r   r-   rB   r    r    r!   rO   w  s    zDetectKeySwitch.presort_savesc                 C   s"   |s| j r| ||}t|S dS rK   )r   _key_switchersbool)r   r-   rB   rE   dr    r    r!   rW   }  s    
z DetectKeySwitch.prop_has_changesc                 C   s   dst d S rK   )r=   rL   r    r    r!   rP     s    zDetectKeySwitch.process_deletesc                 C   s   | j s
t| || d S r#   )r   r=   r   rL   r    r    r!   rQ     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#   )rj   r    r    r    r!   <lambda>      z0DetectKeySwitch._key_switchers.<locals>.<lambda>)ri   unionrr   r   )r   r-   rB   ZswitchedZnotswitchedZ	allstatesrU   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)rT       F)r   r   Zidentity_mapZ
all_states
issubclassr\   r   rA   r'   r   getr   r   ZPASSIVE_NO_RESULTr   r[   Zinstance_stater   r   r   r   r   r   )	r   ZdeplistrM   Z	switchersr*   Zdict_rn   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   rq   r    r    r!   rr     s       zDetectKeySwitch._pks_changedN)rt   rv   rw   __doc__r.   r;   rJ   rN   rO   rW   rP   rQ   r   r   rr   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 r#   r|   r}   )r   r-   r7   r8   r9   r:   r5   r6   r    r    r!   r4     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   rG   r5   r6   rE   rI   r    r    r!   rD     s    z#ManyToManyDP.per_state_dependenciesc                 C   s&   | j s"|D ]}||| j| j q
d S r#   )r   rR   r   r   )r   rM   rB   r*   r    r    r!   rN     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 qq^q>d S )NFTr   r   r   )r   rr   rR   r   r   r   r   r   r   rH   r(   r   r   r   r   )
r   rM   rB   r*   rV   rF   r   r   r   r   r    r    r!   rO   
  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    rc   r   r*   r    r!   r   K  s     z/ManyToManyDP.process_deletes.<locals>.<genexpr>)
rk   rj   rR   r   r   Z	non_addedrb   rC   r}   	_run_crud)r   rM   rB   secondary_deletesecondary_insertsecondary_update	processedtmprV   rF   r`   r    r   r!   rP   ,  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rqfi }| 
 ||d|dsqf|| qf|
jD ]>}|d k	rƈ |f|krqi }| 
 ||d|dsq|| 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_)rk   rj   r   rr   r   r   r   rR   r   r   rb   rC   rH   r}   r   r   r   r   r   r   secondary_synchronize_pairsr   )r   rM   rB   r   r   r   r   r   Zneed_cascade_pksrT   rV   rF   r`   r    r   r!   rQ   T  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rt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   r`   r    r!   re     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!   re     s   
zRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)Ztransaction
connectionr   r   r   r   and_r   executeZsupports_sane_multi_rowcountZrowcountlenr   ZStaleDataErrordescriptionr}   insert)r   rM   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   rH   r   r   r   r   r   r   Zpopulate_dictr   r   r   r   r   r    r    r!   rb     s0    
   zManyToManyDP._synchronizec                 C   s   t ||| j| jjS r#   r   rq   r    r    r!   rr     s       zManyToManyDP._pks_changedN)rt   rv   rw   r4   rD   rN   rO   rP   rQ   r   rb   rr   r    r    r    r!   r     s   "(H=!r   N)r    r   r   r   r   r   r   Z
interfacesr   r   r	   r   r   objectr   ry   r   r   r   r$   r    r    r    r!   <module>   s<     &  3 fu  ;   