o
    DDiB^                     @  s   U d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
 ddl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 d
dlmZmZmZ d
dlmZmZmZ d
dl 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,m-Z-m.Z. d
dl/m0Z0 d
dl1m2Z2 d
dl3m4Z4 d
dl5m6Z6 d
dl7m8Z8 erddl9m:Z: d
dl;m<Z<m=Z= e.dZ>ej?j@Z@ej?jAZAejBjCZCejBjDZDejEjFZFejEjGZGejEjHZHejIjJZJejIjKZKe4L ZMeNdZOG dd de	ZPdeP_QeejRgdf ZSdeTd < eePgdf ZUdeTd!< G d"d# d#ee& ZVdS )$z
psycopg connection objects
    )annotationsN)TYPE_CHECKINGAnyGeneric
NamedTuple	TypeAlias)ReferenceTyperef)warn)partial)deque)Callable   )errors)
generatorspostgrespq)PQGen	PQGenConnQueryNoTemplate)SQL
Composable)Xid)Row)AdaptersMap)IsolationLevel)LiteralStringSelfTypeVar)connection_summary)PrepareManager)capabilities)BasePipeline)ConnectionInfo)BasePool)PGconnPGresult	CursorRowpsycopgc                   @  s.   e Zd ZU dZded< 	 ded< 	 ded< dS )Notifyz8An asynchronous notification received from the database.strchannelpayloadintpidN)__name__
__module____qualname____doc____annotations__ r4   r4   Q/var/www/Datamplify/venv/lib/python3.10/site-packages/psycopg/_connection_base.pyr)   <   s   
 r)   r   NoticeHandlerNotifyHandlerc                   @  s  e Zd ZdZejZejZejZejZej	Z	ej
Z
ejZejZejZejZdddZefdd
dZdddZedddZedddZedddZejdddZdddZdddZedddZejdd dZdd!d"Zdd#d$Zedd&d'Zejdd(d'Zdd)d*Zdd+d,Zedd-d.Z e jdd/d.Z dd0d1Z!dd2d3Z"dd5d6Z#edd8d9Z$edd;d<Z%edd>d?Z&ddAdBZ'ddCdDZ(ddEdFZ)ddJdKZ*ddNdOZ+ddPdQZ,e-ddVdWZ.ddYdZZ/dd[d\Z0e-dd_d`Z1eddbdcZ2e2jddddcZ2eddedfZ3e3jddgdfZ3e4	hddidjddmdnZ5e6fddtduZ7ddxdyZ8ddzd{Z9dd|d}Z:dddZ;dddZ<dddZ=dddZ>dddZ?dddZ@dddZAdddZBdS )BaseConnectionz
    Base class for different types of connections.

    Share common functionalities such as access to the wrapped PGconn, but
    allow different interfaces (sync/async).
    pgconnr%   c                 C  s   || _ d| _d | _g | _g | _d| _d| _t | _d | _	t
 | _t| }ttj||_ttj||_|  d | _|  |  d | _d | _d | _d| _d S )NFr       )r9   _autocommit	_adapters_notice_handlers_notify_handlers_num_transactions_closedr    	_prepared_tpcr   _notifies_backlogr	   r   r8   _notice_handlernotice_handler_notify_handlernotify_handler	_pipeline_isolation_level
_read_only_deferrable_begin_statement)selfr9   wselfr4   r4   r5   __init__c   s*   
zBaseConnection.__init___BaseConnection__warnr   returnNonec                 C  s@   t | dsd S | jrd S t | drd S |t|  dt d S )Nr9   _poolz_ was deleted while still open. Please use 'with' or '.close()' to close the connection properly)hasattrclosedobject__repr__ResourceWarning)rM   rP   r4   r4   r5   __del__   s   

