
    R
h@                    t   d Z ddlmZ ddlZddlZddlmZ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 ddlmZ d"d#dZ G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z ed           Z ed!          Z dS )$z 
SQL composition utility module
    )annotationsN)ABCabstractmethod)AnyIterableIteratorSequence   )Escaping)AdaptContext)PyFormat)LiteralString)conn_encoding)Transformerobjr   contextAdaptContext | Nonereturnstrc                F    t          |                               |          S )a  
    Adapt a Python object to a quoted SQL string.

    Use this function only if you absolutely want to convert a Python string to
    an SQL quoted literal to use e.g. to generate batch SQL and you won't have
    a connection available when you will need to use it.

    This function is relatively inefficient, because it doesn't cache the
    adaptation rules. If you pass a `!context` you can adapt the adaptation
    rules used, otherwise only global rules are used.

    )Literal	as_string)r   r   s     V/var/www/html/01_SiteInternet/03_Maps/venv/lib/python3.11/site-packages/psycopg/sql.pyquoter      s     3<<!!'***    c                  f    e Zd ZdZddZddZeddd            ZdddZddZ	ddZ
ddZddZdS )
ComposableaP  
    Abstract base class for objects that can be used to compose an SQL string.

    `!Composable` objects can be joined using the ``+`` operator: the result
    will be a `Composed` instance containing the objects joined. The operator
    ``*`` is also supported with an integer argument: the result is a
    `!Composed` instance containing the left argument repeated as many times as
    requested.

    `!SQL` and `!Composed` objects can be passed directly to
    `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`,
    `~psycopg.Cursor.copy()` in place of the query string.
    r   r   c                    || _         d S N_obj)selfr   s     r   __init__zComposable.__init__5   s    			r   r   r   c                0    | j         j         d| j        dS )N())	__class____name__r!   r"   s    r   __repr__zComposable.__repr__8   s     .)::DI::::r   Nr   r   bytesc                    t           )a~  
        Return the value of the object as bytes.

        :param context: the context to evaluate the object into.
        :type context: `connection` or `cursor`

        The method is automatically invoked by `~psycopg.Cursor.execute()`,
        `~psycopg.Cursor.executemany()`, `~psycopg.Cursor.copy()` if a
        `!Composable` is passed instead of the query string.

        )NotImplementedErrorr"   r   s     r   as_byteszComposable.as_bytes;   s
     "!r   c                   |r|j         nd}t          |          }|                     |          }t          |t                    r|                    |          S t          j        |                              |          d         S )z
        Return the value of the object as string.

        :param context: the context to evaluate the string into.
        :type context: `connection` or `cursor`

        Nr   )
