a
    [gi                     @  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rd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 }|rd|jr&|d | jjj  }t|}|jj	rd |j
krd||sd|| |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    g/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/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r8dnd |d ur|tjur|tj	ur|j
jrt|}|j|r|r||jv 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+   removeI   s.    

z$track_cascade_events.<locals>.removec           	        s   ||u r|S | j }|r|jr&|d | jjj  }|d urlt|}|jj	rl |j
krl||sl|| |d ur|tjur|tjur|jjrt|}||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/   r1   r0   r2   )	r#   ZnewvalueZoldvaluer%   r&   r'   r(   Znewvalue_stateZoldvalue_stater)   r*   r+   set_k   s<    




z"track_cascade_events.<locals>.set_Zappend_wo_mutationT)rawinclude_keyr,   )r5   retvalr6   r3   setN)r   r   listen)Z
descriptorr(   r,   r3   r4   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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d9d d!d!d!d"d#d!d$d%d&Zd'd( Zd)d* Zejd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4d5d6Zd3d4d7d8ZdS ):UOWTransactionr   r   r   ZtransactionzDict[str, Any]r
   z7util.defaultdict[Mapper[Any], Set[DependencyProcessor]]depsz6util.defaultdict[Mapper[Any], Set[InstanceState[Any]]]mappers)r   c                 C  sR   || _ i | _tt| _tt| _i | _i | _t | _	i | _
tdd | _d S )Nc                   S  s   t  t  fS N)r8   r*   r*   r*   r+   <lambda>       z)UOWTransaction.__init__.<locals>.<lambda>)r   r
   r   defaultdictr8   r<   r=   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>   )boolrE   rG   r*   r*   r+   has_work   s    zUOWTransaction.has_workc                 C  sB   |j r>z||tj W n$ tjy<   | j|g Y dS 0 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rG   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   rO   r*   r*   r+   
is_deleted   s    zUOWTransaction.is_deletedc                 C  s,   || j v r| j | S |  | j |< }|S d S r>   r	   )rG   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   TNrQ   )rG   r#   isdeleter*   r*   r+   remove_state_actions   s    z#UOWTransaction.remove_state_actionsc           	      C  s   d||f}|| j v r| j | \}}}|t j@ s|t j@ r|j| j}|||jt jt jB t jB }|rv|j	rv|
 }n|}|||f| j |< nP|j| j}|||j|t jB 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dictrL   ZLOAD_AGAINST_COMMITTEDZNO_RAISEZuses_objectsZas_state)	rG   r#   r   ZpassiveZhashkeyrW   Zstate_historyZcached_passiverX   r*   r*   r+   get_attribute_history   sH    





z$UOWTransaction.get_attribute_historyc                 C  s   |df| j v S )NT)rB   )rG   	processorr*   r*   r+   has_dep*  s    zUOWTransaction.has_depc                 C  s&   ||f}|| j vr"t||| j |< d S r>   )rB   
Preprocess)rG   r[   
fromparentr   r*   r*   r+   register_preprocessor-  s    
z$UOWTransaction.register_preprocessorFNzInstanceState[Any]rI   zOptional[str]zOptional[MapperProperty])r#   rU   listonlycancel_delete	operationr(   returnc                 C  s   | j |s8|js4|d ur4tdt|||f  dS || jvr~|jj	}|| j
v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_strrE   r   r   r=   _per_mapper_flush_actionsadd)rG   r#   rU   r`   ra   rb   r(   r   r*   r*   r+   register_object2  s"    	