zBaseConnection.__del__r*   c                 C  s>   | j j d| j j }t| j}d| d| dt| ddS )N.< z at 0xx>)	__class__r0   r1   r   r9   id)rM   clsinfor4   r4   r5   rW      s   
zBaseConnection.__repr__boolc                 C  s   | j jtkS )z$`!True` if the connection is closed.)r9   statusBADrM   r4   r4   r5   rU      s   zBaseConnection.closedc                 C  s   | j jtko	| j S )z
        `!True` if the connection was interrupted.

        A broken connection is always `closed`, but wasn't closed in a clean
        way, such as using `close()` or a `!with` block.
        )r9   rd   re   r@   rf   r4   r4   r5   broken   s   zBaseConnection.brokenc                 C     | j S )z'The autocommit state of the connection.)r;   rf   r4   r4   r5   
autocommit   s   zBaseConnection.autocommitvaluec                 C     |  | d S N)_set_autocommitrM   rj   r4   r4   r5   ri         c                 C     t rl   NotImplementedErrorrn   r4   r4   r5   rm         zBaseConnection._set_autocommitPQGen[None]c                 c  s     |  dE d H  t|| _d S )Nri   )_check_intrans_genrc   r;   rn   r4   r4   r5   _set_autocommit_gen   s   z"BaseConnection._set_autocommit_genIsolationLevel | Nonec                 C  rh   )zX
        The isolation level of the new transactions started on the connection.
        )rI   rf   r4   r4   r5   isolation_level      zBaseConnection.isolation_levelc                 C  rk   rl   )_set_isolation_levelrn   r4   r4   r5   rx      ro   c                 C  rp   rl   rq   rn   r4   r4   r5   rz      rs   z#BaseConnection._set_isolation_levelc                 c  2    |  dE d H  |d urt|nd | _d| _d S )Nrx   r:   )ru   r   rI   rL   rn   r4   r4   r5   _set_isolation_level_gen      
z'BaseConnection._set_isolation_level_genbool | Nonec                 C  rh   )zX
        The read-only state of the new transactions started on the connection.
        )rJ   rf   r4   r4   r5   	read_only   ry   zBaseConnection.read_onlyc                 C  rk   rl   )_set_read_onlyrn   r4   r4   r5   r      ro   c                 C  rp   rl   rq   rn   r4   r4   r5   r      rs   zBaseConnection._set_read_onlyc                 c  r{   )Nr   r:   )ru   rc   rJ   rL   rn   r4   r4   r5   _set_read_only_gen   r}   z!BaseConnection._set_read_only_genc                 C  rh   )zY
        The deferrable state of the new transactions started on the connection.
        )rK   rf   r4   r4   r5   
deferrable   ry   zBaseConnection.deferrablec                 C  rk   rl   )_set_deferrablern   r4   r4   r5   r      ro   c                 C  rp   rl   rq   rn   r4   r4   r5   r      rs   zBaseConnection._set_deferrablec                 c  r{   )Nr   r:   )ru   rc   rK   rL   rn   r4   r4   r5   _set_deferrable_gen   r}   z"BaseConnection._set_deferrable_gen	attributec                 c  sr    | j j }tkr| jr| j E d H  | j j}|tkr7| jr(td|dtd|dt	|j
 d S )Nzcan't change z2 now: connection.transaction() context in progressz' now: connection in transaction status )r9   transaction_statusIDLErH   	_sync_genr?   eProgrammingErrorr   TransactionStatusname)rM   r   rd   r4   r4   r5   ru      s   

z!BaseConnection._check_intrans_genr#   c                 C  s
   t | jS )z>A `ConnectionInfo` attribute to inspect connection properties.)r#   r9   rf   r4   r4   r5   rb     s   
zBaseConnection.infor   c                 C  s   | j s	ttj| _ | j S rl   )r<   r   r   adaptersrf   r4   r4   r5   r     s   zBaseConnection.adaptersBaseConnection[Row]c                 C  s   | S rl   r4   rf   r4   r4   r5   
connection     zBaseConnection.connectionr-   c                 C     | j jS )zReturn the file descriptor of the connection.

        This function allows to use the connection as file-like object in
        functions waiting for readiness, such as the ones defined in the
        `selectors` module.
        )r9   socketrf   r4   r4   r5   fileno  s   zBaseConnection.filenoc                 C  s"   |   r| j }|  dS dS )z/Cancel the current operation on the connection.N)_should_cancelr9   