connectionr   r/   
isinstancer+   decodecodecslookup)r"   r   connencbs        r   r   zComposable.as_stringJ   s{     &-6w!!$D!!MM'""a 	388C==  =%%,,Q//22r   otherComposedc                    t          |t                    rt          | g          |z   S t          |t                    r!t          | g          t          |g          z   S t          S r   )r2   r:   r   NotImplementedr"   r9   s     r   __add__zComposable.__add__[   s`    eX&& 	,TF##e++eZ(( 	"TF##hw&7&777!!r   nintc                (    t          | g|z            S r   )r:   )r"   r?   s     r   __mul__zComposable.__mul__c   s    
###r   boolc                ^    t          |           t          |          u o| j        |j        k    S r   )typer!   r=   s     r   __eq__zComposable.__eq__f   s'    DzzT%[[(DTY%*-DDr   c                .    |                      |           S r   )rF   r=   s     r   __ne__zComposable.__ne__i   s    ;;u%%%%r   )r   r   r   r   r   r   r   r   r+   r   r   r   r   r9   r   r   r:   )r?   r@   r   r:   )r9   r   r   rC   )r(   
__module____qualname____doc__r#   r*   r   r/   r   r>   rB   rF   rH    r   r   r   r   &   s            ; ; ; ; " " " " ^"3 3 3 3 3"" " " "$ $ $ $E E E E& & & & & &r   r   c                  R     e Zd ZU dZded<   d fdZdddZddZddZddZ	 xZ
S )r:   a.  
    A `Composable` object made of a sequence of `!Composable`.

    The object is usually created using `!Composable` operators and methods
    (such as the `SQL.format()` method). `!Composed` objects can be passed
    directly to `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`,
    `~psycopg.Cursor.copy()` in place of the query string.

    It is also possible to create a `!Composed` directly specifying a sequence
    of objects as arguments: if they are not `!Composable` they will be wrapped
    in a `Literal`.

    Example::

        >>> comp = sql.Composed(
        ...     [sql.SQL("INSERT INTO "), sql.Identifier("table")])
        >>> print(comp.as_string(conn))
        INSERT INTO "table"

    `!Composed` objects are iterable (so they can be used in `SQL.join` for
    instance).
    zlist[Composable]r!   seqSequence[Any]c                b    d |D             }t                                          |           d S )Nc                Z    g | ](}t          |t                    r|nt          |          )S rP   )r2   r   r   ).0r   s     r   
<listcomp>z%Composed.__init__.<locals>.<listcomp>   s1    SSSjj11Cssws||SSSr   )superr#   )r"   rR   r'   s     r   r#   zComposed.__init__   s4    SSsSSSr   Nr   r   r   r+   c                P    d                     fd| j        D                       S )Nr   c              3  B   K   | ]}|                               V  d S r   )r/   )rV   r   r   s     r   	<genexpr>z$Composed.as_bytes.<locals>.<genexpr>   s/      CC#W--CCCCCCr   )joinr!   r.   s    `r   r/   zComposed.as_bytes   s,    xxCCCCCCCCCCr   Iterator[Composable]c                *    t          | j                  S r   )iterr!   r)   s    r   __iter__zComposed.__iter__   s    DIr   r9   r   c                    t          |t                    rt          | j        |j        z             S t          |t                    rt          | j        |gz             S t          S r   )r2   r:   r!   r   r<   r=   s     r   r>   zComposed.__add__   sZ    eX&& 	4DI
2333eZ(( 	"DI/000!!r   joinerSQL | LiteralStringc                    t          |t                    rt          |          }n(t          |t                    st          d|d          |                    | j                  S )a~  
        Return a new `!Composed` interposing the `!joiner` with the `!Composed` items.

        The `!joiner` must be a `SQL` or a string which will be interpreted as
        an `SQL`.

        Example::

            >>> fields = sql.Identifier('foo') + sql.Identifier('bar')  # a Composed
            >>> print(fields.join(', ').as_string(conn))
            "foo", "bar"

        z5Composed.join() argument must be strings or SQL, got  instead)r2   r   SQL	TypeErrorr\   r!   )r"   rb   s     r   r\   zComposed.join   st     fc"" 	[[FFFC(( 	++ + +  
 {{49%%%r   )rR   rS   r   rJ   )r   r]   rL   )rb   rc   r   r:   )r(   rM   rN   rO   __annotations__r#   r/   r`   r>   r\   __classcell__r'   s   @r   r:   r:   m   s          .      D D D D D   " " " "& & & & & & & &r   r:   c                  r     e Zd ZU dZded<    ej                    Zd fdZdddZ	dddZ
ddZddZ xZS )rf   a  
    A `Composable` representing a snippet of SQL statement.

    `!SQL` exposes `join()` and `format()` methods useful to create a template
    where to merge variable parts of a query (for instance field or table
    names).

    The `!obj` string doesn't undergo any form of escaping, so it is not
    suitable to represent variable identifiers or values: you should only use
    it to pass constant strings representing templates or snippets of SQL
    statements; use other objects such as `Identifier` or `Literal` to
    represent variable parts.

    `!SQL` objects can be passed directly to `~psycopg.Cursor.execute()`,
    `~psycopg.Cursor.executemany()`, `~psycopg.Cursor.copy()` in place of the
    query string.

    Example::

        >>> query = sql.SQL("SELECT {0} FROM {1}").format(
        ...    sql.SQL(', ').join([sql.Identifier('foo'), sql.Identifier('bar')]),
        ...    sql.Identifier('table'))
        >>> print(query.as_string(conn))
        SELECT "foo", "bar" FROM "table"
    r   r!   r   c                    t                                          |           t          |t                    st	          d|d          d S )Nz SQL values must be strings, got re   )rX   r#   r2   r   rg   )r"   r   r'   s     r   r#   zSQL.__init__   sT    #s## 	PNsNNNOOO	P 	Pr   Nr   r   r   r   c                    | j         S r   r    r.   s     r   r   zSQL.as_string   s
    yr   r+   c                j    |r|j         nd }t          |          }| j                            |          S r   )r1   r   r!   encoder"   r   r6   r7   s       r   r/   zSQL.as_bytes   s7    %,6w!!$D!!y$$$r   argsr   kwargsr:   c                F   g }d}| j                             | j                  D ]\  }}}}|rt          d          |rt          d          |r"|                    t          |                     |P|                                r<|rt          d          |                    |t          |                              d}|s2|t          d          |                    ||                    |dz  }|                    ||                    t          |          S )a  
        Merge `Composable` objects into a template.

        :param args: parameters to replace to numbered (``{0}``, ``{1}``) or
            auto-numbered (``{}``) placeholders
        :param kwargs: parameters to replace to named (``{name}``) placeholders
        :return: the union of the `!SQL` string with placeholders replaced
        :rtype: `Composed`

        The method is similar to the Python `str.format()` method: the string
        template supports auto-numbered (``{}``), numbered (``{0}``,
        ``{1}``...), and named placeholders (``{name}``), with positional
        arguments replacing the numbered placeholders and keywords replacing
        the named ones. However placeholder modifiers (``{0!r}``, ``{0:<10}``)
        are not supported.

        If a `!Composable` objects is passed to the template it will be merged
        according to its `as_string()` method. If any other Python object is
        passed, it will be wrapped in a `Literal` object and so escaped
        according to SQL rules.

        Example::

            >>> print(sql.SQL("SELECT * FROM {} WHERE {} = %s")
            ...     .format(sql.Identifier('people'), sql.Identifier('id'))
            ...     .as_string(conn))
            SELECT * FROM "people" WHERE "id" = %s

            >>> print(sql.SQL("SELECT * FROM {tbl} WHERE name = {name}")
            ...     .format(tbl=sql.Identifier('people'), name="O'Rourke"))
            ...     .as_string(conn))
            SELECT * FROM "people" WHERE name = 'O''Rourke'

        r   z(no format specification supported by SQLz%no format conversion supported by SQLNz6cannot switch from automatic field numbering to manualz6cannot switch from manual field numbering to automaticr
   )	
