U
    ڲg                     @  s  U d Z ddlmZ ddlZddlmZmZ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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 ejj Z ejj!Z!ejj"Z"ejj#Z#edddZ$eddddZ%G dd de
e% Z&G dd de
e% Z'G dd de
e% Z(G dd de
e% Z)dZ*de+d< d Z,de+d!< d"d#d$d%d&Z-d"d'd$d(d)Z.d"d*d$d+d,Z/e0d-d.d/d0d1d2d3Z1d4d5d6d7d8Z2d9d5d:d;d<Z3d9d5d:d=d>Z4d"d?d$d@dAZ5dBdCdDdEdFZ6d"dGd$dHdIZ7dJdKdLdMdNZ8dS )Oz
psycopg row factories
    )annotationsN)AnyCallable
NamedTupleNoReturn)TYPE_CHECKINGProtocolSequence)
namedtuple   )pq)errors)	TypeAliasTypeVar)_as_python_identifier)Cursor)
BaseCursor)AsyncCursor)PGresultTT)	covariantRowTupleRow)r   defaultc                   @  s    e Zd ZdZdddddZdS )RowMakera  
    Callable protocol taking a sequence of value and returning an object.

    The sequence of value is what is returned from a database query, already
    adapted to the right Python types. The return value is the object that your
    program would like to receive: by default (`tuple_row()`) it is a simple
    tuple, but it may be any type of object.

    Typically, `!RowMaker` functions are returned by `RowFactory`.
    Sequence[Any]r   )_RowMaker__valuesreturnc                 C  s   d S N )selfr   r   r   0/tmp/pip-unpacked-wheel-b_ea6rx_/psycopg/rows.py__call__1       zRowMaker.__call__N__name__
__module____qualname____doc__r"   r   r   r   r!   r   %   s   r   c                   @  s    e Zd ZdZdddddZdS )
RowFactorya  
    Callable protocol taking a `~psycopg.Cursor` and returning a `RowMaker`.

    A `!RowFactory` is typically called when a `!Cursor` receives a result.
    This way it can inspect the cursor state (for instance the
    `~psycopg.Cursor.description` attribute) and help a `!RowMaker` to create
    a complete object.

    For instance the `dict_row()` `!RowFactory` uses the names of the column to
    define the dictionary key and returns a `!RowMaker` function which would
    use the values to create a dictionary for each record.
    zCursor[Any]RowMaker[Row])_RowFactory__cursorr   c                 C  s   d S r   r   )r    r+   r   r   r!   r"   B   r#   zRowFactory.__call__Nr$   r   r   r   r!   r)   4   s   r)   c                   @  s    e Zd ZdZdddddZdS )AsyncRowFactoryz@
    Like `RowFactory`, taking an async cursor as argument.
    zAsyncCursor[Any]r*   )_AsyncRowFactory__cursorr   c                 C  s   d S r   r   )r    r-   r   r   r!   r"   J   r#   zAsyncRowFactory.__call__Nr$   r   r   r   r!   r,   E   s   r,   c                   @  s    e Zd ZdZdddddZdS )BaseRowFactoryzF
    Like `RowFactory`, taking either type of cursor as argument.
    BaseCursor[Any, Any]r*   )_BaseRowFactory__cursorr   c                 C  s   d S r   r   )r    r0   r   r   r!   r"   R   r#   zBaseRowFactory.__call__Nr$   r   r   r   r!   r.   M   s   r.   ztuple[Any, ...]r   dict[str, Any]DictRowr/   zRowMaker[TupleRow]cursorr   c                 C  s   t S )zRow factory to represent rows as simple tuples.

    This is the default factory, used when `~psycopg.Connection.connect()` or
    `~psycopg.Connection.cursor()` are called without a `!row_factory`
    parameter.

    )tuple)r4   r   r   r!   	tuple_rowd   s    
r6   zRowMaker[DictRow]c                   s,   t |   dkrtS ddd fdd}|S )zRow factory to represent rows as dictionaries.

    The dictionary keys are taken from the column names of the returned columns.
    Nr   r1   valuesr   c                   s   t t | S r   dictzipr8   namesr   r!   	dict_row_z   s    zdict_row.<locals>.dict_row_