get_cancelcancel)rM   cr4   r4   r5   r   (  s   
zBaseConnection.cancelc                 C  s(   | j rdS | jr| jd rtddS )zhCheck whether the current command should actually be cancelled when
        invoking cancel*().
        Fr   z=cancel() cannot be used with a prepared two-phase transactionT)rU   rB   r   r   rf   r4   r4   r5   r   .  s   zBaseConnection._should_canceltimeoutfloatPQGenConn[None]c                c  s,    | j  }|  tj||dE d H  d S )Nr   )r9   cancel_connstartr   r   )rM   r   r   r4   r4   r5   _cancel_gen=  s   
zBaseConnection._cancel_gencallbackr6   c                 C     | j | dS )z
        Register a callable to be invoked when a notice message is received.

        :param callback: the callback to call upon message received.
        :type callback: Callable[[~psycopg.errors.Diagnostic], None]
        N)r=   appendrM   r   r4   r4   r5   add_notice_handlerB     z!BaseConnection.add_notice_handlerc                 C  r   )z
        Unregister a notice message callable previously registered.

        :param callback: the callback to remove.
        :type callback: Callable[[~psycopg.errors.Diagnostic], None]
        N)r=   remover   r4   r4   r5   remove_notice_handlerK  r   z$BaseConnection.remove_notice_handlerrN   "ReferenceType[BaseConnection[Row]]resr&   c                 C  sr   |  }|r|j s
d S t||jj}|j D ]!}z|| W q ty6 } ztd|| W Y d }~qd }~ww d S )Nz)error processing notice callback '%s': %s)r=   r   
Diagnosticr9   	_encoding	Exceptionlogger	exception)rN   r   rM   diagcbexr4   r4   r5   rD   T  s   

zBaseConnection._notice_handlerr7   c                 C  r   )z
        Register a callable to be invoked whenever a notification is received.

        :param callback: the callback to call upon notification received.
        :type callback: Callable[[~psycopg.Notify], None]
        N)r>   r   r   r4   r4   r5   add_notify_handlerc  r   z!BaseConnection.add_notify_handlerc                 C  r   )z
        Unregister a notification callable previously registered.

        :param callback: the callback to remove.
        :type callback: Callable[[~psycopg.Notify], None]
        N)r>   r   r   r4   r4   r5   remove_notify_handlerl  r   z$BaseConnection.remove_notify_handlerpgnpq.PGnotifyc                 C  sr   |   }sd S |j j}t|j||j||j}|jr)|jD ]}|| q d S |j }d ur7|	| d S d S rl   )
r9   r   r)   relnamedecodeextrabe_pidr>   rC   r   )rN   r   rM   encnr   dr4   r4   r5   rF   u  s   


zBaseConnection._notify_handler
int | Nonec                 C  r   )a&  
        Number of times a query is executed before it is prepared.

        - If it is set to 0, every query is prepared the first time it is
          executed.
        - If it is set to `!None`, prepared statements are disabled on the
          connection.

        Default value: 5
        rA   prepare_thresholdrf   r4   r4   r5   r     s   z BaseConnection.prepare_thresholdc                 C  s   || j _d S rl   r   rn   r4   r4   r5   r     s   c                 C  s   | j j}|tjkr|S dS )z
        Maximum number of prepared statements on the connection.

        `!None` means no max number of prepared statements. The default value
        is 100.
        N)rA   prepared_maxsysmaxsize)rM   rvr4   r4   r5   r     s   zBaseConnection.prepared_maxc                 C  s   |d u rt j}|| j_d S rl   )r   r   rA   r   rn   r4   r4   r5   r     s    g        r   conninfoPQGenConn[Self]c                c  s"    t j||dE dH }| |}|S )z?Generator to connect to the database and create a new instance.r   N)r   connect)ra   r   r   r9   connr4   r4   r5   _connect_gen  s   zBaseConnection._connect_gencommandr   result_format	pq.FormatPQGen[PGresult | None]c                 c  s   |    t|tr|| jj}n
