o
    - hi                     @  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
l	mZ ddl	mZ ddl	mZ ddl	mZ ddlmZ erpd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ZG dd dZG dd deZG dd d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.

    )annotations)Any)Dict)Optional)Set)TYPE_CHECKING   
attributes)exc)util   )event)topological)DependencyProcessor)MapperProperty)Mapper)Session)SessionTransaction)InstanceStatec                   s   |j   fdd} fdd} fdd}tj| d|ddd	 tj| d
|dddd tj| d|dddd tj| d|dddd dS )z\Establish event listeners on object attributes which handle
    cascade-on-set/append.

    c                   sh   |d u rd S | j }|r2|jr|d | jjj  }t|}|jj	r2 |j
kr2||s2|| |S )Nzcollection append)session_warn_on_events_flush_warningmanagermapper_propsr
   instance_state_cascadesave_updatekey_contains_state_save_or_update_statestateitem	initiatorkwsesspropZ
item_stater    a/var/www/html/figdemos/bartoux_crm/venv/lib/python3.10/site-packages/sqlalchemy/orm/unitofwork.pyappend2   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+   removeI   s0   




z$track_cascade_events.<locals>.removec           	        s   ||u r|S | j }|r]|jr|d | jjj  }|d ur6t|}|jj	r6 |j
kr6||s6|| |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/   r0   r2   r1   r3   )	r#   newvalueoldvaluer%   r&   r'   r(   Znewvalue_stateZoldvalue_stater)   r*   r+   set_k   s4   







z"track_cascade_events.<locals>.set_append_wo_mutationT)rawinclude_keyr,   )r:   retvalr;   r5   setN)r   r   listen)
descriptorr(   r,   r5   r8   r*   r)   r+   track_cascade_events+   s    "$

r@   c                   @  s   e Zd ZU ded< ded< ded< ded< d	ed
< d=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*d+Zd,d- Zd.d/ Zejd0d1 Zd2d3 Zd4d5 Zd6d7 Zd@d9d:Zd@d;d<ZdS )AUOWTransactionr   r   r   transactionzDict[str, Any]r
   z7util.defaultdict[Mapper[Any], Set[DependencyProcessor]]depsz6util.defaultdict[Mapper[Any], Set[InstanceState[Any]]]mappersc                 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=   rC   rD   presort_actionspostsort_actionsdependenciesstatespost_update_states)selfr   r*   r*   r+   __init__   s   zUOWTransaction.__init__c                 C  s
   t | jS rE   )boolrK   rM   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)expired_load_expiredr
   PASSIVE_OFForm_excObjectDeletedErrorr   _remove_newly_deletedrM   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   rK   rX   r*   r*   r+   
is_deleted   s   zUOWTransaction.is_deletedc                 C  s(   || j v r
| j | S |  | j |< }|S rE   r	   )rM   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.r   TNrZ   )rM   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
   SQL_OKr   implget_historydictrT   LOAD_AGAINST_COMMITTEDNO_RAISEuses_objectsas_state)	rM   r#   r   passiveZhashkeyra   Zstate_historyZcached_passiverc   r*   r*   r+   get_attribute_history   sJ   





z$UOWTransaction.get_attribute_historyc                 C  s   |df| j v S )NT)rH   )rM   	processorr*   r*   r+   has_dep*     zUOWTransaction.has_depc                 C  s*   ||f}|| j vrt||| j |< d S d S rE   )rH   
Preprocess)rM   rl   
fromparentr   r*   r*   r+   register_preprocessor-  s   
z$UOWTransaction.register_preprocessorFNr#   InstanceState[Any]r_   rO   listonlycancel_delete	operationOptional[str]r(   Optional[MapperProperty]returnc                 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_strrK   r   r   rD   _per_mapper_flush_actionsadd)rM   r#   r_   rs   rt   ru   r(   r   r*   r*   r+   register_object2  s$   	


