U
    cci                     @   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	 Z	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G dd de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G dd deZG d d! d!eZd"S )#zThe internals for the unit of work system.

The session's flush() process passes objects to a contextual object
here, which assembles flush tasks based on mappers and their properties,
organizes them in order of dependency, and executes.

   
attributes)exc)util   )event)topologicalc                 C   s   t jd| jj|f dd d S )NaH  "%s" object is being merged into a Session along the backref cascade path for relationship "%s"; in SQLAlchemy 2.0, this reverse cascade will not take place.  Set cascade_backrefs to False in either the relationship() or backref() function for the 2.0 behavior; or to set globally for the whole Session, set the future=True flagZs9r1)code)r   Zwarn_deprecated_20class___name__)stateprop r   =/tmp/pip-unpacked-wheel-8u86ls_i/sqlalchemy/orm/unitofwork.py_warn_for_cascade_backrefs   s    
r   c                    s|   |j   fdd} fdd} fdd}tj| d|dd	 tj| d
|ddd tj| d|ddd tj| d|ddd dS )z\Establish event listeners on object attributes which handle
    cascade-on-set/append.

    c                    s   |d krd S | j }|r|jr&|d | jjj  }t|}|jj	r|j
rR|jr\ |jkr||s |jkrzt|| || |S )Nzcollection append)session_warn_on_events_flush_warningmanagermapper_propsr   instance_state_cascadesave_updatecascade_backrefsfuturekey_contains_stater   _save_or_update_stater   item	initiatorsessr   Z
item_stater   r   r   append+   s,    




z$track_cascade_events.<locals>.appendc                    s   |d krd S | j }| jjj  }|r>|jr>||jr8dnd |d k	r|tjk	r|tj	k	r|j
jrt|}|j|r|r||jkr|| nd|_d S )Nzcollection removezrelated attribute deleteT)r   r   r   r   r   r   Zuselistr   	NEVER_SETPASSIVE_NO_RESULTr   delete_orphanr   
_is_orphan_newexpungeZ_orphaned_outside_of_sessionr   r#   r   r   removeG   s.    

z$track_cascade_events.<locals>.removec                    s   ||kr|S | j }|r|jr&|d | jjj  }|d k	rt|}|jj	r|j
rZ|jrd |jkr||s |jkrt|| || |d k	r|tjk	r|tjk	r|jjrt|}||jkr|j|r|| |S )Nzrelated attribute set)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r&   r'   r)   r(   r*   )r   ZnewvalueZoldvaluer!   r"   r   Znewvalue_stateZoldvalue_stater#   r   r   set_i   sH    






z"track_cascade_events.<locals>.set_Zappend_wo_mutationT)rawr$   )r-   retvalr+   setN)r   r   listen)Z
descriptorr   r$   r+   r,   r   r#   r   track_cascade_events$   s    "*r1   c                   @   s   e Zd Zdd Zedd Zdd Zdd Zd	d
 Zdd Z	e
jfddZdd Zdd Zd'ddZdd Zdd Zejdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& ZdS )(UOWTransactionc                 C   sR   || _ i | _tt| _tt| _i | _i | _t | _	i | _
tdd | _d S )Nc                   S   s   t  t  fS N)r/   r   r   r   r   <lambda>       z)UOWTransaction.__init__.<locals>.<lambda>)r   r   r   defaultdictr/   depsmapperspresort_actionspostsort_actionsdependenciesstatespost_update_states)selfr   r   r   r   __init__   s    zUOWTransaction.__init__c                 C   s
   t | jS r3   )boolr<   r>   r   r   r   has_work   s    zUOWTransaction.has_workc                 C   sD   |j r@z||tj W n& tjk
r>   | j|g Y dS X dS )zZReturn ``True`` if the given state is expired and was deleted
        previously.
        TF)ZexpiredZ_load_expiredr   PASSIVE_OFForm_excZObjectDeletedErrorr   _remove_newly_deletedr>   r   r   r   r   was_already_deleted   s    z"UOWTransaction.was_already_deletedc                 C   s   || j ko| j | d S )z[Return ``True`` if the given state is marked as deleted
        within this uowtransaction.    r<   rF   r   r   r   