zUOWTransaction.register_objectc                 C  s0   |j jj}| j| \}}|| || d S r>   )r   r   base_mapperrF   rg   update)rG   r#   Zpost_update_colsr   rE   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rPqD|j	}||  qDd S r>   )
SaveUpdateAllri   	DeleteAllrD   rg   Z_dependency_processorsZper_property_preprocessorsZrelationshipsZviewonlyZ_dependency_processor)rG   r   ZsavesZdeletesdepr(   r*   r*   r+   rf   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+   r?   s  r@   z0UOWTransaction._mapper_for_dep.<locals>.<lambda>)r   ZPopulateDictrJ   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ro   Zmapper_for_depr*   r+   
<listcomp>|  r@   z8UOWTransaction.filter_states_for_dep.<locals>.<listcomp>)rr   )rG   ro   rE   r*   rv   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 r>   )ri   self_and_descendantsr=   rE   )rG   r   rU   r`   Zchecktupr#   r*   r*   r+   states_for_mapper_hierarchy~  s
    z*UOWTransaction.states_for_mapper_hierarchyc                   sB  d}t  j D ]}| rd}q|s q.q t jt  j   _}|r( fdd|D }t  jD ]}d|v s|d j	s|d j	s|
|r j| qn|d |v r j| ||d  D ]} j||d f qqn|d |v rn j| ||d  D ]} j|d |f q
qndd	  j D |S )
z}Generate the full, unsorted collection of PostSortRecs as
        well as dependency pairs for this UOWTransaction.

        FTc                   s   i | ]}|t | qS r*   )r8   per_state_flush_actions)rt   recrJ   r*   r+   
<dictcomp>  s   z4UOWTransaction._generate_actions.<locals>.<dictcomp>Nr   r   c                 S  s   h | ]}|j s|qS r*   disabled)rt   ar*   r*   r+   	<setcomp>  s   z3UOWTransaction._generate_actions.<locals>.<setcomp>)listrB   valuesexecuter   Zfind_cyclesrD   rC   cyclesr   
issupersetr3   rg   
difference)rG   rS   actionr   convertedgero   r*   rJ   r+   _generate_actions  sH    	


z UOWTransaction._generate_actionsNone)rc   c                 C  sx   |   }t|dd d}| jrVt| j|D ]&}t|}|r,| }|| | q8q,nt	| j|D ]}|
|  qdd S )Nc                 S  s   | j S r>   )sort_key)r$   r*   r*   r+   r?     r@   z(UOWTransaction.execute.<locals>.<lambda>r)   )r   sortedr   r   Zsort_as_subsetsrD   r8   popexecute_aggregatesortr   )rG   rC   Zsubsetr4   nr|   r*   r*   r+   r     s    zUOWTransaction.executec                 C  sV   | j s
dS t| j }dd | j  D }||}|rB| j| |rR| 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   h | ]\}\}}|r|qS r*   r*   )rt   ru   rU   r`   r*   r*   r+   r     s   z8UOWTransaction.finalize_flush_changes.<locals>.<setcomp>)rE   r8   itemsr   r   rN   Z_register_persistent)rG   rE   Zisdelotherr*   r*   r+   finalize_flush_changes  s    

z%UOWTransaction.finalize_flush_changes)FFFNN)__name__
__module____qualname____annotations__rH   propertyrK   rP   rR   rT   rV   r
   ZPASSIVE_NO_INITIALIZErZ   r\   r_   rh   rl   rf   r   Zmemoized_propertyrr   rx   rz   r   r   r   r*   r*   r*   r+   r;      s>   
-

5     "
4r;   c                   @  s   e Zd ZdZdd ZdS )IterateMappersMixinr*   c                   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>   )rr   dependency_processor)rt   mrG   uowr*   r+   	<genexpr>  s   z/IterateMappersMixin._mappers.<locals>.<genexpr>)r^   iterr   parentry   r   r   r*   r   r+   _mappers  s
    zIterateMappersMixin._mappersN)r   r   r   	__slots__r   r*   r*   r*   r+   r     s   r   c                   @  s    e Zd ZdZdd Zdd ZdS )r]   )r   r^   	processedsetup_flush_actionsc                 C  s   || _ || _t | _d| _d S NF)r   r^   r8   r   r   )rG   r   r^   r*   r*   r+   rH      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)r8   r   r=   r   r   rE   rg   r   Zpresort_deletesrj   Zpresort_savesr   Zprop_has_changesZper_property_flush_actions)rG   r   Zdelete_statesZsave_statesr   r#   rU   r`   r*   r*   r+   r     s:    zPreprocess.executeN)r   r   r   r   rH   r   r*   r*   r*   r+   r]     s   r]   c                   @  s    e Zd ZdZdd Zdd ZdS )PostSortRecr~   c                 G  s@   | f| }||j v r|j | S t|  |j |< }d|_|S d S r   )rC   object__new__r   )clsr   argsr   rS   r*   r*   r+   r   -  s    


zPostSortRec.__new__c                 C  s   |  | d S r>   )r   )rG   r   recsr*   r*   r+   r   6  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   rU   r^   r   c                 C  s:   || _ d| j j|f| _|| _|| _|j|jj | d S )Nr   )r   r   rU   r^   r<   r   ri   rg   )rG   r   r   rU   r^   r*   r*   r+   rH   =  s    zProcessAll.__init__c                 C  s2   |  |}| jr | j|| n| j|| d S r>   )	_elementsrU   r   process_deletesprocess_saves)rG   r   rE   r*   r*   r+   r   J  s    
zProcessAll.executec                 C  s   t g S r>   )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   rU   rJ   r*   r*   r+   __repr__X  s
    zProcessAll.__repr__c                 c  sF   |  |D ]6}|j| D ]&}|j| \}}|| jkr|s|V  qq
