o
    6	fUz                     @   s  d Z ddlmZ ddlmZ ddlmZmZmZm	Z	m
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mZ d	dl m!Z!m"Z# d	dl$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/m0Z0 d	dl1m2Z2 d	dl3m4Z4 d	dl5m6Z6 d	dl7m8Z8m9Z9m:Z: erd	dlm;Z; d	dl<m=Z=m>Z> d	dl?m@Z@ ejAjBZBejAjCZCejDjEZEejDjFZFejDjGZGejDjHZHejDjIZIejDjJZJejDjKZKejDjLZLejDjMZMejNjOZOG dd deee%f ZPG dd dePde%f ZQd S )!z
psycopg cursor objects
    )partial)TracebackType)AnyGenericIterableIteratorList)OptionalNoReturnSequenceTupleType)overloadTYPE_CHECKING)warn)contextmanager   )pq)adapt)errors)ConnectionTypeQueryParamsPQGen)CopyWriter)RowRowMaker
RowFactoryColumn)Self)connection_summary)PostgresQueryPostgresClientQuery)Pipeline)pgconn_encoding)Prepare)executefetchsend)Transformer)PGconnPGresult)
Connectionc                   @   s  e Zd ZU d ZejZded< ee	 ed< ded< de
fdd	ZdmdeddfddZdefddZede
fddZedejfddZedefddZedeee  fddZedefddZedee fddZdee ddfdd Zdnd!ed"ee ddfd#d$Z dee fd%d&Z!edee fd'd(Z"dee	 fd)d*Z#	dnddd+d,e$d-ee% d.ee d/ee de&d f
d0d1Z'd,e$d2e(e% d3ede&d fd4d5Z)d,e$d2e(e% d3ede&d fd6d7Z*ddd+d8e+d.ee d/ee de&eed9   fd:d;Z,	dnd8e+d.ee de-e.e/f fd<d=Z0	dndd>d,e$d-ee% d/ee de&d fd?d@Z1dAede&ed9  fdBdCZ2dnd,ee$ de&d fdDdEZ3	dndFe$d-ee% de&d fdGdHZ4dIddJd,e+dKed/ee ddfdLdMZ5	dnd,e$d-ee% de+fdNdOZ6dPed9 ddfdQdRZ7dSd9de8fdTdUZ9	dndVedWeej: ddfdXdYZ;dPed9 ddfdZd[Z<d\e/d,e+ddfd]d^Z=dd>d\e/d8e+d/ee ddfd_d`Z>dodadbZ?dpdcddZ@deedfeddfdgdhZAdodidjZBedefdkdlZCdS )q
BaseCursorz
        _conn format _adapters arraysize _closed _results pgresult _pos
        _iresult _rowcount _query _tx _last_query _row_factory _make_row
        _pgconn _execmany_returning
        __weakref__
        r+   _tx	_make_rowr,   _pgconn
connectionc                 C   s@   || _ t| _|j| _t|j| _d| _	d| _
d | _|   d S )Nr   F)_connTEXTformatpgconnr2   r   AdaptersMapadapters	_adapters	arraysize_closed_last_query_resetselfr3    rA   G/home/ertert/spirit/venv/lib/python3.10/site-packages/psycopg/cursor.py__init__A   s   zBaseCursor.__init__Treset_queryreturnNc                 C   s:   g | _ d | _d| _d| _d| _|  d | _|rd | _d S d S )Nr   )_resultspgresult_pos_iresult	_rowcount_execmany_returning_query)r@   rD   rA   rA   rB   r>   K   s   
zBaseCursor._resetc              	   C   sl   | j j d| j j }t| j}| jrd}n| jr"t| jj	j
}nd}d| d| d| dt| dd		S )
N.closedz	no result<z [z] z at 0xx>)	__class__
__module____qualname__r"   r2   r<   rH   r   
ExecStatusstatusnameid)r@   clsinforW   rA   rA   rB   __repr__W   s   
$zBaseCursor.__repr__c                 C      | j S )z$The connection this cursor is using.)r4   r@   rA   rA   rB   r3   b      zBaseCursor.connectionc                 C   r]   N)r:   r^   rA   rA   rB   r9   g   s   zBaseCursor.adaptersc                 C   r]   )z`True` if the cursor is closed.)r<   r^   rA   rA   rB   rO   k   r_   zBaseCursor.closedc                    s@    j }|r|js|jtks|jtkr fddt|jD S dS )z
        A list of `Column` objects describing the current resultset.

        `!None` if the current resultset didn't return tuples.
        c                    s   g | ]}t  |qS rA   r   ).0ir^   rA   rB   
