B
    .``                 @   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prop
item_state)r    H/home/dcms/DCMS/lib/python3.7/site-packages/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_session)r   r   r   r   r   r   )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_state)r   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 )N)boolr5   )r7   r   r   r   has_work   s    zUOWTransaction.has_workc             C   sB   |j r>y||tj W n$ tjk
r<   | j|g 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)r7   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.    )r5   )r7   r   r   r   r   
is_deleted   s    zUOWTransaction.is_deletedc             C   s,   || j kr| j | S |  | j |< }|S d S )N)r   )r7   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.r?   TN)r5   )r7   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)	r7   r   r   ZpassiveZhashkeyrE   Zstate_historyZcached_passiverF   r   r   r   get_attribute_history   s,    







z$UOWTransaction.get_attribute_historyc             C   s   |df| j kS )NT)r2   )r7   	processorr   r   r   has_dep  s    zUOWTransaction.has_depc             C   s&   ||f}|| j kr"t||| j |< d S )N)r2   
Preprocess)r7   rI   
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_strr5   r   r   r1   _per_mapper_flush_actionsadd)r7   r   rC   listonlyZcancel_deleteZ	operationr   r   r   r   r   register_object  s    	


zUOWTransaction.register_objectc             C   s0   |j jj}| j| \}}|| || d S )N)r   r   base_mapperr6   rQ   update)r7   r   Zpost_update_colsr   r5   colsr   r   r   register_post_update-  s    