_formatterparser!   
ValueErrorappendrf   isdigitr@   r:   )	r"   rq   rr   rvautonumprenamespecconvs	            r   formatz
SQL.format   sQ   F  " &*_%:%:49%E%E 	( 	(!CtT M !KLLL J !HIII $		#c((###|||~~ ( $P   		$s4yy/*** 	(?$P   		$w-(((1 		&,''''||r   rR   Iterable[Composable]c                   g }t          |          }	 |                    t          |                     |D ],}|                    |            |                    |           -n# t          $ r Y nw xY wt	          |          S )a  
        Join a sequence of `Composable`.

        :param seq: the elements to join.
        :type seq: iterable of `!Composable`

        Use the `!SQL` object's string to separate the elements in `!seq`.
        Note that `Composed` objects are iterable too, so they can be used as
        argument for this method.

        Example::

            >>> snip = sql.SQL(', ').join(
            ...     sql.Identifier(n) for n in ['foo', 'bar', 'baz'])
            >>> print(snip.as_string(conn))
            "foo", "bar", "baz"
        )r_   rw   nextStopIterationr:   )r"   rR   ry   itis        r   r\   zSQL.join%  s    $ #YY	IId2hh   		$		!  	 	 	D	 ||s   "A% %
A21A2)r   r   r   rK   rJ   )rq   r   rr   r   r   r:   )rR   r   r   r:   )r(   rM   rN   rO   rh   string	Formatterrt   r#   r   r/   r   r\   ri   rj   s   @r   rf   rf      s          4 !!##JP P P P P P
    % % % % %
F F F FP       r   rf   c                  J     e Zd ZU dZded<   d fdZddZdddZddZ xZ	S )
Identifiera#  
    A `Composable` representing an SQL identifier or a dot-separated sequence.

    Identifiers usually represent names of database objects, such as tables or
    fields. PostgreSQL identifiers follow `different rules`__ than SQL string
    literals for escaping (e.g. they use double quotes instead of single).

    .. __: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#         SQL-SYNTAX-IDENTIFIERS

    Example::

        >>> t1 = sql.Identifier("foo")
        >>> t2 = sql.Identifier("ba'r")
        >>> t3 = sql.Identifier('ba"z')
        >>> print(sql.SQL(', ').join([t1, t2, t3]).as_string(conn))
        "foo", "ba'r", "ba""z"

    Multiple strings can be passed to the object to represent a qualified name,
    i.e. a dot-separated sequence of identifiers.

    Example::

        >>> query = sql.SQL("SELECT {} FROM {}").format(
        ...     sql.Identifier("table", "field"),
        ...     sql.Identifier("schema", "table"))
        >>> print(query.as_string(conn))
        SELECT "table"."field" FROM "schema"."table"

    zSequence[str]r!   stringsr   c                    t                                          |           |st          d          |D ]*}t          |t                    st          d|d          +d S )NzIdentifier cannot be emptyz*SQL identifier parts must be strings, got re   )rX   r#   rg   r2   r   )r"   r   sr'   s      r   r#   zIdentifier.__init__g  s    !!! 	:8999 	 	Aa%% NNNN  	 	r   r   c                |    | j         j         dd                    t          t          | j                             dS )Nr%   , r&   )r'   r(   r\   mapreprr!   r)   s    r   r*   zIdentifier.__repr__t  s6    .)NNDIIc$	6J6J,K,KNNNNr   Nr   r   r+   c                     |r|j         nd }|r8t          |j                  t          |          fd j        D             }n fd j        D             }d                    |          S )Nc                `    g | ]*}                     |                                        +S rP   )escape_identifierro   )rV   r   r7   escs     r   rW   z'Identifier.as_bytes.<locals>.<listcomp>|  s1    LLLQC))!((3--88LLLr   c                ^    g | ])}                     |                                          *S rP   )_escape_identifierro   )rV   r   r"   s     r   rW   z'Identifier.as_bytes.<locals>.<listcomp>~  s/    KKKAD++AHHJJ77KKKr      .)r1   r   pgconnr   r!   r\   )r"   r   r6   escsr7   r   s   `   @@r   r/   zIdentifier.as_bytesw  s    %,6w!!$ 	L4;''C%%CLLLLL$)LLLDDKKKKKKKDyyr   r   c                :    d|                     dd          z   dz   S )zK
        Approximation of PQescapeIdentifier taking no connection.
           "s   "")replace)r"   r   s     r   r   zIdentifier._escape_identifier  s"     aiie,,,t33r   )r   r   rI   r   rJ   )r   r+   r   r+   )