<listcomp>   s    z*BaseCursor.description.<locals>.<listcomp>N)rH   nfieldsrW   	TUPLES_OKSINGLE_TUPLErange)r@   resrA   r^   rB   descriptionp   s   zBaseCursor.descriptionc                 C   r]   )z6Number of records affected by the precedent operation.)rK   r^   rA   rA   rB   rowcount   r_   zBaseCursor.rowcountc                 C   s    | j o| j jtk}|r| jS dS )zoIndex of the next row to fetch in the current result.

        `!None` if there is no result to fetch.
        N)rH   rW   re   rI   )r@   tuplesrA   rA   rB   	rownumber   s   zBaseCursor.rownumbersizesc                 C      d S r`   rA   )r@   rm   rA   rA   rB   setinputsizes      zBaseCursor.setinputsizessizecolumnc                 C   rn   r`   rA   )r@   rq   rr   rA   rA   rB   setoutputsize   rp   zBaseCursor.setoutputsizec                 C   sH   | j du r| jjrtdt | jt| jd k r"| | jd  dS dS )a  
        Move to the result set of the next query executed through `executemany()`
        or to the next result set if `execute()` returned more than one.

        Return `!True` if a new result is available, which will be the one
        methods `!fetch*()` will operate on.
        Nzusing nextset() in pipeline mode for several execute() is deprecated and will be dropped in 3.2; please use different cursors to receive more than one resultr   T)	rL   r4   	_pipeliner   DeprecationWarningrJ   lenrG   _select_current_resultr^   rA   rA   rB   nextset   s   zBaseCursor.nextsetc                 C   s"   | j r| j jnd}|r| S dS )z
        The command status tag from the last SQL command executed.

        `!None` if the cursor doesn't have a result available.
        N)rH   command_statusdecode)r@   msgrA   rA   rB   statusmessage   s   zBaseCursor.statusmessagec                 C   s   t r`   )NotImplementedErrorr^   rA   rA   rB   _make_row_maker      zBaseCursor._make_row_makerpreparebinaryqueryparamsr   r   c                c   s    |  |E dH  | ||}| j|||dE dH }| jjr(| jj E dH  n|dus.J | | || _| d || _	| jj
 D ]}| j|E dH  qDdS )z*Generator implementing `Cursor.execute()`.Nr   r   )_start_query_convert_query_maybe_prepare_genr4   rt   _communicate_gen_check_resultsrG   rw   r=   	_preparedget_maintenance_commands_exec_command)r@   r   r   r   r   pgqresultscmdrA   rA   rB   _execute_gen   s    	

zBaseCursor._execute_gen
params_seq	returningc           	      c   s    | j j}|s	J | |E dH  |sd| _| jdu sJ || _d}|D ]&}|r4| ||}|| _d}n|| | j|ddE dH  |	 E dH  q$|| _
|rY|jddE dH  | j j D ]}| j |E dH  q_dS )zY
        Generator implementing `Cursor.executemany()` with pipelines available.
        Nr   TFr   flush)r4   rt   r   rK   rL   r   rM   dumpr   r   r=   
_fetch_genr   r   r   )	r@   r   r   r   pipelinefirstr   r   r   rA   rA   rB   _executemany_gen_pipeline   s.   
z$BaseCursor._executemany_gen_pipelinec           
      c   s    |  |E dH  |sd| _d}|D ]B}|r"| ||}|| _d}n|| | j|ddE dH }|dus7J | | |rE| j| q|D ]}|  j|j	pPd7  _qGq| jr]| 
d || _| jj D ]}	| j|	E dH  qfdS )z]
        Generator implementing `Cursor.executemany()` with pipelines not available.
        Nr   TFr   )r   rK   r   rM   r   r   r   rG   extendcommand_tuplesrw   r=   r4   r   r   r   )
r@   r   r   r   r   r   r   r   rh   r   rA   rA   rB   _executemany_gen_no_pipeline  s2   


z'BaseCursor._executemany_gen_no_pipeliner   r-   c          
      c   s    |  ||\}}|tju r| j||d n-|tju r;| || | jjs;t| j	E d H \}|j
tkr;tj|| jd| j|||d | jj|||}| jjrgd }|d ur[|||f}| jjj| |f d S t| j	E d H }	|d ur}| jj||||	 |	S )Nr   encoding)_get_preparedr'   NO_execute_sendSHOULD_send_preparer4   rt   r(   r2   rW   FATAL_ERROReerror_from_result	_encoding_send_query_preparedr   maybe_add_to_cacheresult_queueappendvalidate)
r@   r   r   r   preprX   resultkeyqueuedr   rA   rA   rB   r   ,  s,   



zBaseCursor._maybe_prepare_genc                 C   s   | j j||S r`   )r4   r   get)r@   r   r   rA   rA   rB   r   W  s   zBaseCursor._get_preparedr   c                c   sR    |  |E dH  | ||}| j||dd | j  || _t| jE dH  dS )z2Generator to send the query for `Cursor.stream()`.NT)r   force_extended)r   r   r   r2   set_single_row_moder=   r*   )r@   r   r   r   r   rA   rA   rB   _stream_send_gen\  s   
zBaseCursor._stream_send_genr   c                 c   s    t | jE d H }|d u rd S |j}|tkr*|| _| jj||d |r(|  | _|S |t	ks2|t
krI|r>t | jE d H }|s4|t	krGtdd S | |S )N)set_loadersz1the operation in stream() didn't produce a result)r)   r2   rW   rf   rH   r0   set_pgresultr~   r1   re   
COMMAND_OKr   ProgrammingError_raise_for_result)r@   r   rh   rW   rA   rA   rB   _stream_fetchone_genk  s*   