z#UOWTransaction.register_post_updatec             C   sn   t | |j}t| |j}| j||f x|jD ]}||  q0W x&|jD ]}|jrVqJ|j	}||  qJW d S )N)
SaveUpdateAllrT   	DeleteAllr4   rQ   Z_dependency_processorsZper_property_preprocessorsZrelationshipsZviewonlyZ_dependency_processor)r7   r   ZsavesZdeletesdepr   r   r   r   rP   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 )Nr?   r   )r   getr   r   )tupr   r   r   r-   L  r.   z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   ZPopulateDict)r7   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)rZ   mapper_for_depr   r   
<listcomp>U  s    z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)r]   )r7   rZ   r5   r   )rZ   r`   r   filter_states_for_depO  s    z$UOWTransaction.filter_states_for_depc             c   sF   ||f}x8|j jD ],}x&| j| D ]}| j| |kr"|V  q"W qW d S )N)rT   self_and_descendantsr1   r5   )r7   r   rC   rR   Zchecktupr   r   r   r   states_for_mapper_hierarchyW  s
    z*UOWTransaction.states_for_mapper_hierarchyc                s^  x4d}x$t  j D ]}| rd}qW |sP qW t jt  j   _}|r@t	 fdd|D }xt  jD ]}d|ks|d j
s|d j
s||r j| q||d |kr j| xn||d  D ]} j||d f qW q||d |kr| j| x*||d  D ]} j|d |f qW q|W t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 )N)r)   per_state_flush_actions)r^   rec)r7   r   r   	<genexpr>w  s    z3UOWTransaction._generate_actions.<locals>.<genexpr>Nr?   r   c             S   s   g | ]}|j s|qS r   )disabled)r^   ar   r   r   ra     s    z4UOWTransaction._generate_actions.<locals>.<listcomp>)listr2   valuesexecuter   Zfind_cyclesr4   r3   cyclesrG   rh   
issupersetr%   rQ   r)   
difference)r7   rA   actionrm   convertZedgerZ   r   )r7   r   _generate_actions^  s:    



z UOWTransaction._generate_actionsc             C   sl   |   }| jrFxXt| j|D ]"}x|r>| }|| | q$W qW n"x t| j|D ]}||  qVW d S )N)	rr   rm   r   Zsort_as_subsetsr4   popexecute_aggregatesortrl   )r7   r3   r&   nrf   r   r   r   rl     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 )Nr   )r^   r_   rC   rR   r   r   r   rg     s    z8UOWTransaction.finalize_flush_changes.<locals>.<genexpr>)r5   r)   itemsro   r	   r=   Z_register_persistent)r7   r5   Zisdelotherr   r   r   finalize_flush_changes  s    

z%UOWTransaction.finalize_flush_changes)FFFNN)__name__
__module____qualname__r8   propertyr:   r>   r@   rB   rD   r   ZPASSIVE_NO_INITIALIZErH   rJ   rM   rS   rW   rP   r   Zmemoized_propertyr]   rb   rd   rr   rl   ry   r   r   r   r   r,      s,   -.    
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 )N)r]   dependency_processor)r^   m)r7   uowr   r   rg     s   z/IterateMappersMixin._mappers.<locals>.<genexpr>)rL   iterr   parentrc   r   )r7   r   r   )r7   r   r   _mappers  s
    zIterateMappersMixin._mappersN)rz   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 )rK   )r   rL   	processedsetup_flush_actionsc             C   s   || _ || _t | _d| _d S )NF)r   rL   r)   r   r   )r7   r   rL   r   r   r   r8     s    zPreprocess.__init__c             C   s   t  }t  }xZ| |D ]L}xF|j| | jD ]0}|j| \}}|s0|rV|| q0|| q0W qW |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   r1   ro   r   r5   rQ   r   Zpresort_deletesrU   Zpresort_savesr   Zprop_has_changesZper_property_flush_actions)r7   r   Zdelete_statesZsave_statesr   r   rC   rR   r   r   r   rl     s2    

zPreprocess.executeN)rz   r{   r|   	__slots__r8   rl   r   r   r   r   rK     s   rK   c               @   s    e Zd ZdZdd Zdd ZdS )PostSortRec)rh   c             G   s@   | f| }||j kr|j | S t|  |j |< }d|_|S d S )NF)r3   object__new__rh   )clsr   argsr   rA   r   r   r   r     s    


zPostSortRec.__new__c             C   s   |  | d S )N)rl   )r7   r   recsr   r   r   rt     s    zPostSortRec.execute_aggregateN)rz   r{   r|   r   r   rt   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   rC   rL   c             C   s*   || _ || _|| _|j|jj | d S )N)r   rC   rL   r0   r   rT   rQ   )r7   r   r   rC   rL   r   r   r   r8     s
    zProcessAll.__init__c             C   s2   |  |}| jr | j|| n| j|| d S )N)	_elementsrC   r   process_deletesprocess_saves)r7   r   r5   r   r   r   rl     s    
zProcessAll.executec             C   s   t g S )N)r   )r7   r   r   r   r   re     s    z"ProcessAll.per_state_flush_actionsc             C   s   d| j j| j| jf S )Nz%s(%s, isdelete=%s))	__class__rz   r   rC   )r7   r   r   r   __repr__%  s    zProcessAll.__repr__c             c   sN   xH|  |D ]:}x4|j| D ]&}|j| \}}|| jkr|s|V  qW qW d S )N)r   r1   r5   rC   )r7   r   r   r   rC   rR   r   r   r   r   ,  s
    zProcessAll._elementsN)	rz   r{   r|   r   r8   rl   re   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   rC   c             C   s   || _ || _d S )N)r   rC   )r7   r   r   rC   r   r   r   r8   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 )r?   )r5   rC   )r^   r_   )r7   r   r   r   ra   =  s    z)PostUpdateAll.execute.<locals>.<listcomp>)r6   r   r   Zpost_update)r7   r   r5   rV   r   )r7   r   r   rl   ;  s    zPostUpdateAll.executeN)rz   r{   r|   r   r8   rl   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 )rX   )r   c             C   s   || _ ||jkstd S )N)r   rT   AssertionError)r7   r   r   r   r   r   r8   E  s    zSaveUpdateAll.__init__c             C   s    t | j|| jdd| d S )NF)r   save_objr   rd   )r7   r   r   r   r   rl   I  s    zSaveUpdateAll.executec       	      c   s   t || jdd}| jj}t||}x,|D ]$}t||}|j||f |V  q,W x.|j| j D ]}|	||}|
||d qbW d S )NF)rj   rd   r   rT   rY   SaveUpdateStater4   rQ   r0   rb   re   )	r7   r   r5   rT   Z
delete_allr   rp   rZ   states_for_propr   r   r   re   P  s    



z%SaveUpdateAll.per_state_flush_actionsc             C   s   d| j j| jf S )Nz%s(%s))r   rz   r   )r7   r   r   r   r   a  s    zSaveUpdateAll.__repr__N)rz   r{   r|   r   r8   rl   re   r   r   r   r   r   rX   B  s
   rX   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )rY   )r   c             C   s   || _ ||jkstd S )N)r   rT   r   )r7   r   r   r   r   r   r8   h  s    zDeleteAll.__init__c             C   s    t | j|| jdd| d S )NTF)r   
delete_objr   rd   )r7   r   r   r   r   rl   l  s    zDeleteAll.executec       	      c   s   t || jdd}| jj}t||}x,|D ]$}t||}|j||f |V  q,W x.|j| j D ]}|	||}|
||d qbW d S )NTF)rj   rd   r   rT   rX   DeleteStater4   rQ   r0   rb   re   )	r7   r   r5   rT   Zsave_allr   rp   rZ   r   r   r   r   re   s  s    



z!DeleteAll.per_state_flush_actionsc             C   s   d| j j| jf S )Nz%s(%s))r   rz   r   )r7   r   r   r   r     s    zDeleteAll.__repr__N)rz   r{   r|   r   r8   rl   re   r   r   r   r   r   rY   e  s
   rY   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ProcessState)r   rC   r   c             C   s   || _ || _|| _d S )N)r   rC   r   )r7   r   r   rC   r   r   r   r   r8     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   rC   )r^   r)cls_r   rC   r   r   ra     s   

z2ProcessState.execute_aggregate.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )r   )r^   r   r   r   r   ra     s    )r   r   rC   difference_updater   r   r   )r7   r   r   our_recsr5   r   )r   r   rC   r   rt     s    
zProcessState.execute_aggregatec             C   s    d| j j| jt| j| jf S )Nz%s(%s, %s, delete=%s))r   rz   r   rO   	state_strr   rC   )r7   r   r   r   r     s
    
zProcessState.__repr__N)rz   r{   r|   r   r8   rt   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 )N)r   r   rT   )r7   r   r   r   r   r   r8     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   r   ra     s    z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )r   )r^   r   r   r   r   ra     s    )r   r   r   r   r   r   )r7   r   r   r   r   )r   r   r   rt     s    
z!SaveUpdateState.execute_aggregatec             C   s   d| j jt| jf S )Nz%s(%s))r   rz   rO   r   r   )r7   r   r   r   r     s    zSaveUpdateState.__repr__N)rz   r{   r|   r   r8   rt   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 )N)r   r   rT   )r7   r   r   r   r   r   r8     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   r   r   r   ra     s    z1DeleteState.execute_aggregate.<locals>.<listcomp>c             S   s   g | ]
}|j qS r   )r   )r^   r   r   r   r   ra     s    c                s   g | ]} j | d  r|qS )r?   )r5   )r^   r_   )r   r   r   ra     s    )r   r   r   r   r   r   )r7   r   r   r   r5   r   )r   r   r   r   rt     s    
zDeleteState.execute_aggregatec             C   s   d| j jt| jf S )Nz%s(%s))r   rz   rO   r   r   )r7   r   r   r   r     s    zDeleteState.__repr__N)rz   r{   r|   r   r8   rt   r   r   r   r   r   r     s   r   N)__doc__ r   r   r<   r   r   rO   r   r   r+   r   r,   r~   rK   r   r   r   rX   rY   r   r   r   r   r   r   r   <module>   s*   i  >2(###