r(   rM   rN   rO   rh   r#   r*   r/   r   ri   rj   s   @r   r   r   E  s          >      O O O O    4 4 4 4 4 4 4 4r   r   c                      e Zd ZdZdd	dZdS )
r   a  
    A `Composable` representing an SQL value to include in a query.

    Usually you will want to include placeholders in the query and pass values
    as `~cursor.execute()` arguments. If however you really really need to
    include a literal value in the query you can use this object.

    The string returned by `!as_string()` follows the normal :ref:`adaptation
    rules <types-adaptation>` for Python objects.

    Example::

        >>> s1 = sql.Literal("fo'o")
        >>> s2 = sql.Literal(42)
        >>> s3 = sql.Literal(date(2000, 1, 1))
        >>> print(sql.SQL(', ').join([s1, s2, s3]).as_string(conn))
        'fo''o', 42, '2000-01-01'::date

    Nr   r   r   r+   c                ^    t          j        |          }|                    | j                  S r   )r   from_context
as_literalr!   )r"   r   txs      r   r/   zLiteral.as_bytes  s&    %g..}}TY'''r   r   rJ   )r(   rM   rN   rO   r/   rP   r   r   r   r     s7         (( ( ( ( ( ( (r   r   c                  P     e Zd ZdZdej        fd fdZdd	ZdddZdddZ	 xZ
S )Placeholdera	  A `Composable` representing a placeholder for query parameters.

    If the name is specified, generate a named placeholder (e.g. ``%(name)s``,
    ``%(name)b``), otherwise generate a positional placeholder (e.g. ``%s``,
    ``%b``).

    The object is useful to generate SQL queries with a variable number of
    arguments.

    Examples::

        >>> names = ['foo', 'bar', 'baz']

        >>> q1 = sql.SQL("INSERT INTO my_table ({}) VALUES ({})").format(
        ...     sql.SQL(', ').join(map(sql.Identifier, names)),
        ...     sql.SQL(', ').join(sql.Placeholder() * len(names)))
        >>> print(q1.as_string(conn))
        INSERT INTO my_table ("foo", "bar", "baz") VALUES (%s, %s, %s)

        >>> q2 = sql.SQL("INSERT INTO my_table ({}) VALUES ({})").format(
        ...     sql.SQL(', ').join(map(sql.Identifier, names)),
        ...     sql.SQL(', ').join(map(sql.Placeholder, names)))
        >>> print(q2.as_string(conn))
        INSERT INTO my_table ("foo", "bar", "baz") VALUES (%(foo)s, %(bar)s, %(baz)s)

     r|   r   r   str | PyFormatc                   t                                          |           t          |t                    st	          d|          d|v rt          d|          t          |          t          u rt          |          }t          |t                    s$t	          dt          |          j                  || _	        d S )Nzexpected string as name, got r&   zinvalid name: z!expected PyFormat as format, got )
