o
    i`                     @   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 u rd S | j }|r5|jr|d | jjj  }t|}|jj	r5|j
s+ |jkr5||s5|| |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    T/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/sqlalchemy/orm/unitofwork.py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   uselistr   	NEVER_SETPASSIVE_NO_RESULTr   delete_orphanr   
_is_orphan_newexpunge_orphaned_outside_of_sessionr   r   r   r    remove6   s0   




z$track_cascade_events.<locals>.removec                    s   ||u r|S | j }|r`|jr|d | jjj  }|d ur9t|}|jj	r9|j
s/ |jkr9||s9|| |d ur`|tjur`|tjur`|jjr`t|}||jv 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   newvalueoldvaluer   r   r   newvalue_stateoldvalue_stater   r   r    set_X   s8   







z"track_cascade_events.<locals>.set_r!   T)rawretvalr*   setN)r   r   listen)
descriptorr   r!   r*   r/   r   r   r    track_cascade_events   s   "%r5   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)r2   r   r   r   r    <lambda>   s    z)UOWTransaction.__init__.<locals>.<lambda>)r
   r   r   defaultdictr2   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 r7   )boolr?   rA   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 )zVreturn true if the given state is expired and was deleted
        previously.
        TF)expired_load_expiredr   PASSIVE_OFForm_excObjectDeletedErrorr
   _remove_newly_deletedrA   r   r   r   r    was_already_deleted   s   z"UOWTransaction.was_already_deletedc                 C   s   || j v o| j | d S )zWreturn true if the given state is marked as deleted
        within this uowtransaction.    r?   rL   r   r   r    
is_deleted   s   zUOWTransaction.is_deletedc                 C   s(   || j v r
| j | S |  | j |< }|S r7   r   )rA   r   	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.rN   TNrO   )rA   r   isdeleter   r   r    remove_state_actions   s   z#UOWTransaction.remove_state_actionsc           	      C   s   d||f}|| j v rD| j | \}}}|t j@ sB|t j@ rB|j| j}|||jt jt jB }|r8|jr8|	 }n|}|||f| j |< |S |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   SQL_OKr   implget_historydictrH   LOAD_AGAINST_COMMITTEDuses_objectsas_state)	rA   r   r   passivehashkeyrV   state_historycached_passiverX   r   r   r    get_attribute_history   s6   






z$UOWTransaction.get_attribute_historyc                 C   s   |df| j v S )NT)r<   )rA   	processorr   r   r    has_dep     zUOWTransaction.has_depc                 C   s*   ||f}|| j vrt||| j |< d S d S r7   )r<   
Preprocess)rA   rc   
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   deletedr   warnorm_utilstate_class_strr?   r   r   r;   _per_mapper_flush_actionsadd)rA   r   rT   listonlycancel_delete	operationr   r   r   r   r    register_object  s$   	


zUOWTransaction.register_objectc                 C   s0   |j jj}| j| \}}|| || d S r7   )r   r   base_mapperr@   rn   update)rA   r   post_update_colsr   r?   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r(q"|j	}||  q"d S r7   )
SaveUpdateAllrs   	DeleteAllr>   rn   _dependency_processorsper_property_preprocessorsrelationshipsviewonly_dependency_processor)rA   r   savesdeletesdepr   r   r   r    rm   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u S )NrN   r   )r   getr   r   )tupr   r   r    r8   L       z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   PopulateDictrD   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   mapper_for_depr   r    
<listcomp>U  r   z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)r   )rA   r   r?   r   r   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 r7   )rs   self_and_descendantsr;   r?   )rA   r   rT   ro   checktupr   r   r   r    states_for_mapper_hierarchyW  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 r7   )r2   per_state_flush_actions)r   recrD   r   r    	<genexpr>v  s    
z3UOWTransaction._generate_actions.<locals>.<genexpr>NrN   r   c                 S   s   g | ]}|j s|qS r   disabled)r   ar   r   r    r     s    z4UOWTransaction._generate_actions.<locals>.<listcomp>)listr<   valuesexecuter	   find_cyclesr>   r=   cyclesrZ   r   
issupersetr*   rn   r2   
difference)rA   rR   actionr   convertedger   r   rD   r    _generate_actions^  sP   
	
z UOWTransaction._generate_actionsc                 C   sd   |   }| jr!t| j|D ]}|r| }|| | |sqd S t| j|D ]}||  q(d S r7   )	r   r   r	   sort_as_subsetsr>   popexecute_aggregatesortr   )rA   r=   r/   nr   r   r   r    r     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 r7   r   )r   r   rT   ro   r   r   r    r     s    
z8UOWTransaction.finalize_flush_changes.<locals>.<genexpr>)r?   r2   itemsr   r
   rK   _register_persistent)rA   r?   isdelotherr   r   r    finalize_flush_changes  s   

z%UOWTransaction.finalize_flush_changes)FFFNN)__name__
__module____qualname__rB   propertyrE   rM   rP   rS   rU   r   PASSIVE_NO_INITIALIZErb   rd   rh   rr   rw   rm   r   memoized_propertyr   r   r   r   r   r   r   r   r   r    r6      s6    -