is_deleted   s    zUOWTransaction.is_deletedc                 C   s,   || j kr| j | S |  | j |< }|S d S r3   r   )r>   r   Z	callable_retr   r   r   memo   s    

zUOWTransaction.memoc                 C   s    | j | d }|df| j |< dS )z;Remove pending actions for a state from the uowtransaction.rH   TNrI   )r>   r   isdeleter   r   r   remove_state_actions   s    z#UOWTransaction.remove_state_actionsc           	      C   s   d||f}|| j kr| j | \}}}|t j@ s|t j@ r|j| j}|||jt jt jB t jB }|rv|j	rv|
 }n|}|||f| j |< nP|j| j}|||j|t jB t jB }|r|j	r|
 }n|}|||f| j |< |S )zOFacade to attributes.get_state_history(), including
        caching of results.history)r   ZSQL_OKr   implZget_historydictrC   ZLOAD_AGAINST_COMMITTEDZNO_RAISEZuses_objectsZas_state)	r>   r   r   ZpassiveZhashkeyrO   Zstate_historyZcached_passiverP   r   r   r   get_attribute_history   sH    





z$UOWTransaction.get_attribute_historyc                 C   s   |df| j kS )NT)r9   )r>   	processorr   r   r   has_dep   s    zUOWTransaction.has_depc                 C   s&   ||f}|| j kr"t||| j |< d S r3   )r9   
Preprocess)r>   rS   
fromparentr   r   r   r   register_preprocessor#  s    
z$UOWTransaction.register_preprocessorFNc                 C   s   | j |s8|js4|d k	r4tdt|||f  dS || jkr~|jj	}|| j
kr^| | | j
| | ||f| j|< n|s|s|r|df| j|< dS )NzJObject of type %s not in session, %s operation along '%s' will not proceedFT)r   r   Zdeletedr   warnorm_utilZstate_class_strr<   r   r   r8   _per_mapper_flush_actionsadd)r>   r   rM   listonlyZcancel_deleteZ	operationr   r   r   r   r   register_object(  s"    	


zUOWTransaction.register_objectc                 C   s0   |j jj}| j| \}}|| || d S r3   )r   r   base_mapperr=   r[   update)r>   r   Zpost_update_colsr   r<   colsr   r   r   register_post_updateJ  s    

z#UOWTransaction.register_post_updatec                 C   sf   t | |j}t| |j}| j||f |jD ]}||  q.|jD ]}|jrPqD|j	}||  qDd S r3   )
SaveUpdateAllr^   	DeleteAllr;   r[   Z_dependency_processorsZper_property_preprocessorsZrelationshipsZviewonlyZ_dependency_processor)r>   r   ZsavesZdeletesdepr   r   r   r   rZ   P  s    

z(UOWTransaction._per_mapper_flush_actionsc                 C   s   t dd S )a  return a dynamic mapping of (Mapper, DependencyProcessor) to
        True or False, indicating if the DependencyProcessor operates
        on objects of that Mapper.

        The result is stored in the dictionary persistently once
        calculated.

        c                 S   s    | d j | d j| d jkS )NrH   r   )r   getr   r   )tupr   r   r   r4   i  r5   z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   ZPopulateDictrA   r   r   r   _mapper_for_dep^  s    
zUOWTransaction._mapper_for_depc                    s   | j  fdd|D S )zmFilter the given list of InstanceStates to those relevant to the
        given DependencyProcessor.

        c                    s    g | ]}|j j f r|qS r   )r   r   .0srd   Zmapper_for_depr   r   
