o
    Rcl                     @   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   ;D:\Flask\env\Lib\site-packages\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 u rd S | j }|rB|jr|d | jjj  }t|}|jj	rB|j
r)|jr. |jkrB||sB |jkr=t|| || |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 u rd S | j }| jjj  }|r|jr||jrdnd |d urO|tjurQ|tj	urS|j
jrUt|}|j|rW|rJ||jv rJ|| d S d|_d S d S d S d S d S 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   s2   


	z$track_cascade_events.<locals>.removec                    s   ||u r|S | j }|rm|jr|d | jjj  }|d urFt|}|jj	rF|j
r-|jr2 |jkrF||sF |jkrAt|| || |d urm|tjurm|tjurm|jjrmt|}||jv rm|j|rm|| |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>   s    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 dS  tjy   | j|g Y dS w 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 v o| j | d S )z[Return ``True`` if the given state is marked as deleted
        within this uowtransaction.    r;   rE   r   r   r   
is_deleted   s   zUOWTransaction.is_deletedc                 C   s(   || j v r
| j | S |  | j |< }|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.rG   TNrH   )r=   r   isdeleter   r   r   remove_state_actions   s   z#UOWTransaction.remove_state_actionsc           	      C   s   d||f}|| j v rG| j | \}}}|t j@ sE|t j@ rE|j| j}|||jt jt jB t jB }|r;|j	r;|
 }n|}|||f| j |< |S |j| j}|||j|t jB t jB }|re|j	re|
 }n|}|||f| j |< |S )zOFacade to attributes.get_state_history(), including
        caching of results.history)r   ZSQL_OKr   implZget_historydictrB   ZLOAD_AGAINST_COMMITTEDZNO_RAISEZuses_objectsZas_state)	r=   r   r   ZpassiveZhashkeyrN   Zstate_historyZcached_passiverO   r   r   r   get_attribute_history   sJ   





z$UOWTransaction.get_attribute_historyc                 C   s   |df| j v S )NT)r8   )r=   	processorr   r   r   has_dep      zUOWTransaction.has_depc                 C   s*   ||f}|| j vrt||| j |< d S d S r3   )r8   
Preprocess)r=   rR   
fromparentr   r   r   r   register_preprocessor#  s   
z$UOWTransaction.register_preprocessorFNc                 C   s   | j |s|js|d urtdt|||f  dS || jvr@|jj	}|| j
vr/| | | j
| | ||f| j|< dS |sM|sF|rM|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   r7   _per_mapper_flush_actionsadd)r=   r   rL   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r(q"|j	}||  q"d 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u S )NrG   r   )r   getr   r   )tupr   r   r   r4   i       z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   ZPopulateDictr@   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  rg   z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)rh   )r=   rd   r;   r   rl   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_descendantsr7   r;   )r=   r   rL   r\   Zchecktupr   r   r   r   states_for_mapper_hierarchyt  s   z*UOWTransaction.states_for_mapper_hierarchyc                    sH  	 d}t  j D ]	}| rd}q
|snqt jt  j   _}|rt	 fdd|D }t  jD ][}d|v sN|d j
sN|d j
sN||rU j| q9|d |v ru j| ||d  D ]} j||d f qgq9|d |v r j| ||d  D ]} j|d |f qq9tdd	  j D |S )
z}Generate the full, unsorted collection of PostSortRecs as
        well as dependency pairs for this UOWTransaction.

        TFc                 3   s"    | ]}|t | fV  qd S r3   )r/   per_state_flush_actions)rj   recr@   r   r   	<genexpr>  s    
z3UOWTransaction._generate_actions.<locals>.<genexpr>NrG   r   c                 S   s   g | ]}|j s|qS r   disabled)rj   ar   r   r   rm     s    z4UOWTransaction._generate_actions.<locals>.<listcomp>)listr8   valuesexecuter   Zfind_cyclesr:   r9   cyclesrP   ru   
issupersetr+   r[   r/   
difference)r=   rJ   actionrz   convertedgerd   r   r@   r   _generate_actions{  sR   
	
z UOWTransaction._generate_actionsc                 C   s|   |   }t|dd d}| jr-t| j|D ]}t|}|r*| }|| | |sqd S t	| j|D ]}|
|  q4d S )Nc                 S   s   | j S r3   )sort_key)r    r   r   r   r4     s    z(UOWTransaction.execute.<locals>.<lambda>r#   )r   sortedrz   r   Zsort_as_subsetsr:   r/   popexecute_aggregatesortry   )r=   r9   Zsubsetr,   nrr   r   r   r   ry     s&   zUOWTransaction.executec                 C   s^   | j sdS t| j }tdd | j  D }||}|r#| j| |r-| j| dS 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   )rj   rk   rL   r\   r   r   r   rs     s    
z8UOWTransaction.finalize_flush_changes.<locals>.<genexpr>)r;   r/   itemsr|   r   rD   Z_register_persistent)r=   r;   Zisdelotherr   r   r   finalize_flush_changes  s   

z%UOWTransaction.finalize_flush_changes)FFFNN)r   
__module____qualname__r>   propertyrA   rF   rI   rK   rM   r   ZPASSIVE_NO_INITIALIZErQ   rS   rW   r]   ra   rZ   r   Zmemoized_propertyrh   rn   rp   r   ry   r   r   r   r   r   r2      s6    -

5
"
4r2   c                   @   s   e Zd Zdd ZdS )IterateMappersMixinc                    s.    j rt fdd jjjD S  jjjS )Nc                 3   s$    | ]}j | jf r|V  qd S r3   )rh   dependency_processor)rj   mr=   uowr   r   rs     s    
z/IterateMappersMixin._mappers.<locals>.<genexpr>)rV   iterr   parentro   r   r   r   r   r   _mappers  s
   
