U
    ڲg$                     @  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 ddlmZ ddlmZ dd	l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  e	rddl!m"Z" ej#j$Z$G dd de def Z%dS )z
Psycopg Cursor object.
    )annotations)TracebackType)AnyIteratorIterableTYPE_CHECKINGoverload)contextmanager   )pq)errors)QueryParams)CopyWriter)RowRowMaker
RowFactory)Self)Pipeline)
BaseCursor)
Connectionc                      s  e Zd ZdZdZeddddZeddd	d
dZddddd	 fddZddddZdddddddZddddZe	ddddZ
e
jdddddZ
d dd!d"ZdQddd#d$d%d&d&dd'd(d)Zd*d+d$d,d-dd.d/d0ZdRdd1d2d$d%d&d3d4d5d6d7Zd8dd9d:ZdSd3d<d=d>d?Zd<dd@dAZd4ddBdCZdTd3dEddFdGdHZedUddId$d%dJdKdLdMdNZdddOdPZ  ZS )VCursorZpsycopg zConnection[Row])
connectionc                 C  s   d S Nr   )selfr   r   r   2/tmp/pip-unpacked-wheel-b_ea6rx_/psycopg/cursor.py__init__#   s    zCursor.__init__Connection[Any]zRowFactory[Row])r   row_factoryc                C  s   d S r   r   r   r   r    r   r   r   r   &   s    N)r    zRowFactory[Row] | Nonec                  s   t  | |p|j| _d S r   )superr   r    _row_factoryr!   	__class__r   r   r   +   s    r   )returnc                 C  s   | S r   r   r   r   r   r   	__enter__1   s    zCursor.__enter__ztype[BaseException] | NonezBaseException | NonezTracebackType | NoneNone)exc_typeexc_valexc_tbr&   c                 C  s   |    d S r   )close)r   r*   r+   r,   r   r   r   __exit__4   s    zCursor.__exit__c                 C  s   |    dS )zI
        Close the current cursor and free associated resources.
        N)_closer'   r   r   r   r-   <   s    zCursor.closec                 C  s   | j S )z9Writable attribute to control how result rows are formed.r#   r'   r   r   r   r    B   s    zCursor.row_factory)r    r&   c                 C  s   || _ | jr|| | _d S r   )r#   pgresult	_make_row)r   r    r   r   r   r    G   s    zRowMaker[Row]c                 C  s
   |  | S r   r0   r'   r   r   r   _make_row_makerM   s    zCursor._make_row_makerpreparebinaryr   zParams | Nonezbool | None)queryparamsr5   r6   r&   c             
   C  sf   z2| j j  | j | j||||d W 5 Q R X W n. tjk
r` } z|dW 5 d}~X Y nX | S )z=
        Execute a query or command to the database.
        r4   N)_connlockwaitZ_execute_gene_NO_TRACEBACKwith_traceback)r   r7   r8   r5   r6   exr   r   r   executeP   s    
zCursor.executeF)	returningzIterable[Params]bool)r7   
params_seqrA   r&   c             
   C  s   zt  r| jj( | jj}|r6| j| ||| W 5 Q R X |s| j 0 | jj | j| ||| W 5 Q R X W 5 Q R X n*| jj | j| ||| W 5 Q R X W n. t	j
k
r } z|dW 5 d}~X Y nX dS )zI
        Execute the same command with a sequence of input data.
        N)r   is_supportedr9   r:   	_pipeliner;   Z_executemany_gen_pipelineZpipelineZ_executemany_gen_no_pipeliner<   r=   r>   )r   r7   rC   rA   pr?   r   r   r   executemanyd   s&    

zCursor.executemanyr
   r6   sizeintzIterator[Row])r7   r8   r6   rI   r&   c          	      c  sH  | j jrtd| jj" zzj| j	| j||||d d}| j	| 
|rt|D ]&}| j|| j}|dkrz q|V  qZd}q@W n. tjk
r } z|dW 5 d}~X Y nX W 5 | j jtkr8| j  z| j	| j
ddrqW n tk
r   Y nX z| j	| j
dd W n tk
r6   Y nX X W 5 Q R X dS )a  
        Iterate row-by-row on a result from the database.

        :param size: if greater than 1, results will be retrieved by chunks of
            this size from the server (but still yielded row-by-row); this is only
            available from version 17 of the libpq.
        z(stream() cannot be used in pipeline modeF)firstrH   TN)Z_pgconnZpipeline_statusr<   ZProgrammingErrorr9   r:   Ztransaction_statusACTIVEZ_try_cancelr;   Z_stream_fetchone_gen	ExceptionZ_stream_send_genrange_txload_rowr2   r=   r>   )	r   r7   r8   r6   rI   rK   posZrecr?   r   r   r   stream   s8    

 
zCursor.stream
Row | Nonec                 C  s<   |    |   | j| j| j}|dk	r8|  jd7  _|S )z
        Return the next record from the current recordset.

        Return `!None` the recordset is finished.

        :rtype: Row | None, with Row defined by `row_factory`
        Nr
   )_fetch_pipeline_check_result_for_fetchrO   rP   _posr2   )r   recordr   r   r   fetchone   s    zCursor.fetchoner   z	list[Row])rI   r&   c                 C  s^   |    |   | jst|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`
        )rT   rU   r1   AssertionErrorZ	arraysizerO   	load_rowsrV   minntuplesr2   len)r   rI   recordsr   r   r   	fetchmany   s    
  zCursor.fetchmanyc                 C  s@   |    |   | jst| 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`
        )	rT   rU   r1   rY   rO   rZ   rV   r\   r2   )r   r^   r   r   r   fetchall   s    

zCursor.fetchallc                 #  sR          ddd fdd}| j}|d kr8qN  jd7  _|V  q$d S )NrJ   rS   )rQ   r&   c                   s    j |  jS r   )rO   rP   r2   )rQ   r'   r   r   load   s    zCursor.__iter__.<locals>.loadr
   )rT   rU   rV   )r   ra   rowr   r'   r   __iter__   s    
zCursor.__iter__relativestr)valuemoder&   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)rT   Z_scroll)r   rf   rg   r   r   r   scroll   s    zCursor.scrollwriterzWriter | NonezIterator[Copy])	statementr8   rj   r&   c             
   c  s   zJ| j j | j | || W 5 Q R X t| |d}|V  W 5 Q R X W n. tjk
rx } z|dW 5 d}~X Y nX | d dS )zU
        Initiate a :sql:`COPY` operation and return an object to manage it.
        ri   Nr   )	r9   r:   r;   Z_start_copy_genr   r<   r=   r>   Z_select_current_result)r   rk   r8   rj   copyr?   r   r   r   rl     s    
zCursor.copyc              	   C  sH   | j dk	rD| jsD| jjrD| jj | j| jjjdd W 5 Q R X d S )NFT)flush)Z_execmany_returningr1   r9   rE   r:   r;   Z
_fetch_genr'   r   r   r   rT     s    
zCursor._fetch_pipeline)N)N)r   )rd   )N)__name__
__module____qualname__	__slots__r   r   r(   r.   r-   propertyr    setterr3   r@   rG   rR   rX   r_   r`   rc   rh   r	   rl   rT   __classcell__r   r   r$   r   r      sN    ! 3 r   r   N)&__doc__
__future__r   typesr   typingr   r   r   r   r   
contextlibr	    r   r   r<   abcr   r   rl   r   r   Zrowsr   r   r   _compatr   rE   r   Z_cursor_baser   r   r   ZTransactionStatusrL   r   r   r   r   r   <module>   s    