zUOWTransaction.register_objectc                 C  s0   |j jj}| j| \}}|| || d S rE   )r   r   base_mapperrL   r~   update)rM   r#   Zpost_update_colsr   rK   colsr*   r*   r+   register_post_updateT  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 rE   )
SaveUpdateAllr   	DeleteAllrJ   r~   _dependency_processorsZper_property_preprocessorsrelationshipsviewonly_dependency_processor)rM   r   ZsavesZdeletesdepr(   r*   r*   r+   r}   Z  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 )Nr   r   )r   getr   r(   )tupr*   r*   r+   rF   s       z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   PopulateDictrP   r*   r*   r+   _mapper_for_deph  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>|  r   z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)r   )rM   r   rK   r*   r   r+   filter_states_for_depv  s   z$UOWTransaction.filter_states_for_depc                 c  s@    ||f}|j jD ]}| j| D ]}| j| |kr|V  qq	d S rE   )r   self_and_descendantsrD   rK   )rM   r   r_   rs   Zchecktupr#   r*   r*   r+   states_for_mapper_hierarchy~  s   z*UOWTransaction.states_for_mapper_hierarchyc                   s@  	 d}t  j D ]	}| rd}q
|snqt jt  j   _}|r fdd|D }t  jD ][}d|v sL|d j	sL|d j	sL|
|rS j| q7|d |v rs j| ||d  D ]} j||d f qeq7|d |v r j| ||d  D ]} j|d |f qq7dd	  j D |S )
z}Generate the full, unsorted collection of PostSortRecs as
        well as dependency pairs for this UOWTransaction.

        TFc                   s   i | ]
}|t | qS r*   )r=   per_state_flush_actions)r   recrP   r*   r+   
<dictcomp>  s    z4UOWTransaction._generate_actions.<locals>.<dictcomp>Nr   r   c                 S  s   h | ]}|j s|qS r*   disabled)r   ar*   r*   r+   	<setcomp>  s
    z3UOWTransaction._generate_actions.<locals>.<setcomp>)listrH   valuesexecuter   find_cyclesrJ   rI   cyclesr   
issupersetr5   r~   
difference)rM   r]   actionr   convertedger   r*   rP   r+   _generate_actions  sP   
	

z UOWTransaction._generate_actionsNonec                 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 rE   )sort_key)r$   r*   r*   r+   rF     s    z(UOWTransaction.execute.<locals>.<lambda>r)   )r   sortedr   r   sort_as_subsetsrJ   r=   popexecute_aggregatesortr   )rM   rI   Zsubsetr8   nr   r*   r*   r+   r     s&   zUOWTransaction.executec                 C  sZ   | j sdS t| j }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   h | ]
\}\}}|r|qS r*   r*   )r   r   r_   rs   r*   r*   r+   r     s
    z8UOWTransaction.finalize_flush_changes.<locals>.<setcomp>)rK   r=   itemsr   r   rW   Z_register_persistent)rM   rK   Zisdelotherr*   r*   r+   finalize_flush_changes  s   

