o
    6	f;                     @   s   U d Z ddlmZmZ ddlmZmZmZmZ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	r?dd
lmZ eeeedf f Zeed< ejjZejjZG dd deZG dd dZdS )z!
Support for prepared statements
    )IntEnumauto)IteratorOptionalSequenceTupleTYPE_CHECKING)OrderedDict)	TypeAlias   )pq)Deque)PostgresQuery)PGresult.Keyc                   @   s   e Zd Ze Ze Ze ZdS )PrepareN)__name__
__module____qualname__r   NOYESSHOULD r   r   K/home/ertert/spirit/venv/lib/python3.10/site-packages/psycopg/_preparing.pyr      s    
r   c                
   @   s  e Zd ZU dZee ed< dZeed< d"ddZe	d	e
defd
dZ	d#d	e
dee deeef fddZdeded defddZe	ded defddZd"ddZd	e
dededee fddZdedededed ddf
ddZdefddZdee fd d!ZdS )$PrepareManager   prepare_thresholdd   prepared_maxreturnNc                 C   s&   t  | _t  | _d| _tt  | _d S )Nr   )r	   _counts_names_prepared_idxr   bytes_maint_commandsselfr   r   r   __init__&   s   zPrepareManager.__init__queryc                 C   s   | j | jfS N)r(   types)r(   r   r   r   key2   s   zPrepareManager.keypreparec                 C   s   |du s	| j du rtjdfS | |}| j|}|r tj|fS | j|d}|| j ks.|rBd| j 	 }|  jd7  _tj
|fS tjdfS )zP
        Check if a query is prepared, tell back whether to prepare it.
        FN    r   _pg3_r   )r   r   r   r+   r!   getr   r    r"   encoder   )r&   r(   r,   r+   namecountr   r   r   r/   6   s   




zPrepareManager.getprepresultsr   c                 C   sR   | j s|tjkr'|D ]}|jtkrq
|j}|r&|ds |dkr&|    S q
dS )zCheck if we need to discard our entire state: it should happen on
        rollback or on dropping objects, because the same object may get
        recreated and postgres would fail internal lookups.
        s   DROP s   ROLLBACKF)r!   r   r   status
COMMAND_OKcommand_status
startswithclear)r&   r3   r4   resultcmdstatr   r   r   _should_discardP   s   
zPrepareManager._should_discardc                 C   s:   t | dkrdS | d j}t|  krtkrdS  dS dS )zCReturn False if 'results' are invalid for prepared statement cache.r   Fr   T)lenr5   r6   	TUPLES_OK)r4   r5   r   r   r   _check_results^   s   
zPrepareManager._check_resultsc                 C   sX   t | j| jkr| jjdd t | j| jkr*| jjddd }| jd|  dS dS )zEvict an old value from the cache.

        If it was prepared, deallocate it. Do it only once: if the cache was
        resized, deallocate gradually.
        F)lastr   s   DEALLOCATE N)r=   r    r   popitemr!   r$   append)r&   r1   r   r   r   _rotatel   s   zPrepareManager._rotater1   c                 C   s   | j du rdS | |}|| jv r2|tju r!| j|= || j|< dS | j|  d7  < | j| dS || jv r?| j| dS |tju rK|| j|< |S d| j|< |S )zHandle 'query' for possible addition to the cache.

        If a new entry has been added, return its key. Return None otherwise
        (meaning the query is already in cache or cache is not enabled).
        Nr   )r   r+   r    r   r   r!   move_to_end)r&   r(   r3   r1   r+   r   r   r   maybe_add_to_cachey   s&   
	







z!PrepareManager.maybe_add_to_cacher+   c                 C   sF   |  ||rdS | |s| j|d | j|d dS |   dS )zValidate cached entry with 'key' by checking query 'results'.

        Possibly record a command to perform maintenance on database side.
        N)r<   r?   r!   popr    rC   )r&   r+   r3   r1   r4   r   r   r   validate   s   
zPrepareManager.validatec                 C   s8   | j   | jr| j  | j  | jd dS dS )zClear the cache of the maintenance commands.

        Clear the internal state and prepare a command to clear the state of
        the server.
        s   DEALLOCATE ALLTF)r    r9   r!   r$   rB   r%   r   r   r   r9      s   


zPrepareManager.clearc                 c   s"    | j r| j  V  | j sdS dS )zY
        Iterate over the commands needed to align the server state to our state
        N)r$   popleftr%   r   r   r   get_maintenance_commands   s   z'PrepareManager.get_maintenance_commands)r   Nr)   )r   r   r   r   r   int__annotations__r   r'   staticmethodr   r   r+   boolr   r   r#   r/   r   r<   r?   rC   rE   rG   r9   r   rI   r   r   r   r   r      sP   
 




!
r   N)__doc__enumr   r   typingr   r   r   r   r   collectionsr	   typing_extensionsr
    r   _compatr   _queriesr   pq.abcr   r#   rJ   r   rK   
ExecStatusr6   r>   r   r   r   r   r   r   <module>   s    