zIterateMappersMixin._mappersN)r   r   r   r   r   r   r   r   r     s    r   c                   @       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 ]$}|j| | jD ]}|j| \}}|s.|r)|| q|| qq|r?| j|| | j	| |rN| j
|| | j	| |sR|rp| jsn| j||dse| j||drn| j| d| _dS dS NTF)r/   r   r7   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   rL   r\   r   r   r   ry     s>   
zPreprocess.executeN)r   r   r   	__slots__r>   ry   r   r   r   r   rU     s    rU   c                   @   r   )PostSortRecrt   c                 G   s<   | f| }||j v r|j | S t|  |j |< }d|_|S r   )r9   object__new__ru   )clsr   argsr   rJ   r   r   r   r   !  s   


zPostSortRec.__new__c                 C   s   |  | d S r3   )ry   )r=   r   recsr   r   r   r   *  rT   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   rL   rV   r   c                 C   s:   || _ d| j j|f| _|| _|| _|j|jj | d S )Nr   )r   r   rL   rV   r6   r   r^   r[   )r=   r   r   rL   rV   r   r   r   r>   1  s   zProcessAll.__init__c                 C   s4   |  |}| jr| j|| d S | j|| d S r3   )	_elementsrL   r   process_deletesprocess_saves)r=   r   r;   r   r   r   ry   >  s   
zProcessAll.executec                 C   s   t g S r3   )r   r   r   r   r   rq   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   rL   r@   r   r   r   __repr__L  s
   zProcessAll.__repr__c                 c   sH    |  |D ]}|j| D ]}|j| \}}|| jkr |s |V  qqd S r3   )r   r7   r;   rL   )r=   r   r   r   rL   r\   r   r   r   r   S  s   zProcessAll._elementsN)	r   r   r   r   r>   ry   rq   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   rL   r   c                 C   s   || _ || _d|j|f| _d S )Nr   )r   rL   	_sort_keyr   )r=   r   r   rL   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 rG   )r;   rL   ri   r   r   r   rm   g  s   $ z)PostUpdateAll.execute.<locals>.<listcomp>)r   	preloadedorm_persistencer<   r   Zpost_update)r=   r   persistencer;   r`   r   r   r   ry   c  s   zPostUpdateAll.executeN)r   r   r   r   r>   r   preload_modulery   r   r   r   r   r   [  s
    r   c                   @   :   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   $   || _ d|jf| _||ju sJ d S )Nrb   r   r   r   r^   r=   r   r   r   r   r   r>   o     zSaveUpdateAll.__init__r   c                 C   s$   t jj| j|| jdd| d S r   )r   r   r   save_objr   rp   r   r   r   r   ry   t  
   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   )rw   rp   r   r^   rc   SaveUpdateStater:   r[   r6   rn   rq   )	r=   r   r;   r^   Z
delete_allr   r}   rd   states_for_propr   r   r   rq   |     

z%SaveUpdateAll.per_state_flush_actionsc                 C      d| j j| jf S Nz%s(%s)r   r   r   r@   r   r   r   r        zSaveUpdateAll.__repr__N
r   r   r   r   r>   r   r   ry   rq   r   r   r   r   r   rb   l      
rb   c                   @   r   )rc   r   c                 C   r   )Nrc   r   r   r   r   r   r>     r   zDeleteAll.__init__r   c                 C   s$   t jj| j|| jdd| d S r   )r   r   r   
delete_objr   rp   r   r   r   r   ry     r   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   )rw   rp   r   r^   rb   DeleteStater:   r[   r6   rn   rq   )	r=   r   r;   r^   Zsave_allr   r}   rd   r   r   r   r   rq     r   z!DeleteAll.per_state_flush_actionsc                 C   r   r   r   r@   r   r   r   r     r   zDeleteAll.__repr__Nr   r   r   r   r   rc     r   rc   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ProcessState)r   rL   r   r   c                 C   s"   || _ d|jf| _|| _|| _d S Nr   )r   r   rL   r   )r=   r   r   rL   r   r   r   r   r>     s   
zProcessState.__init__c                    sl   | j  | j| j fdd|D }|| | jgdd |D  }r.|| d S || d S )Nc                    s.   g | ]}|j  u r|ju r|ju r|qS r   )r   r   rL   rj   rcls_r   rL   r   r   rm     s    z2ProcessState.execute_aggregate.<locals>.<listcomp>c                 S      g | ]}|j qS r   r   r   r   r   r   rm         )r   r   rL   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   rL   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                   @   2   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   "   || _ |jj| _d| jjf| _d S r   r   r   r^   r   r   r=   r   r   r   r   r   r>        
zSaveUpdateState.__init__r   c                    sV   t jj}| j | j fdd|D }|| || jgdd |D  | d S )Nc                    $   g | ]}|j  u r|ju r|qS r   r   r   r   r   r   r   r   rm         
z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   rm     r   )r   r   r   r   r   r   r   r   )r=   r   r   r   r   r   r   r   r     s   
z!SaveUpdateState.execute_aggregatec                 C      d| j jt| jf S r   r   r   rY   r   r   r@   r   r   r   r        
zSaveUpdateState.__repr__N	r   r   r   r   r>   r   r   r   r   r   r   r   r   r     s    
r   c                   @   r   )
r   r   c                 C   r   )Nr   r   r   r   r   r   r>     r   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                    r   r   r   r   r   r   r   rm     r   z1DeleteState.execute_aggregate.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   rm     r   c                    s   g | ]} j | d  r|qS r   rH   ri   )r   r   r   rm   	  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   r   r   r   r@   r   r   r   r     r   zDeleteState.__repr__Nr   r   r   r   r   r     s    
r   N)__doc__ r   r   rC   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-%%$