U
    ڲg-                     @  s(  U d Z ddlmZ ddl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mZmZmZmZ dd
lmZmZ ddlmZmZ ddl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$ dZ%de&d< dZ'de&d< dZ(de&d< ej)j*Z*ej*Z+G dd deZ,dS )a7  
Helper object to transform values between Python and PostgreSQL

Python implementation of the object. Use the `_transformer module to import
the right implementation (Python or C). The public place where the object
is exported is `psycopg.adapt` (which we may not use to avoid circular
dependencies problems).
    )annotations)AnySequenceDefaultDictTYPE_CHECKING)defaultdict   )pq)abc)errors)BufferLoadFuncAdaptContextPyFormatNoneType)RowRowMaker)INVALID_OIDTEXT_OID)	TypeAlias)conn_encoding)	DumperKey)AdaptersMap)PGresult)BaseConnectionzdict[DumperKey, abc.Dumper]r   DumperCachezdict[int, abc.Dumper]OidDumperCachezdict[int, abc.Loader]LoaderCachec                   @  s  e Zd ZU dZdZd Zded< ded< ded	< d
ed< ded< dUddddZedd dddZ	e
ddddZe
ddddZe
ddddZe
d
ddd Zd!dd"d
d#d$d%d&d'd(Zd)d*d%d+d,d-Zd)d*d%d+d.d/Zd0d1d2d3d4d5Zd6d7d8d9d:Zd6d;d<d=d>d?Zddd@dAZdd*d<dBdCdDZdddEdFdGdHdIZddEdJdKdLdMZd2dNdOdPdQZdd*dRdBdSdTZdS )VTransformeraJ  
    An object that can adapt efficiently between Python and PostgreSQL.

    The life cycle of the object is the query, so it is assumed that attributes
    such as the server version or the connection encoding will not change. The
    object have its state so adapting several values of the same type can be
    optimised.

    zpsycopg.adaptz
        types formats
        _conn _adapters _pgresult _dumpers _loaders _encoding _none_oid
        _oid_dumpers _oid_types _row_dumpers _row_loaders
        ztuple[int, ...] | Nonetypeszlist[pq.Format] | Noneformatsr   	_adapterszPGresult | None	_pgresultint	_none_oidNzAdaptContext | None)contextc                 C  s   d  | _  | _| _|r(|j| _|j| _nddlm} |j| _d | _|  t	t
| _|  d | _i i f| _d | _g | _i | _d| _d S )Nr   )postgres )r"   r   r    adaptersr!   
connection_connr'   r&   r   dict_dumpers_oid_dumpers_loaders_row_dumpers_row_loaders
_oid_types	_encoding)selfr%   r&    r4   ;/tmp/pip-unpacked-wheel-b_ea6rx_/psycopg/_py_transformer.py__init__B   s     


zTransformer.__init__)r%   returnc                 C  s   t |tr|S | |S dS )z
        Return a Transformer from an AdaptContext.

        If the context is a Transformer instance, just return it.
        N)
isinstancer   )clsr%   r4   r4   r5   from_contextf   s    
zTransformer.from_contextzBaseConnection[Any] | None)r7   c                 C  s   | j S N)r*   r3   r4   r4   r5   r)   r   s    zTransformer.connectionstrc                 C  s   | j st| j| _ | j S r;   )r2   r   r)   r<   r4   r4   r5   encodingv   s    zTransformer.encodingc                 C  s   | j S r;   )r!   r<   r4   r4   r5   r(   |   s    zTransformer.adaptersc                 C  s   | j S r;   )r"   r<   r4   r4   r5   pgresult   s    zTransformer.pgresultT)set_loadersformatboolzpq.Format | NoneNone)resultr@   rA   r7   c                  s   _ s$d __|r g _d S j_j }_|s@d S |sNg _d S |d kr`dn|  fddt|D _d S )Nr   c                   s    g | ]} | jqS r4   )
get_loaderZftypeload).0ifmtrD   r3   r4   r5   
<listcomp>   s    z,Transformer.set_pgresult.<locals>.<listcomp>)r"   _nfields_ntuplesr0   ZntuplesZnfieldsZfformatrange)r3   rD   r@   rA   nfr4   rI   r5   set_pgresult   s"    zTransformer.set_pgresultzSequence[int]z	pq.Format)r   rA   r7   c                   s4    fdd|D _ t|_ gt| _d S )Nc                   s   g | ]} | qS r4   )get_dumper_by_oidrG   oidrA   r3   r4   r5   rK      s     z0Transformer.set_dumper_types.<locals>.<listcomp>)r/   tupler   lenr    r3   r   rA   r4   rT   r5   set_dumper_types   s    
zTransformer.set_dumper_typesc                   s    fdd|D _ d S )Nc                   s   g | ]} | jqS r4   )rE   rF   rR   rT   r4   r5   rK      s     z0Transformer.set_loader_types.<locals>.<listcomp>r0   rW   r4   rT   r5   set_loader_types   s    zTransformer.set_loader_typeszSequence[Any]zSequence[PyFormat]zSequence[Buffer | None])paramsr    r7   c           
      C  s   t |}d g| }| jrNt|D ](}|| }|d k	r | j| |||< q |S |  g| }tg| }t|D ]H}|| }|d krqn| ||| }	|	|||< |	j||< |	j||< qnt	|| _