rX   r#   r2   r   rg   rv   rE   r   r(   _format)r"   r|   r   r'   s      r   r#   zPlaceholder.__init__  s    $$$ 	FDDDDEEE$;;6d66777<<3f%%F&(++ 	MDLL4IMM   "(r   r   c                   g }| j         r'|                    t          | j                              | j        t          j        ur"|                    d| j        j                    | j        j         dd	                    |           dS )Nzformat=r%   r   r&   )
r!   rw   r   r   r   AUTOr|   r'   r(   r\   )r"   partss     r   r*   zPlaceholder.__repr__  s    9 	*LLdi)))<x},,LL64<#466777.)??DIIe,<,<????r   Nr   r   c                L    | j         j        }| j        rd| j         d| nd| S )Nz%(r&   %)r   valuer!   )r"   r   codes      r   r   zPlaceholder.as_string  s7    |!*.)C&DI&&&&&TCr   r+   c                    |r|j         nd }t          |          }|                     |                              |          S r   )r1   r   r   ro   rp   s       r   r/   zPlaceholder.as_bytes  sA    %,6w!!$D!!~~g&&--c222r   )r|   r   r   r   rI   r   rK   rJ   )r(   rM   rN   rO   r   r   r#   r*   r   r/   ri   rj   s   @r   r   r     s         6 $& ( ( ( ( ( ( ("@ @ @ @D D D D D3 3 3 3 3 3 3 3 3r   r   NULLDEFAULTr   )r   r   r   r   r   r   )!rO   
__future__r   r4   r   abcr   r   typingr   r   r   r	   pqr   r   _enumsr   _compatr   
_encodingsr   _transformerr   r   r   r:   rf   r   r   r   r   r   rP   r   r   <module>r      s7    # " " " " "   # # # # # # # # 4 4 4 4 4 4 4 4 4 4 4 4                   " " " " " " % % % % % % % % % % % %+ + + + + D& D& D& D& D& D& D& D&NB& B& B& B& B&z B& B& B&JP P P P P* P P Pf@4 @4 @4 @4 @4 @4 @4 @4F( ( ( ( (j ( ( (4=3 =3 =3 =3 =3* =3 =3 =3B s6{{
#i..r   