<listcomp>r  s      z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)rg   )r>   rd   r<   r   rk   r   filter_states_for_depl  s    z$UOWTransaction.filter_states_for_depc                 c   s>   ||f}|j jD ](}| j| D ]}| j| |kr|V  qqd S r3   )r^   self_and_descendantsr8   r<   )r>   r   rM   r\   Zchecktupr   r   r   r   states_for_mapper_hierarchyt  s
    z*UOWTransaction.states_for_mapper_hierarchyc                    sJ  d}t  j D ]}| rd}q|s q.q t jt  j   _}|r,t	 fdd|D }t  jD ]}d|ks|d j
s|d j
s||r j| qr|d |kr j| ||d  D ]} j||d f qqr|d |krr j| ||d  D ]} j|d |f qqrtdd	  j D |S )
z}Generate the full, unsorted collection of PostSortRecs as
        well as dependency pairs for this UOWTransaction.

        FTc                 3   s    | ]}|t | fV  qd S r3   )r/   per_state_flush_actions)ri   recrA   r   r   	<genexpr>  s    z3UOWTransaction._generate_actions.<locals>.<genexpr>NrH   r   c                 S   s   g | ]}|j s|qS r   disabled)ri   ar   r   r   rl     s      z4UOWTransaction._generate_actions.<locals>.<listcomp>)listr9   valuesexecuter   Zfind_cyclesr;   r:   cyclesrQ   rt   
issupersetr+   r[   r/   
difference)r>   rK   actionry   convertZedgerd   r   rA   r   _generate_actions{  sJ    	
 
z UOWTransaction._generate_actionsc                 C   sx   |   }t|dd d}| jrVt| j|D ]&}t|}|r,| }|| | q8q,nt	| j|D ]}|
|  qdd S )Nc                 S   s   | j S r3   )sort_key)r    r   r   r   r4     r5   z(UOWTransaction.execute.<locals>.<lambda>r#   )r~   sortedry   r   Zsort_as_subsetsr;   r/   popexecute_aggregatesortrx   )r>   r:   Zsubsetr,   nrq   r   r   r   rx     s      zUOWTransaction.executec                 C   sZ   | j s
dS t| j }tdd | j  D }||}|rF| j| |rV| j| dS )zMark processed objects as clean / deleted after a successful
        flush().

        This method is called within the flush() method after the
        execute() method has succeeded and the transaction has been committed.

        Nc                 s   s   | ]\}\}}|r|V  qd S r3   r   )ri   rj   rM   r\   r   r   r   rr     s   
  z8UOWTransaction.finalize_flush_changes.<locals>.<genexpr>)r<   r/   itemsr{   r   rE   Z_register_persistent)r>   r<   Zisdelotherr   r   r   finalize_flush_changes  s    

z%UOWTransaction.finalize_flush_changes)FFFNN)r   
__module____qualname__r?   propertyrB   rG   rJ   rL   rN   r   ZPASSIVE_NO_INITIALIZErR   rT   rW   r]   ra   rZ   r   Zmemoized_propertyrg   rm   ro   r~   rx   r   r   r   r   r   r2      s4   -

5     
"
4r2   c                   @   s   e Zd Zdd ZdS )IterateMappersMixinc                    s2    j r$t fdd jjjD S  jjjS d S )Nc                 3   s"   | ]}j | jf r|V  qd S r3   )rg   dependency_processor)ri   mr>   uowr   r   rr     s   z/IterateMappersMixin._mappers.<locals>.<genexpr>)rV   iterr   parentrn   r   r   r   r   r   _mappers  s
    zIterateMappersMixin._mappersN)r   r   r   r   r   r   r   r   r     s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )rU   )r   rV   	processedsetup_flush_actionsc                 C   s   || _ || _t | _d| _d S NF)r   rV   r/   r   r   )r>   r   rV   r   r   r   r?     s    zPreprocess.__init__c                 C   s   t  }t  }| |D ]H}|j| | jD ]0}|j| \}}|s,|rR|| q,|| q,q|r~| j|| | j	| |r| j