t|tr|| }| jr9t	| jj
|d|d}| jj| | jjd dS |tkrD| j| n	| jj
|d|d t| jE dH d }|jtkr|jtkr|jtkrptj|| jjdtdt|jj d| |S )z
        Generator to send a command and receive the result to the backend.

        Only used to implement internal commands such as "commit", with eventual
        arguments bound client-side. The cursor can do more complex stuff.
        N)r   encodingunexpected result z from command )_check_connection_ok
isinstancer*   encoder9   r   r   as_bytesrH   r   send_query_paramscommand_queuer   result_queueTEXT
send_queryr   executerd   
COMMAND_OK	TUPLES_OKFATAL_ERRORr   error_from_resultInterfaceErrorr   
ExecStatusr   r   )rM   r   r   cmdresultr4   r4   r5   _exec_command  s:   	



zBaseConnection._exec_commandr   bytes | Nonec                 c  s    |du st s|durd| nd}| |E dH  dS |   | jr9t| jj|}| jj| | jj	d dS | j| t
| jE dH d }|jtkrk|jtkr]tj|| jjdtdt|jj ddS )ae  
        Deallocate one, or all, prepared statement in the session.

        ``name == None`` stands for DEALLOCATE ALL.

        If possible, use protocol-level commands; otherwise use SQL statements.

        Note that PgBouncer doesn't support DEALLOCATE name, but it supports
        protocol-level Close from 1.21 and DEALLOCATE ALL from 1.22.
        Ns   DEALLOCATE s   DEALLOCATE ALLr   r   r   z0 from sending closing prepared statement message)_HAS_SEND_CLOSEr   r   rH   r   r9   send_close_preparedr   r   r   r   r   rd   r   r   r   r   r   r   r   r   r   )rM   r   stmtr   r   r4   r4   r5   _deallocate  s(   

zBaseConnection._deallocatec                 C  s:   | j jtkrd S | j jtkrtdtd| j j )Nzthe connection is closedz7cannot execute operations: the connection is in status )r9   rd   OKre   r   OperationalErrorr   rf   r4   r4   r5   r     s   
z#BaseConnection._check_connection_okc                 c  sN    | j rdS | jjtkrdS | |  E dH  | jr%| j E dH  dS dS )z.Generator to start a transaction if necessary.N)r;   r9   r   r   r   _get_tx_start_commandrH   r   rf   r4   r4   r5   _start_query  s   zBaseConnection._start_querybytesc                 C  s   | j r| j S dg}| jd ur$t| j}|d ||jdd  | jd ur3|| jr0dnd | jd urB|| jr?dnd d		|| _ | j S )
Ns   BEGINs   ISOLATION LEVEL_r\   s	   READ ONLYs
   READ WRITEs
   DEFERRABLEs   NOT DEFERRABLE    )
rL   rx   r   r   r   replacer   r   r   join)rM   partsvalr4   r4   r5   r   &  s   