|| _|S r;   )rV   r/   rN   dump_get_none_oidTEXT
get_dumperrS   rA   rU   r   r    )
r3   r[   r    ZnparamsoutrH   paramr   Z	pqformatsdumperr4   r4   r5   dump_sequence   s*    



zTransformer.dump_sequencer   bytes)objr7   c                 C  s   |  |t}||}|j}|r|r|d dkr|tkrz| j| }W nn tk
r   | jj	|}|r|dk r|j
| j}n|j| j}||jkr|d7 }nd}|| j|< Y nX |rd||f }t|tst|}|S )N'   i    s   []    s   %s::%s)r_   PY_TEXTquoterS   r   r1   KeyErrorr(   r   getnameencoder>   ZregtypeZ	array_oidr8   rd   )r3   re   rb   rvrS   Ztype_sqlZtir4   r4   r5   
as_literal   s*    



zTransformer.as_literalr   z
abc.Dumper)re   rA   r7   c           	      C  s   t |}| j| }z|| }W nd tk
r   z| j||}W n* tjk
rj } z
|dW 5 d}~X Y nX |||  ||< }Y nX |||}||kr|S z
|| W S  tk
r   ||| }||< | Y S X dS )z:
        Return a Dumper instance to dump `!obj`.
        N)	typer,   rk   r(   r_   eProgrammingErrorget_keyupgrade)	r3   re   rA   keycacherb   dclsexkey1r4   r4   r5   r_      s$    

zTransformer.get_dumperc                 C  s\   z| j W S  tk
r   Y nX z| jttj }| _ W n tk
rV   t	dY nX |S )NzNone dumper not found)
r$   AttributeErrorr!   r_   r   ri   rS   rk   rr   InterfaceError)r3   ro   r4   r4   r5   r]     s    zTransformer._get_none_oid)rS   rA   r7   c                 C  s^   | j si i f| _ | j | }z
|| W S  tk
rX   | j||}|t|  ||< }Y nX |S )zO
        Return a Dumper to dump an object to the type with given oid.
        )r-   rk   r(   rQ   r   )r3   rS   rA   rw   rx   rb   r4   r4   r5   rQ     s    


zTransformer.get_dumper_by_oidzRowMaker[Row]z	list[Row])row0row1make_rowr7   c           
      C  s   | j }|stdd|  kr*| jkrFn nd|  krD| jksXn td| j g }t||D ]T}d g| j }t| jD ]*}|||}	|	d k	r| j| |	||< q||| qf|S )Nzresult not setr   z$rows must be included between 0 and )	r"   rr   r|   rM   rN   rL   	get_valuer0   append)
r3   r}   r~   r   resrecordsrowrecordcolvalr4   r4   r5   	load_rows,  s     
2
zTransformer.load_rowsz
Row | None)r   r   r7   c                 C  st   | j }|sd S d|  kr$| jk s*n d S d g| j }t| jD ]*}|||}|d k	r@| j| |||< q@||S )Nr   )r"   rM   rL   rN   r   r0   )r3   r   r   r   r   r   r   r4   r4   r5   load_rowA  s    zTransformer.load_rowztuple[Any, ...])r   r7   c                   sN   t  jt |kr4tdt | dt  j dt fddt|D S )Nzcannot load sequence of z items: z loaders registeredc                 3  s,   | ]$\}}|d k	r  j | |nd V  qd S r;   rY   )rG   rH   r   r<   r4   r5   	<genexpr>X  s   z,Transformer.load_sequence.<locals>.<genexpr>)rV   r0   rr   rs   rU   	enumerate)r3   r   r4   r<   r5   load_sequenceQ  s    zTransformer.load_sequencez
abc.Loaderc                 C  sp   z| j | | W S  tk
r$   Y nX | j||}|sT| jt|}|sTtd|||  }| j | |< |S )Nzunknown oid loader not found)r.   rk   r!   rE   r   rr   r|   )r3   rS   rA   
loader_clsloaderr4   r4   r5   rE   ]  s    
zTransformer.get_loader)N)__name__
__module____qualname____doc__split	__slots____annotations__r6   classmethodr:   propertyr)   r>   r(   r?   rP   rX   rZ   rc   rp   r_   r]   rQ   r   r   r   rE   r4   r4   r4   r5   r   (   sB   

$!!r   N)-r   
__future__r   typingr   r   r   r   collectionsr   r'   r	   r
   r   rr   r   r   r   r   r   Zrowsr   r   Z_oidsr   r   _compatr   Z
_encodingsr   r   Zadaptr   Zpq.abcr   Z_connection_baser   r   r   r   r   ZFormatr^   ri   r   r4   r4   r4   r5   <module>   s,   