zBaseCursor._stream_fetchone_genc                 c   sP    | j r	td|   | jr| j|urd| _t| | _| j	 E dH  dS )zGenerator to start the processing of a query.

        It is implemented as generator because it may send additional queries,
        such as `begin`.
        the cursor is closedN)
rO   r   InterfaceErrorr>   r=   r   r+   r0   r4   r   )r@   r   rA   rA   rB   r     s   
zBaseCursor._start_query	statementc                 c   s    | j jr
td|  E dH  |r!t| j}||| |j}| 	|}| j
|dd t| jE dH }t|dkr@td| |d  || _| d dS )z<Generator implementing sending a command for `Cursor.copy().z$COPY cannot be used in pipeline modeNFr   r   z*COPY cannot be mixed with other operationsr   )r4   rt   r   NotSupportedErrorr   r$   r0   convertr   r   r   r(   r2   rv   r   _check_copy_resultrG   rw   )r@   r   r   r   r   r   rA   rA   rB   _start_copy_gen  s    



zBaseCursor._start_copy_genF)r   r   r   c             
   C   s   |du r| j }n|rtnt}|| _| jjr-| jjjt| j	j
|j|j|j|j|d dS |s6|js6|tkrG| j	j
|j|j|j|j|d dS | j	|j dS )z
        Implement part of execute() before waiting common to sync and async.

        This is not a generator, but a normal non-blocking function.
        N)param_formatsparam_typesresult_format)r6   BINARYr5   rM   r4   rt   command_queuer   r   r2   send_query_paramsr   r   formatstypes
send_query)r@   r   r   r   fmtrA   rA   rB   r     s0   



zBaseCursor._execute_sendc                 C   s   t | j}||| |S r`   )r#   r0   r   )r@   r   r   r   rA   rA   rB   r     s   
zBaseCursor._convert_queryr   c                 C   sD   |st d|D ]}|j}|tkr|tkr|tkr| | q	dS )z
        Verify that the results of a query are valid.

        Verify that the query returned at least one result and that they all
        represent a valid result from the database.
        zgot no result from the queryN)r   InternalErrorrW   re   r   EMPTY_QUERYr   )r@   r   rh   rW   rA   rA   rB   r     s   

