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
 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)persistence)util   )event)topologicalc                    sj   |j   fdd} fdd} f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                    sn   |d krd S | j }|rj|jr&|d | jjj  }t|}|jj	rj|j
sV |jkrj||sj|| |S )Nzcollection append)session_warn_on_events_flush_warningmanagermapper_propsr   instance_state_cascadesave_updatecascade_backrefskey_contains_state_save_or_update_statestateitem	initiatorsesspropZ
item_stater    A/tmp/pip-install-dq5v43_d/SQLAlchemy/sqlalchemy/orm/unitofwork.py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   remove6   s.    

z$track_cascade_events.<locals>.removec                    s   ||kr|S | j }|r|jr&|d | jjj  }|d k	rrt|}|jj	rr|j
s^ |jkrr||sr|| |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   ZnewvalueZoldvaluer   r   r   Znewvalue_stateZoldvalue_stater   r   r   set_X   s@    




z"track_cascade_events.<locals>.set_r    T)rawretvalr'   setN)r   r   listen)Z
descriptorr   r    r'   r(   r   r   r   track_cascade_events   s    "%r-   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 r/   )boolr8   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 )zVreturn 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 )zWreturn true if the given state is marked as deleted
        within this uowtransaction.    r8   rB   r   r   r   
is_deleted   s    zUOWTransaction.is_deletedc                 C   s,   || j kr| j | S |  | j |< }|S d S r/   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.rD   TNrE   )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 }|rp|jrp|	 }n|}|||f| j |< nJ|j| j}|||j|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dictr?   ZLOAD_AGAINST_COMMITTEDZuses_objectsZas_state)	r:   r   r   ZpassiveZhashkeyrK   Zstate_historyZcached_passiverL   r   r   r   get_attribute_history   s8    




  

z$UOWTransaction.get_attribute_historyc                 C   s   |df| j kS )NT)r5   )r:   	processorr   r   r   has_dep  s    zUOWTransaction.has_depc                 C   s&   ||f}|| j kr"t||| j |< d S r/   )r5   
Preprocess)r:   rO   
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_strr8   r   r   r4   _per_mapper_flush_actionsadd)r:   r   rI   listonlyZcancel_deleteZ	operationr   r   r   r   r   register_object  s"    	


zUOWTransaction.register_objectc                 C   s0   |j jj}| j| \}}|| || d S r/   )r   r   base_mapperr9   rW   update)r:   r   Zpost_update_colsr   r8   colsr   r   r   register_post_update-  s    

z#UOWTransaction.register_post_updatec                 C   sf   t | |j}t| |j}| j||f |jD ]}||  q.|jD ]}|jrPqD|j	}||  qDd S r/   )
SaveUpdateAllrZ   	DeleteAllr7   rW   Z_dependency_processorsZper_property_preprocessorsZrelationshipsZviewonlyZ_dependency_processor)r:   r   ZsavesZdeletesdepr   r   r   r   rV   3  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 )NrD   r   )r   getr   r   )tupr   r   r   r0   L  r1   z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   ZPopulateDictr=   r   r   r   _mapper_for_depA  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r`   Zmapper_for_depr   r   
<listcomp>U  s      z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)rc   )r:   r`   r8   r   rg   r   filter_states_for_depO  s    z$UOWTransaction.filter_states_for_depc                 c   s>   ||f}|j jD ](}| j| D ]}| j| |kr|V  qqd S r/   )rZ   self_and_descendantsr4   r8   )r:   r   rI   rX   Zchecktupr   r   r   r   states_for_mapper_hierarchyW  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 r/   )r+   per_state_flush_actions)re   recr=   r   r   	<genexpr>v  s    z3UOWTransaction._generate_actions.<locals>.<genexpr>NrD   r   c                 S   s   g | ]}|j s|qS r   disabled)re   ar   r   r   rh     s      z4UOWTransaction._generate_actions.<locals>.<listcomp>)listr5   valuesexecuter	   Zfind_cyclesr7   r6   cyclesrM   rp   
issupersetr'   rW   r+   
difference)r:   rG   actionru   convertZedger`   r   r=   r   _generate_actions^  sJ    	
 
z UOWTransaction._generate_actionsc                 C   s`   |   }| jr>t| j|D ]}|r| }|| | q qnt| j|D ]}||  qLd S r/   )	rz   ru   r	   Zsort_as_subsetsr7   popexecute_aggregatesortrt   )r:   r6   r(   nrm   r   r   r   rt     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 r/   r   )re   rf   rI   rX   r   r   r   rn     s   
  z8UOWTransaction.finalize_flush_changes.<locals>.<genexpr>)r8   r+   itemsrw   r
   rA   Z_register_persistent)r:   r8   Zisdelotherr   r   r   finalize_flush_changes  s    

z%UOWTransaction.finalize_flush_changes)FFFNN)__name__
__module____qualname__r;   propertyr>   rC   rF   rH   rJ   r   ZPASSIVE_NO_INITIALIZErN   rP   rS   rY   r]   rV   r   Zmemoized_propertyrc   ri   rk   rz   rt   r   r   r   r   r   r.      s4   -