_get_names	no_result)r4   r?   r   r=   r!   dict_rowq   s
    rC   zRowMaker[NamedTuple]c                   sJ   | j   stS t }|dkr"tS t| jf fddt|D  }|jS )zRow factory to represent rows as `~collections.namedtuple`.

    The field names are taken from the column names of the returned columns,
    with some mangling to deal with invalid names.
    Nc                 3  s   | ]}  |V  qd S r   )fname.0iresr   r!   	<genexpr>   s     z!namedtuple_row.<locals>.<genexpr>)pgresultrB   _get_nfields_make_nt	_encodingrange_make)r4   nfieldsntr   rH   r!   namedtuple_row   s    "rS   i   strbytesztype[NamedTuple])encr>   r   c                   s    t  fdd|D }td|S )Nc                 3  s   | ]}t | V  qd S r   )r   decode)rF   nrV   r   r!   rJ      s     z_make_nt.<locals>.<genexpr>r   )r5   r
   )rV   r>   Zsnamesr   rY   r!   rM      s    rM   ztype[T]zBaseRowFactory[T])clsr   c                   s   ddd fdd}|S )aQ  Generate a row factory to represent rows as instances of the class `!cls`.

    The class must support every output column name as a keyword parameter.

    :param cls: The class to return for each row. It must support the fields
        returned by the query as keyword arguments.
    :rtype: `!Callable[[Cursor],` `RowMaker`\[~T]]
    r/   RowMaker[T]r3   c                   s.   t |   d krtS ddd fdd}|S )Nr   r   r7   c                   s    f t t| S r   r9   r<   )rZ   r>   r   r!   class_row__   s    z2class_row.<locals>.class_row_.<locals>.class_row__r@   )r4   r\   rZ   r=   r!   
class_row_   s
    zclass_row.<locals>.class_row_r   )rZ   r^   r   r]   r!   	class_row   s    

r_   zCallable[..., T])funcr   c                   s   ddd fdd}|S )zGenerate a row factory calling `!func` with positional parameters for every row.

    :param func: The function to call for each row. It must support the fields
        returned by the query as positional arguments.
    BaseCursor[Any, T]r[   )curr   c                   s   ddd fdd}|S )Nr   r   r7   c                   s    |  S r   r   r<   r`   r   r!   
args_row__   s    z/args_row.<locals>.args_row_.<locals>.args_row__r   )rb   rd   rc   r   r!   	args_row_   s    zargs_row.<locals>.args_row_r   )r`   re   r   rc   r!   args_row   s    rf   c                   s   ddd fdd}|S )zGenerate a row factory calling `!func` with keyword parameters for every row.

    :param func: The function to call for each row. It must support the fields
        returned by the query as keyword arguments.
    ra   r[   r3   c                   s.   t |   d krtS ddd fdd}|S )Nr   r   r7   c                   s    f t t| S r   r9   r<   )r`   r>   r   r!   kwargs_row__   s    z5kwargs_row.<locals>.kwargs_row_.<locals>.kwargs_row__r@   )r4   rg   rc   r=   r!   kwargs_row_   s
    zkwargs_row.<locals>.kwargs_row_r   )r`   rh   r   rc   r!   
kwargs_row   s    
ri   zRowMaker[Any]c                 C  sH   | j }|stS t|}|dkr"tS |dk r4tdddddd}|S )	zR
    Generate a row factory returning the first column
    as a scalar value.
    Nr   zat least one column expectedr   r   r7   c                 S  s   | d S )Nr   r   r<   r   r   r!   scalar_row_   s    zscalar_row.<locals>.scalar_row_)rK   rB   rL   eZProgrammingError)r4   rI   rQ   rj   r   r   r!   
scalar_row   s    
rl   r   r   r7   c                 C  s   t ddS )zA `RowMaker` that always fail.

    It can be used as return value for a `RowFactory` called with no result.
    Note that the `!RowFactory` *will* be called with no result, but the
    resulting `!RowMaker` never should.
    z the cursor doesn't have a resultN)rk   ZInterfaceErrorr<   r   r   r!   rB      s    rB   zlist[str] | Nonec                   s@   | j sd S t}|d kr"d S | j  fddt|D S )Nc                   s   g | ]} | qS r   )rD   rW   rE   rV   rI   r   r!   
<listcomp>   s    z_get_names.<locals>.<listcomp>)rK   rL   rN   rO   )r4   rQ   r   rm   r!   rA      s    rA   r   z
int | None)rI   r   c                 C  s>   | j }| jtks2| jtks2| jtks2| jtkr6|r6|S dS dS )z
    Return the number of columns in a result, if it returns tuples else None

    Take into account the special case of results with zero columns.
    N)rQ   status	TUPLES_OKSINGLE_TUPLETUPLES_CHUNK
COMMAND_OK)rI   rQ   r   r   r!   rL     s    rL   )9r(   
__future__r   	functoolstypingr   r   r   r   r   r   r	   collectionsr
    r   r   rk   _compatr   r   Z
_encodingsr   r4   r   Z_cursor_baser   Zcursor_asyncr   Zpsycopg.pq.abcr   Z
ExecStatusrs   rp   rq   rr   r   r   r   r)   r,   r.   r   __annotations__r2   r6   rC   rS   	lru_cacherM   r_   rf   ri   rl   rB   rA   rL   r   r   r   r!   <module>   sL   	