z%UOWTransaction.finalize_flush_changes)r   r   )FFFNN)r#   rr   r_   rO   rs   rO   rt   rO   ru   rv   r(   rw   rx   rO   )rx   r   )__name__
__module____qualname____annotations__rN   propertyrQ   rY   r[   r^   r`   r
   PASSIVE_NO_INITIALIZErk   rm   rq   r   r   r}   r   memoized_propertyr   r   r   r   r   r   r*   r*   r*   r+   rA      s@   
 
-

5"

4rA   c                   @  s   e Zd ZdZdd ZdS )IterateMappersMixinr*   c                   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 rE   )r   dependency_processor)r   mrM   uowr*   r+   	<genexpr>  s    
z/IterateMappersMixin._mappers.<locals>.<genexpr>)rp   iterr   parentr   r   r   r*   r   r+   _mappers  s
   
zIterateMappersMixin._mappersN)r   r   r   	__slots__r   r*   r*   r*   r+   r     s    r   c                   @      e Zd ZdZdd Zdd ZdS )ro   )r   rp   	processedsetup_flush_actionsc                 C  s   || _ || _t | _d| _d S NF)r   rp   r=   r   r   )rM   r   rp   r*   r*   r+   rN      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   rD   r   r   rK   r~   r   Zpresort_deletesr   Zpresort_savesr   Zprop_has_changesZper_property_flush_actions)rM   r   Zdelete_statesZsave_statesr   r#   r_   rs   r*   r*   r+   r     s>   
zPreprocess.executeN)r   r   r   r   rN   r   r*   r*   r*   r+   ro     s    ro   c                   @  r   )PostSortRecr   c                 G  s<   | f| }||j v r|j | S t|  |j |< }d|_|S r   )rI   object__new__r   )clsr   argsr   r]   r*   r*   r+   r   -  s   


zPostSortRec.__new__c                 C  s   |  | d S rE   )r   )rM   r   recsr*   r*   r+   r   6  rn   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   r_   rp   r   c                 C  s:   || _ d| j j|f| _|| _|| _|j|jj | d S )Nr   )r   r   r_   rp   rC   r   r   r~   )rM   r   r   r_   rp   r*   r*   r+   rN   =  s   zProcessAll.__init__c                 C  s4   |  |}| jr| j|| d S | j|| d S rE   )	_elementsr_   r   process_deletesprocess_saves)rM   r   rK   r*   r*   r+   r   J  s   
zProcessAll.executec                 C  s   t g S rE   )r   r   r*   r*   r+   r   Q  s   z"ProcessAll.per_state_flush_actionsc                 C  s   d| j j| j| jf S )Nz%s(%s, isdelete=%s))	__class__r   r   r_   rP   r*   r*   r+   __repr__X  s
   zProcessAll.__repr__c                 c  sH    |  |D ]}|j| D ]}|j| \}}|| jkr |s |V  qqd S rE   )r   rD   rK   r_   )rM   r   r   r#   r_   rs   r*   r*   r+   r   _  s   zProcessAll._elementsN)	r   r   r   r   rN   r   r   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   r_   r   c                 C  s   || _ || _d|j|f| _d S )Nr   )r   r_   	_sort_keyr   )rM   r   r   r_   r*   r*   r+   rN   j  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 r   )rK   r_   r   r   r*   r+   r   s  s   $ z)PostUpdateAll.execute.<locals>.<listcomp>)r   	preloadedorm_persistencerL   r   post_update)rM   r   persistencerK   r   r*   r   r+   r   o  s   zPostUpdateAll.executeN)r   r   r   r   rN   r   preload_moduler   r*   r*   r*   r+   r   g  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 )r   r   r   c                 C  $   || _ d|jf| _||ju sJ d S )Nr   r   r   r   r   rM   r   r   r*   r*   r+   rN   {     zSaveUpdateAll.__init__r   c                 C  s$   t jj| j|| jdd| d S r   )r   r   r   save_objr   r   r   r*   r*   r+   r     
   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   r   r   SaveUpdateStaterJ   r~   rC   r   r   )	rM   r   rK   r   Z
delete_allr#   r   r   states_for_propr*   r*   r+   r        

z%SaveUpdateAll.per_state_flush_actionsc                 C     d| j j| jf S Nz%s(%s)r   r   r   rP   r*   r*   r+   r        zSaveUpdateAll.__repr__N
r   r   r   r   rN   r   r   r   r   r   r*   r*   r*   r+   r   x      
r   c                   @  r   )r   r   c                 C  r   )Nr   r   r   r*   r*   r+   rN     r   zDeleteAll.__init__r   c                 C  s$   t jj| j|| jdd| d S r   )r   r   r   
delete_objr   r   r   r*   r*   r+   r     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   r   r   DeleteStaterJ   r~   rC   r   r   )	rM   r   rK   r   Zsave_allr#   r   r   r   r*   r*   r+   r     r   z!DeleteAll.per_state_flush_actionsc                 C  r   r   r   rP   r*   r*   r+   r     r   zDeleteAll.__repr__Nr   r*   r*   r*   r+   r     r   r   c                   @  s(   e Zd ZdZdd Zdd Zdd ZdS )	ProcessState)r   r_   r#   r   c                 C  s"   || _ d|jf| _|| _|| _d S Nr   )r   r   r_   r#   )rM   r   r   r_   r#   r*   r*   r+   rN     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   r_   r   rcls_r   r_   r*   r+   r     s    


z2ProcessState.execute_aggregate.<locals>.<listcomp>c                 S     g | ]}|j qS r*   r#   r   r*   r*   r+   r         )r   r   r_   difference_updater#   r   r   )rM   r   r   our_recsrK   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   r{   	state_strr#   r_   rP   r*   r*   r+   r     s   
zProcessState.__repr__N)r   r   r   r   rN   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   rM   r   r#   r*   r*   r+   rN        
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+   r         z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c                 S  r   r*   r   r   r*   r*   r+   r     r   )r   r   r   r   r   r   r   r#   )rM   r   r   r   r   r*   r  r+   r     s   
z!SaveUpdateState.execute_aggregatec                 C     d| j jt| jf S r   r   r   r{   r   r#   rP   r*   r*   r+   r        
zSaveUpdateState.__repr__N	r   r   r   r   rN   r   r   r   r   r*   r*   r*   r+   r     s    
r   c                   @  r   )
r   r   c                 C  r  )Nr   r  r  r*   r*   r+   rN     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+   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   rZ   r   )r   r*   r+   r     s    )r   r   r   r   r   r   r#   r   )rM   r   r   r   r   rK   r*   )r   r   r   r+   r   
  s   
zDeleteState.execute_aggregatec                 C  r	  r   r
  rP   r*   r*   r+   r     r  zDeleteState.__repr__Nr  r*   r*   r*   r+   r     s    
r   N)(__doc__
__future__r   typingr   r   r   r   r    r
   r   rU   r   r{   r   r   
dependencyr   
interfacesr   r   r   r   r   r   r#   r   r@   rA   r   ro   r   r   r   r   r   r   r   r   r*   r*   r*   r+   <module>   sD   	r  O2-%%$