zBaseCursor._check_resultsr   c                 C   sj   |j }|tkrtj|| jd|tkrtd|tks$|tks$|t	kr)t
dtdt|j )zV
        Raise an appropriate error message for an unexpected database result
        r   pipeline abortedz8COPY cannot be used with this method; use copy() insteadz%unexpected result status from query: )rW   r   r   r   r   PIPELINE_ABORTEDPipelineAbortedCOPY_INCOPY_OUT	COPY_BOTHr   r   r   rV   rX   r@   r   rW   rA   rA   rB   r     s   
zBaseCursor._raise_for_resultrb   r6   c                 C   st   || _ | j|  }| _| jj||d d| _|jtkr!| jj| _	n|jt
kr3| jj}|dur0|nd| _	|  | _dS )zL
        Select one of the results in the cursor as the active one.
        )r6   r   NrF   )rJ   rG   rH   r0   r   rI   rW   re   ntuplesrK   r   r   r~   r1   )r@   rb   r6   rh   nrowsrA   rA   rB   rw     s   

z!BaseCursor._select_current_resultc                 C   s   |  | | j }| jd u r| j| |r| d d S d S | jr3| j| |r1| d d S d S |D ]}|  j|jp>d7  _q5d S )Nr   )r   rG   rL   r   rw   rK   r   )r@   r   first_batchrh   rA   rA   rB   _set_results_from_pipeline#  s   

z%BaseCursor._set_results_from_pipelinerX   c                 C   sZ   | j jr | j jjt| jj||j|jd | j jj	d  d S | jj||j|jd d S )N)r   )
r4   rt   r   r   r   r2   send_preparer   r   r   )r@   rX   r   rA   rA   rB   r   9  s   
zBaseCursor._send_preparec             	   C   sj   |d u r| j }n|rtnt}| jjr'| jjjt| jj	||j
|j|d d S | jj	||j
|j|d d S )N)r   r   )r6   r   r5   r4   rt   r   r   r   r2   send_query_preparedr   r   )r@   rX   r   r   r   rA   rA   rB   r   G  s    


zBaseCursor._send_query_preparedc                 C   sj   | j rtd| j}|std|j}|tkrd S |tkr'tj|| j	d|t
kr0tdtd)Nr   zno result availabler   r   z*the last operation didn't produce a result)rO   r   r   rH   r   rW   re   r   r   r   r   r   )r@   rh   rW   rA   rA   rB   _check_result_for_fetch^  s   



z"BaseCursor._check_result_for_fetchc                 C   sJ   |j }|tks|tkrdS |tkrtj|| jdtdt	|j
 )zV
        Check that the value returned in a copy() operation is a legit COPY.
        Nr   zZcopy() should be used only with COPY ... TO STDOUT or COPY ... FROM STDIN statements, got )rW   r   r   r   r   r   r   r   r   rV   rX   r   rA   rA   rB   r   o  s   
zBaseCursor._check_copy_resultvaluemodec                 C   sv   |    | js	J |dkr| j| }n|dkr|}ntd| dd|  kr1| jjk s6td td|| _d S )Nrelativeabsolutez
bad mode: z'. It should be 'relative' or 'absolute'r   zposition out of bound)r   rH   rI   
ValueErrorr   
IndexError)r@   r   r   newposrA   rA   rB   _scroll~  s   