z$BaseConnection._get_tx_start_commandc                 c  s`    | j r	td| jrtd| jjtkrdS | dE dH  | jr.| j	 E dH  dS dS )z-Generator implementing `Connection.commit()`.zExplicit commit() forbidden within a Transaction context. (Transaction will be automatically committed on successful exit from context.)z6commit() cannot be used during a two-phase transactionNs   COMMIT)
r?   r   r   rB   r9   r   r   r   rH   r   rf   r4   r4   r5   _commit_gen:  s   zBaseConnection._commit_genc                 c  s    | j r	td| jrtd| jr| j E dH  | jjtkr$dS | 	dE dH  | j
  | j
| E dH  | jrG| j E dH  dS dS )z/Generator implementing `Connection.rollback()`.zExplicit rollback() forbidden within a Transaction context. (Either raise Rollback() or allow an exception to propagate out of the context.)z8rollback() cannot be used during a two-phase transactionNs   ROLLBACK)r?   r   r   rB   rH   r   r9   r   r   r   rA   clearmaintain_genrf   r4   r4   r5   _rollback_genN  s&   
zBaseConnection._rollback_gen	format_idgtridbqualr   c                 C  s   |    t|||S )aL  
        Returns a `Xid` to pass to the `!tpc_*()` methods of this connection.

        The argument types and constraints are explained in
        :ref:`two-phase-commit`.

        The values passed to the method will be available on the returned
        object as the members `~Xid.format_id`, `~Xid.gtrid`, `~Xid.bqual`.
        )
_check_tpcr   
from_parts)rM   r   r   r   r4   r4   r5   xidi  s   
zBaseConnection.xidr   	Xid | strc                 c  sx    |    t|tst|}| jjtkr#tdt	
| jjj | jr+td|df| _| |  E d H  d S )Nz8can't start two-phase transaction: connection in status z3can't use two-phase transactions in autocommit modeF)r   r   r   from_stringr9   r   r   r   r   r   r   r   r;   rB   r   r   rM   r   r4   r4   r5   _tpc_begin_genv  s    


zBaseConnection._tpc_begin_genc                 c  sv    | j s	td| j d rtd| j d }|df| _ | tdt|E d H  | jr9| j E d H  d S d S )Nz='tpc_prepare()' must be called inside a two-phase transactionr   zF'tpc_prepare()' cannot be used during a prepared two-phase transactionr   TzPREPARE TRANSACTION {})	rB   r   r   r   r   formatr*   rH   r   r   r4   r4   r5   _tpc_prepare_gen  s   


zBaseConnection._tpc_prepare_genactionr   Xid | str | Nonec                 c  s    d|   d}|d u r| jst| d| jd }n| jr)t| dt|ts3t|}| jrQ| jd sQt| d|   d}d | _| E d H  d S | t	d	
t	|t|E d H  d | _d S )
Ntpc_z()z? without xid must must be called inside a two-phase transactionr   z= with xid must must be called outside a two-phase transactionr   r   _genz{} PREPARED {})lowerrB   r   r   r   r   r   getattrr   r   r  r*   )rM   r  r   fnamemethr4   r4   r5   _tpc_finish_gen  s,   



zBaseConnection._tpc_finish_genc                 C  s   dS )z0Raise NotSupportedError if TPC is not supported.Nr4   rf   r4   r4   r5   r     r   zBaseConnection._check_tpcN)r9   r%   )rP   r   rQ   rR   )rQ   r*   )rQ   rc   )rj   rc   rQ   rR   )rj   rc   rQ   rt   )rQ   rw   )rj   rw   rQ   rR   )rj   rw   rQ   rt   )rQ   r~   )rj   r~   rQ   rR   )rj   r~   rQ   rt   )r   r*   rQ   rt   )rQ   r#   )rQ   r   )rQ   r   )rQ   r-   )rQ   rR   )r   r   rQ   r   )r   r6   rQ   rR   )rN   r   r   r&   rQ   rR   )r   r7   rQ   rR   )rN   r   r   r   rQ   rR   )rQ   r   )rj   r   rQ   rR   )r   )r   r*   r   r   rQ   r   )r   r   r   r   rQ   r   )r   r   rQ   rt   )rQ   rt   )rQ   r   )r   r-   r   r*   r   r*   rQ   r   )r   r   rQ   rt   )r  r   r   r  rQ   rt   )Cr/   r0   r1   r2   r   WarningErrorr   DatabaseError	DataErrorr   IntegrityErrorInternalErrorr   NotSupportedErrorrO   r
   rY   rW   propertyrU   rg   ri   setterrm   rv   rx   rz   r|   r   r   r   r   r   r   ru   rb   r   r   r   r   r   r   r   r   staticmethodrD   r   r   rF   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r  r  r  r   r4   r4   r4   r5   r8   O   s    
)
	










	



		

		
	
.
$







r8   )Wr2   
__future__r   r   loggingtypingr   r   r   r   r   weakrefr   r	   warningsr
   	functoolsr   collectionsr   collections.abcr   r   r   r   r   r   r   abcr   r   r   sqlr   r   rB   r   rowsr   adaptr   _enumsr   _compatr   r   r   pq.miscr   
_preparingr    _capabilitiesr!   _pipeline_baser"   _connection_infor#   psycopg_pool.baser$   pq.abcr%   r&   r'   Formatr   BINARY
ConnStatusr   re   r   r   r   r   r   r   INTRANShas_send_close_preparedr   	getLoggerr   r)   r0   r   r6   r3   r7   r8   r4   r4   r4   r5   <module>   sX    