|| | j	| |s|r| js| j||ds| j||dr| j| d| _dS dS d S NTF)r/   r   r8   r{   r   r<   r[   r   Zpresort_deletesr_   Zpresort_savesr   Zprop_has_changesZper_property_flush_actions)r>   r   Zdelete_statesZsave_statesr   r   rM   r\   r   r   r   rx     sB        zPreprocess.executeN)r   r   r   	__slots__r?   rx   r   r   r   r   rU     s   rU   c                   @   s    e Zd ZdZdd Zdd ZdS )PostSortRecrs   c                 G   s@   | f| }||j kr|j | S t|  |j |< }d|_|S d S r   )r:   object__new__rt   )clsr   argsr   rK   r   r   r   r   !  s    


zPostSortRec.__new__c                 C   s   |  | d S r3   )rx   )r>   r   recsr   r   r   r   *  s    zPostSortRec.execute_aggregateN)r   r   r   r   r   r   r   r   r   r   r     s   	r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )
ProcessAll)r   rM   rV   r   c                 C   s:   || _ d| j j|f| _|| _|| _|j|jj | d S )Nr   )r   r   rM   rV   r7   r   r^   r[   )r>   r   r   rM   rV   r   r   r   r?   1  s    zProcessAll.__init__c                 C   s2   |  |}| jr | j|| n| j|| d S r3   )	_elementsrM   r   process_deletesprocess_saves)r>   r   r<   r   r   r   rx   >  s    
zProcessAll.executec                 C   s   t g S r3   )r   r   r   r   r   rp   E  s    z"ProcessAll.per_state_flush_actionsc                 C   s   d| j j| j| jf S )Nz%s(%s, isdelete=%s))	__class__r   r   rM   rA   r   r   r   __repr__L  s
    zProcessAll.__repr__c                 c   sF   |  |D ]6}|j| D ]&}|j| \}}|| jkr|s|V  qq