/     
"
4r.   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 r/   )rc   dependency_processor)re   mr:   uowr   r   rn     s   z/IterateMappersMixin._mappers.<locals>.<genexpr>)rR   iterr   parentrj   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 )rQ   )r   rR   	processedsetup_flush_actionsc                 C   s   || _ || _t | _d| _d S NF)r   rR   r+   r   r   )r:   r   rR   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   r4   rw   r   r8   rW   r   Zpresort_deletesr[   Zpresort_savesr   Zprop_has_changesZper_property_flush_actions)r:   r   Zdelete_statesZsave_statesr   r   rI   rX   r   r   r   rt     sB        zPreprocess.executeNr   r   r   	__slots__r;   rt   r   r   r   r   rQ     s   rQ   c                   @   s    e Zd ZdZdd Zdd ZdS )PostSortRecro   c                 G   s@   | f| }||j kr|j | S t|  |j |< }d|_|S d S r   )r6   object__new__rp   )clsr   argsr   rG   r   r   r   r     s    


zPostSortRec.__new__c                 C   s   |  | d S r/   )rt   )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   rI   rR   c                 C   s*   || _ || _|| _|j|jj | d S r/   )r   rI   rR   r3   r   rZ   rW   )r:   r   r   rI   rR   r   r   r   r;     s    zProcessAll.__init__c                 C   s2   |  |}| jr | j|| n| j|| d S r/   )	_elementsrI   r   process_deletesprocess_saves)r:   r   r8   r   r   r   rt     s    
zProcessAll.executec                 C   s   t g S r/   )r   r   r   r   r   rl     s    z"ProcessAll.per_state_flush_actionsc                 C   s   d| j j| j| jf S )Nz%s(%s, isdelete=%s))	__class__r   r   rI   r=   r   r   r   __repr__%  s
    zProcessAll.__repr__c                 c   sF   |  |D ]6}|j| D ]&}|j| \}}|| jkr|s|V  qq
d S r/   )r   r4   r8   rI   )r:   r   r   r   rI   rX   r   r   r   r   ,  s
    zProcessAll._elementsN)	r   r   r   r   r;   rt   rl   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 )PostUpdateAllr   rI   c                 C   s   || _ || _d S r/   r   )r:   r   r   rI   r   r   r   r;   7  s    zPostUpdateAll.__init__c                    s:   j  j \}} fdd|D }t j|| d S )Nc                    s$   g | ]}j | d   jkr|qS rD   )r8   rI   rd   r   r   r   rh   =  s      z)PostUpdateAll.execute.<locals>.<listcomp>)r9   r   r   Zpost_update)r:   r   r8   r\   r   r   r   rt   ;  s    zPostUpdateAll.executeNr   r   r   r   r   r   4  s   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r^   r   c                 C   s   || _ ||jkstd S r/   r   rZ   AssertionErrorr:   r   r   r   r   r   r;   E  s    zSaveUpdateAll.__init__c                 C   s    t | j|| jdd| d S r   )r   save_objr   rk   r   r   r   r   rt   I  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   )rr   rk   r   rZ   r_   SaveUpdateStater7   rW   r3   ri   rl   )	r:   r   r8   rZ   Z
delete_allr   rx   r`   states_for_propr   r   r   rl   P  s    

z%SaveUpdateAll.per_state_flush_actionsc                 C   s   d| j j| jf S Nz%s(%s)r   r   r   r=   r   r   r   r   a  s    zSaveUpdateAll.__repr__Nr   r   r   r   r;   rt   rl   r   r   r   r   r   r^   B  s
   r^   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r_   r   c                 C   s   || _ ||jkstd S r/   r   r   r   r   r   r;   h  s    zDeleteAll.__init__c                 C   s    t | j|| jdd| d S r   )r   
delete_objr   rk   r   r   r   r   rt   l  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   )rr   rk   r   rZ   r^   DeleteStater7   rW   r3   ri   rl   )	r:   r   r8   rZ   Zsave_allr   rx   r`   r   r   r   r   rl   s  s    

z!DeleteAll.per_state_flush_actionsc                 C   s   d| j j| jf S r   r   r=   r   r   r   r     s    zDeleteAll.__repr__Nr   r   r   r   r   r_   e  s
   r_   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ProcessStater   rI   r   c                 C   s   || _ || _|| _d S r/   r   )r:   r   r   rI   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   rI   re   rcls_r   rI   r   r   rh     s
   


z2ProcessState.execute_aggregate.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   rh     s     )r   r   rI   difference_updater   r   r   r:   r   r   our_recsr8   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   rU   	state_strr   rI   r=   r   r   r   r     s    
zProcessState.__repr__Nr   r   r   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d ZdS )	r   r   r   c                 C   s   || _ |jj| _d S r/   r   r   rZ   r:   r   r   r   r   r   r;     s    zSaveUpdateState.__init__c                    sN   | j  | j fdd|D }|| t| 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   rh     s    
 
 z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   rh     s     )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   rU   r   r   r=   r   r   r   r     s    
zSaveUpdateState.__repr__Nr   r   r   r   r   r     s   r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	r   r   c                 C   s   || _ |jj| _d S r/   r   r   r   r   r   r;     s    zDeleteState.__init__c                    s`   | j  | j fdd|D }|| | jgdd |D  }tfdd|D  d S )Nc                    s$   g | ]}|j  kr|jkr|qS r   r   r   r   r   r   rh     s    
 
 z1DeleteState.execute_aggregate.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   r   r   r   r   r   rh     s     c                    s   g | ]} j | d  r|qS r   rE   rd   )r   r   r   rh     s      )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   r=   r   r   r   r     s    
zDeleteState.__repr__Nr   r   r   r   r   r     s   r   N)__doc__ r   r   r@   r   r   rU   r   r	   r-   r   r.   r   rQ   r   r   r   r^   r_   r   r   r   r   r   r   r   <module>   s*   i  >2(###