zBaseCursor._scrollc                 C   s   | j dd d| _dS )z3Non-blocking part of closing. Common to sync/async.F)rD   TN)r>   r<   r^   rA   rA   rB   _close  s   
zBaseCursor._closec                 C   s
   t | jS r`   )r&   r2   r^   rA   rA   rB   r     s   
zBaseCursor._encoding)Tr`   rE   N)r   r-   rE   N)D__name__rT   rU   split	__slots__r   rV   __annotations__r   r   r   rC   boolr>   strr\   propertyr3   r   r8   r9   rO   r	   r   r    ri   intrj   rl   r   r   ro   rs   rx   r|   r~   r   r   r   r   r   r   r   r#   r   r   r'   bytesr   r   r   r   r   r   r   r   r
   r   Formatrw   r   r   r   r   r   r   r   r   rA   rA   rA   rB   r/   3   s,  
 
	

$
)
,



!
.





r/   c                       s  e Zd ZdZdZedBddZedddee fd	dZd
ddddeee  f fddZde	fddZ
deee  dee dee dd
fddZdCddZedee fddZejdee dd
fddZdee fddZ	
dDd
d
ddedee dee d ee de	f
d!d"Zd#d$ded%ee d&edd
fd'd(Z	
dDd
d)dedee d ee dee fd*d+Zdee fd,d-ZdEd/edee fd0d1Z dee fd2d3Z!dee fd4d5Z"dFd7ed8e#dd
fd9d:Z$e%	
dDd
d;d<edee d=ee& dee' fd>d?Z(dCd@dAZ)  Z*S )GCursorpsycopgrA   r3   Connection[Row]c                 C   rn   r`   rA   r?   rA   rA   rB   rC     r   zCursor.__init__Connection[Any]row_factoryc                C   rn   r`   rA   r@   r3   r   rA   rA   rB   rC     s   N)r   c                   s   t  | |p
|j| _d S r`   )superrC   r   _row_factoryr   rS   rA   rB   rC     s   rE   c                 C   s   | S r`   rA   r^   rA   rA   rB   	__enter__  r   zCursor.__enter__exc_typeexc_valexc_tbc                 C   s   |    d S r`   )close)r@   r   r   r   rA   rA   rB   __exit__  s   zCursor.__exit__c                 C   s   |    dS )zI
        Close the current cursor and free associated resources.
        N)r   r^   rA   rA   rB   r     s   zCursor.closec                 C   r]   )z9Writable attribute to control how result rows are formed.r   r^   rA   rA   rB   r     r_   zCursor.row_factoryc                 C   s   || _ | jr|| | _d S d S r`   )r   rH   r1   )r@   r   rA   rA   rB   r     s   c                 C   s
   |  | S r`   r  r^   rA   rA   rB   r~     s   
zCursor._make_row_makerr   r   r   r   r   c             
   C   sr   z&| j j | j | j||||d W d   W | S 1 sw   Y  W | S  tjy8 } z|dd}~ww )z=
        Execute a query or command to the database.
        r   N)r4   lockwaitr   r   _NO_TRACEBACKwith_traceback)r@   r   r   r   r   exrA   rA   rB   r(     s   

zCursor.executeF)r   r   r   c             
   C   s>  zt  ri| jj | jj}|r| j| ||| W d   n1 s%w   Y  |sc| j ' | jj | j| ||| W d   n1 sLw   Y  W d   n1 s[w   Y  W dS W dS W dS | jj | j| ||| W d   W dS 1 sw   Y  W dS  t	j
y } z|dd}~ww )zI
        Execute the same command with a sequence of input data.
        N)r%   is_supportedr4   r  rt   r  r   r   r   r   r  r  )r@   r   r   r   pr  rA   rA   rB   executemany  s:   

" 
&
zCursor.executemanyr   c                c   s   | j jr
td| jj zz/| j| j|||d d}| j| |r>| j	
d| j}|V  d}| j| |s(W n tjyQ } z|dd}~ww W | j jtkr| j  z| j| jddrt	 | j| jddsiW n	 ty~   Y nw z| j| jdd W nU ty   Y nUw nC| j jtkr| j  z| j| jddr	 | j| jddsW n	 ty   Y nw z| j| jdd W w  ty   Y w w w W d   dS W d   dS W d   dS 1 sw   Y  dS )zC
        Iterate row-by-row on a result from the database.
        z(stream() cannot be used in pipeline moder   Tr   FN)r   )r2   pipeline_statusr   r   r4   r  r  r   r   r0   load_rowr1   r  r  transaction_statusACTIVEcancel	Exception)r@   r   r   r   r   recr  rA   rA   rB   stream  sl   





"zCursor.streamc                 C   s<   |    |   | j| j| j}|dur|  jd7  _|S )z
        Return the next record from the current recordset.

        Return `!None` the recordset is finished.

        :rtype: Optional[Row], with Row defined by `row_factory`
        Nr   )_fetch_pipeliner   r0   r  rI   r1   )r@   recordrA   rA   rB   fetchone-  s   zCursor.fetchoner   rq   c                 C   s^   |    |   | jsJ |s| j}| j| jt| j| | jj| j	}|  jt
|7  _|S )z
        Return the next `!size` records from the current recordset.

        `!size` default to `!self.arraysize` if not specified.

        :rtype: Sequence[Row], with Row defined by `row_factory`
        )r  r   rH   r;   r0   	load_rowsrI   minr   r1   rv   )r@   rq   recordsrA   rA   rB   	fetchmany<  s   
zCursor.fetchmanyc                 C   s@   |    |   | jsJ | j| j| jj| j}| jj| _|S )z
        Return all the remaining records from the current recordset.

        :rtype: Sequence[Row], with Row defined by `row_factory`
        )r  r   rH   r0   r  rI   r   r1   )r@   r  rA   rA   rB   fetchallR  s   

zCursor.fetchallc                 #   sZ           dtdtt f fdd}	 | j}|d u r"d S   jd7  _|V  q)NposrE   c                    s    j |  jS r`   )r0   r  r1   )r  r^   rA   rB   loadc  s   zCursor.__iter__.<locals>.loadTr   )r  r   r   r	   r   rI   )r@   r  rowrA   r^   rB   __iter___  s   
zCursor.__iter__r   r   r   c                 C   s   |    | || dS )a  
        Move the cursor in the result set to a new position according to mode.

        If `!mode` is ``'relative'`` (default), `!value` is taken as offset to
        the current position in the result set; if set to ``'absolute'``,
        `!value` states an absolute target position.

        Raise `!IndexError` in case a scroll operation would leave the result
        set. In this case the position will not change.
        N)r  r   )r@   r   r   rA   rA   rB   scrollm  s   zCursor.scrollwriterr   r   c             
   c   s    z9| j j | j | || W d   n1 sw   Y  t| |d}|V  W d   n1 s4w   Y  W n tjyL } z|dd}~ww | d dS )zk
        Initiate a :sql:`COPY` operation and return an object to manage it.

        :rtype: Copy
        Nr  r   )	r4   r  r  r   r   r   r  r  rw   )r@   r   r   r   copyr  rA   rA   rB   r!  {  s   

zCursor.copyc                 C   sj   | j dur/| js1| jjr3| jj | j| jjjdd W d    d S 1 s(w   Y  d S d S d S d S )NFTr   )rL   rH   r4   rt   r  r  r   r^   rA   rA   rB   r    s   

"zCursor._fetch_pipeline)r3   r   r   r`   )r   )r   )+r   rT   rU   r   r   rC   r   r   r	   r!   r   r   BaseExceptionr   r   r   r   r   setterr   r~   r   r   r   r(   r   r	  r   r  r  r   r   r  r  r  r   r  r   
CopyWriterr   r!  r  __classcell__rA   rA   r   rB   r     s    
	




%
,r   r   N)R__doc__	functoolsr   r   r   typingr   r   r   r   r   r	   r
   r   r   r   r   r   warningsr   
contextlibr    r   r   r   r   abcr   r   r   r   r!  r   r   r$  rowsr   r   r   _columnr    _compatr!   pq.miscr"   _queriesr#   r$   rt   r%   
_encodingsr&   
_preparingr'   
generatorsr(   r)   r*   r+   pq.abcr,   r-   r3   r.   r   r5   r   rV   r   r   re   r   r   r   r   rf   r   TransactionStatusr  r/   r   rA   rA   rA   rB   <module>   sX        h