d S r3   )r   r8   r<   rM   )r>   r   r   r   rM   r\   r   r   r   r   S  s
    zProcessAll._elementsN)	r   r   r   r   r?   rx   rp   r   r   r   r   r   r   r   .  s   r   c                   @   s*   e Zd ZdZdd Zeddd ZdS )PostUpdateAll)r   rM   r   c                 C   s   || _ || _d|j|f| _d S )Nr   )r   rM   	_sort_keyr   )r>   r   r   rM   r   r   r   r?   ^  s    zPostUpdateAll.__init__sqlalchemy.orm.persistencec                    sB   t jj}j j \}} fdd|D }| j|| d S )Nc                    s$   g | ]}j | d   jkr|qS rH   )r<   rM   rh   r   r   r   rl   g  s      z)PostUpdateAll.execute.<locals>.<listcomp>)r   	preloadedorm_persistencer=   r   Zpost_update)r>   r   persistencer<   r`   r   r   r   rx   c  s    zPostUpdateAll.executeN)r   r   r   r   r?   r   preload_modulerx   r   r   r   r   r   [  s   r   c                   @   s:   e Zd ZdZdd Zeddd Zdd Zd	d
 Z	dS )rb   r   r   c                 C   s$   || _ d|jf| _||jks td S )Nrb   r   r   r   r^   AssertionErrorr>   r   r   r   r   r   r?   o  s    zSaveUpdateAll.__init__r   c                 C   s$   t jj| j|| jdd| d S r   )r   r   r   save_objr   ro   r   r   r   r   rx   t  s
    zSaveUpdateAll.executec           	      c   s   t || jdd}| jj}t||}|D ]$}t||}|j||f |V  q*|j| j D ]}|	||}|
||d q\d S r   )rv   ro   r   r^   rc   SaveUpdateStater;   r[   r7   rm   rp   )	r>   r   r<   r^   Z
delete_allr   r|   rd   states_for_propr   r   r   rp   |  s    

z%SaveUpdateAll.per_state_flush_actionsc                 C   s   d| j j| jf S Nz%s(%s)r   r   r   rA   r   r   r   r     s    zSaveUpdateAll.__repr__N
r   r   r   r   r?   r   r   rx   rp   r   r   r   r   r   rb   l  s   
rb   c                   @   s:   e Zd ZdZdd Zeddd Zdd Zd	d
 Z	dS )rc   r   c                 C   s$   || _ d|jf| _||jks td S )Nrc   r   r   r   r   r   r?     s    zDeleteAll.__init__r   c                 C   s$   t jj| j|| jdd| d S r   )r   r   r   
delete_objr   ro   r   r   r   r   rx     s
    zDeleteAll.executec           	      c   s   t || jdd}| jj}t||}|D ]$}t||}|j||f |V  q*|j| j D ]}|	||}|
||d q\d S r   )rv   ro   r   r^   rb   DeleteStater;   r[   r7   rm   rp   )	r>   r   r<   r^   Zsave_allr   r|   rd   r   r   r   r   rp     s    

z!DeleteAll.per_state_flush_actionsc                 C   s   d| j j| jf S r   r   rA   r   r   r   r     s    zDeleteAll.__repr__Nr   r   r   r   r   rc     s   
rc   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ProcessState)r   rM   r   r   c                 C   s"   || _ d|jf| _|| _|| _d S Nr   )r   r   rM   r   )r>   r   r   rM   r   r   r   r   r?     s    zProcessState.__init__c                    sj   | j  | j| j fdd|D }|| | jgdd |D  }rZ|| n|| d S )Nc                    s.   g | ]&}|j  kr|jkr|jkr|qS r   )r   r   rM   ri   rcls_r   rM   r   r   rl     s
   


z2ProcessState.execute_aggregate.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   rl     s     )r   r   rM   difference_updater   r   r   )r>   r   r   our_recsr<   r   r   r   r     s    
zProcessState.execute_aggregatec                 C   s    d| j j| jt| j| jf S )Nz%s(%s, %s, delete=%s))r   r   r   rY   	state_strr   rM   rA   r   r   r   r     s    
zProcessState.__repr__N)r   r   r   r   r?   r   r   r   r   r   r   r     s   r   c                   @   s2   e Zd ZdZdd Zeddd Zdd Zd	S )
r   r   r   r   c                 C   s"   || _ |jj| _d| jjf| _d S r   r   r   r^   r   r   r>   r   r   r   r   r   r?     s    
zSaveUpdateState.__init__r   c                    sV   t jj}| j | j fdd|D }|| || jgdd |D  | d S )Nc                    s$   g | ]}|j  kr|jkr|qS r   r   r   r   r   r   r   r   rl     s    
 
 z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   rl     s     )r   r   r   r   r   r   r   r   )r>   r   r   r   r   r   r   r   r     s    
  z!SaveUpdateState.execute_aggregatec                 C   s   d| j jt| jf S r   r   r   rY   r   r   rA   r   r   r   r     s    
zSaveUpdateState.__repr__N	r   r   r   r   r?   r   r   r   r   r   r   r   r   r     s
   
r   c                   @   s2   e Zd ZdZdd Zeddd Zdd Zd	S )
r   r   c                 C   s"   || _ |jj| _d| jjf| _d S )Nr   r   r   r   r   r   r?     s    
zDeleteState.__init__r   c                    sh   t jj}| j | j fdd|D }|| | jgdd |D  }|fdd|D  d S )Nc                    s$   g | ]}|j  kr|jkr|qS r   r   r   r   r   r   rl     s    
 
 z1DeleteState.execute_aggregate.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   rl     s     c                    s   g | ]} j | d  r|qS r   rI   rh   )r   r   r   rl   	  s      )r   r   r   r   r   r   r   r   )r>   r   r   r   r   r<   r   )r   r   r   r   r     s    
  zDeleteState.execute_aggregatec                 C   s   d| j jt| jf S r   r   rA   r   r   r   r     s    
zDeleteState.__repr__Nr   r   r   r   r   r     s
   
r   N)__doc__ r   r   rD   r   rY   r   r   r   r1   r   r2   r   rU   r   r   r   rb   rc   r   r   r   r   r   r   r   <module>   s*   u  I2-%%$