d S r>   )r   r=   rE   rU   )rG   r   r   r#   rU   r`   r*   r*   r+   r   _  s
    zProcessAll._elementsN)	r   r   r   r   rH   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   rU   r   c                 C  s   || _ || _d|j|f| _d S )Nr   )r   rU   	_sort_keyr   )rG   r   r   rU   r*   r*   r+   rH   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   )rE   rU   rs   r   r*   r+   rw   s  r@   z)PostUpdateAll.execute.<locals>.<listcomp>)r   	preloadedorm_persistencerF   r   Zpost_update)rG   r   persistencerE   rk   r*   r   r+   r   o  s    zPostUpdateAll.executeN)r   r   r   r   rH   r   preload_moduler   r*   r*   r*   r+   r   g  s   r   c                   @  s:   e Zd ZdZdd Zeddd Zdd Zd	d
 Z	dS )rm   r   r   c                 C  s$   || _ d|jf| _||ju s J d S )Nrm   r   r   r   ri   rG   r   r   r*   r*   r+   rH   {  s    zSaveUpdateAll.__init__r   c                 C  s$   t jj| j|| jdd| d S r   )r   r   r   save_objr   rz   r   r*   r*   r+   r     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   )r   rz   r   ri   rn   SaveUpdateStaterD   rg   r<   rx   r{   )	rG   r   rE   ri   Z
delete_allr#   r   ro   states_for_propr*   r*   r+   r{     s    

z%SaveUpdateAll.per_state_flush_actionsc                 C  s   d| j j| jf S Nz%s(%s)r   r   r   rJ   r*   r*   r+   r     s    zSaveUpdateAll.__repr__N
r   r   r   r   rH   r   r   r   r{   r   r*   r*   r*   r+   rm   x  s   
rm   c                   @  s:   e Zd ZdZdd Zeddd Zdd Zd	d
 Z	dS )rn   r   c                 C  s$   || _ d|jf| _||ju s J d S )Nrn   r   r   r*   r*   r+   rH     s    zDeleteAll.__init__r   c                 C  s$   t jj| j|| jdd| d S r   )r   r   r   
delete_objr   rz   r   r*   r*   r+   r     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   )r   rz   r   ri   rm   DeleteStaterD   rg   r<   rx   r{   )	rG   r   rE   ri   Zsave_allr#   r   ro   r   r*   r*   r+   r{     s    

z!DeleteAll.per_state_flush_actionsc                 C  s   d| j j| jf S r   r   rJ   r*   r*   r+   r     s    zDeleteAll.__repr__Nr   r*   r*   r*   r+   rn     s   
rn   c                   @  s(   e Zd ZdZdd Zdd Zdd ZdS )	ProcessState)r   rU   r#   r   c                 C  s"   || _ d|jf| _|| _|| _d S Nr   )r   r   rU   r#   )rG   r   r   rU   r#   r*   r*   r+   rH     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  u r|ju r|ju r|qS r*   )r   r   rU   rt   rcls_r   rU   r*   r+   rw     s
   


z2ProcessState.execute_aggregate.<locals>.<listcomp>c                 S  s   g | ]
}|j qS r*   r#   r   r*   r*   r+   rw     r@   )r   r   rU   difference_updater#   r   r   )rG   r   r   our_recsrE   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   re   	state_strr#   rU   rJ   r*   r*   r+   r     s    
zProcessState.__repr__N)r   r   r   r   rH   r   r   r*   r*   r*   r+   r     s   r   c                   @  s2   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  s"   || _ |jj| _d| jjf| _d S r   r#   r   ri   r   r   rG   r   r#   r*   r*   r+   rH     s    
zSaveUpdateState.__init__r   c                   sV   t jj}| j | j fdd|D }|| || jgdd |D  | d S )Nc                   s$   g | ]}|j  u r|ju r|qS r*   r   r   r   r   r   r*   r+   rw     s   z5SaveUpdateState.execute_aggregate.<locals>.<listcomp>c                 S  s   g | ]
}|j qS r*   r   r   r*   r*   r+   rw     r@   )r   r   r   r   r   r   r   r#   )rG   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   re   r   r#   rJ   r*   r*   r+   r     s    
zSaveUpdateState.__repr__N	r   r   r   r   rH   r   r   r   r   r*   r*   r*   r+   r     s
   
r   c                   @  s2   e Zd ZdZdd Zeddd Zdd Zd	S )
r   r   c                 C  s"   || _ |jj| _d| jjf| _d S )Nr   r   r   r*   r*   r+   rH     s    
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                   s$   g | ]}|j  u r|ju r|qS r*   r   r   r   r*   r+   rw     s   z1DeleteState.execute_aggregate.<locals>.<listcomp>c                 S  s   g | ]
}|j qS r*   r   r   r*   r*   r+   rw     r@   c                   s   g | ]} j | d  r|qS r   rQ   rs   )r   r*   r+   rw     r@   )r   r   r   r   r   r   r#   r   )rG   r   r   r   r   rE   r*   )r   r   r   r+   r   
  s    
zDeleteState.execute_aggregatec                 C  s   d| j jt| jf S r   r   rJ   r*   r*   r+   r     s    
zDeleteState.__repr__Nr   r*   r*   r*   r+   r     s
   
r   N)(__doc__
__future__r   typingr   r   r   r   r    r
   r   rM   r   re   r   r   
dependencyr   Z
interfacesr   r   r   r   r   r   r#   r   r:   r;   r   r]   r   r   r   rm   rn   r   r   r   r*   r*   r*   r+   <module>
   sB   r  O2-%%$