/
"
4r6   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 r7   )r   dependency_processor)r   mrA   uowr   r    r     s    
z/IterateMappersMixin._mappers.<locals>.<genexpr>)rg   iterr   parentr   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 )rf   )r   rg   	processedsetup_flush_actionsc                 C   s   || _ || _t | _d| _d S NF)r   rg   r2   r   r   )rA   r   rg   r   r   r    rB     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)r2   r   r;   r   r   r?   rn   r   presort_deletesrt   presort_savesr   prop_has_changesper_property_flush_actions)rA   r   delete_statessave_statesr   r   rT   ro   r   r   r    r     s>   
zPreprocess.executeNr   r   r   	__slots__rB   r   r   r   r   r    rf     s    rf   c                   @   r   )PostSortRecr   c                 G   s<   | f| }||j v r|j | S t|  |j |< }d|_|S r   )r=   object__new__r   )clsr   argsr   rR   r   r   r    r     s   


zPostSortRec.__new__c                 C   s   |  | d S r7   )r   )rA   r   recsr   r   r    r     re   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   rT   rg   c                 C   s*   || _ || _|| _|j|jj | d S r7   )r   rT   rg   r:   r   rs   rn   )rA   r   r   rT   rg   r   r   r    rB     s   zProcessAll.__init__c                 C   s4   |  |}| jr| j|| d S | j|| d S r7   )	_elementsrT   r   process_deletesprocess_saves)rA   r   r?   r   r   r    r     s   
zProcessAll.executec                 C   s   t g S r7   )r   r   r   r   r    r     s   z"ProcessAll.per_state_flush_actionsc                 C   s   d| j j| j| jf S )Nz%s(%s, isdelete=%s))	__class__r   r   rT   rD   r   r   r    __repr__%  s
   zProcessAll.__repr__c                 c   sH    |  |D ]}|j| D ]}|j| \}}|| jkr |s |V  qqd S r7   )r   r;   r?   rT   )rA   r   r   r   rT   ro   r   r   r    r   ,  s   zProcessAll._elementsN)	r   r   r   r   rB   r   r   r   r   r   r   r   r    r     s    r   c                   @   r   )PostUpdateAllr   rT   c                 C   s   || _ || _d S r7   r   )rA   r   r   rT   r   r   r    rB   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 rN   )r?   rT   r   r   r   r    r   =  s   $ z)PostUpdateAll.execute.<locals>.<listcomp>)r@   r   r   post_update)rA   r   r?   rv   r   r   r    r   ;  s   zPostUpdateAll.executeNr   r   r   r   r    r   4  s    r   c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )rx   r   c                 C      || _ ||ju s
J d S r7   r   rs   rA   r   r   r   r   r    rB   E     zSaveUpdateAll.__init__c                 C   s    t | j|| jdd| d S r   )r   save_objr   r   r   r   r   r    r   I  
   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   )r   r   r   rs   ry   SaveUpdateStater>   rn   r:   r   r   )	rA   r   r?   rs   
delete_allr   r   r   states_for_propr   r   r    r   P     

z%SaveUpdateAll.per_state_flush_actionsc                 C      d| j j| jf S Nz%s(%s)r   r   r   rD   r   r   r    r   a     zSaveUpdateAll.__repr__Nr   r   r   r   rB   r   r   r   r   r   r   r    rx   B      rx   c                   @   r   )ry   r   c                 C   r   r7   r   r   r   r   r    rB   h  r   zDeleteAll.__init__c                 C   s    t | j|| jdd| d S r   )r   
delete_objr   r   r   r   r   r    r   l  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   )r   r   r   rs   rx   DeleteStater>   rn   r:   r   r   )	rA   r   r?   rs   save_allr   r   r   r   r   r   r    r   s  r   z!DeleteAll.per_state_flush_actionsc                 C   r   r   r   rD   r   r   r    r     r   zDeleteAll.__repr__Nr   r   r   r   r    ry   e  r   ry   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	ProcessStater   rT   r   c                 C   s   || _ || _|| _d S r7   r   )rA   r   r   rT   r   r   r   r    rB     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   rT   r   rcls_r   rT   r   r    r     s    


z2ProcessState.execute_aggregate.<locals>.<listcomp>c                 S      g | ]}|j qS r   r   r   r   r   r    r         )r   r   rT   difference_updater   r   r   rA   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   rk   	state_strr   rT   rD   r   r   r    r     s   
zProcessState.__repr__Nr   r   r   r   rB   r   r   r   r   r   r    r     s
    r   c                   @   r   )	r   r   r   c                 C      || _ |jj| _d S r7   r   r   rs   rA   r   r   r   r   r    rB        zSaveUpdateState.__init__c                    sN   | j  | j fdd|D }|| t| 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    r         z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r    r     r   )r   r   r   r   r   r   )rA   r   r   r   r   r  r    r     s   
z!SaveUpdateState.execute_aggregatec                 C      d| j jt| jf S r   r   r   rk   r   r   rD   r   r   r    r        
zSaveUpdateState.__repr__Nr   r   r   r   r    r     s
    r   c                   @   r   )	r   r   c                 C   r   r7   r   r   r   r   r    rB     r   zDeleteState.__init__c                    s`   | j  | j fdd|D }|| | jgdd |D  }tfdd|D  d S )Nc                    r   r   r  r   r  r   r    r     r  z1DeleteState.execute_aggregate.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r    r     r   c                    s   g | ]} j | d  r|qS r   rO   r   )r   r   r    r     s    )r   r   r   r   r   r   r   r   )r   r   r   r    r     s   
zDeleteState.execute_aggregatec                 C   r  r   r  rD   r   r   r    r     r  zDeleteState.__repr__Nr   r   r   r   r    r     s
    r   N)__doc__ r   r   rI   r   r   rk   r   r	   r5   r   r6   r   rf   r   r   r   rx   ry   r   r   r   r   r   r   r    <module>   s,   i  >2(###