
    9h9                         S r SSKrSSKJr  \R
                  " 5       r " S S5      r " S S\5      r " S S	\5      r	 " S
 S\5      r
 " S S\5      r " S S\5      r\	" S5      r\	" S5      rg)zSQL composition utility module
    N)
extensionsc                   B    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
rg)
Composable#   a  
Abstract base class for objects that can be used to compose an SQL string.

`!Composable` objects can be passed directly to `~cursor.execute()`,
`~cursor.executemany()`, `~cursor.copy_expert()` in place of the query
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.
c                     Xl         g N_wrapped)selfwrappeds     >/var/www/html/env/lib/python3.13/site-packages/psycopg2/sql.py__init__Composable.__init__1   s        c                 P    U R                   R                   SU R                  < S3$ )N())	__class____name__r
   r   s    r   __repr__Composable.__repr__4   s%    ..))*!DMM+<A>>r   c                     [         e)a2  
Return the string value of the object.

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

The method is automatically invoked by `~cursor.execute()`,
`~cursor.executemany()`, `~cursor.copy_expert()` if a `!Composable` is
passed instead of the query string.
)NotImplementedErrorr   contexts     r   	as_stringComposable.as_string7   s
     "!r   c                     [        U[        5      (       a  [        U /5      U-   $ [        U[        5      (       a  [        U /5      [        U/5      -   $ [        $ r   )
isinstanceComposedr   NotImplementedr   others     r   __add__Composable.__add__D   sM    eX&&TF#e++eZ((TF#hw&777!!r   c                      [        U /U-  5      $ r   )r!   )r   ns     r   __mul__Composable.__mul__L   s    
##r   c                 n    [        U 5      [        U5      L =(       a    U R                  UR                  :H  $ r   )typer
   r#   s     r   __eq__Composable.__eq__O   s'    DzT%[(LT]]enn-LLr   c                 .    U R                  U5      (       + $ r   )r-   r#   s     r   __ne__Composable.__ne__R   s    ;;u%%%r   r	   N)r   
__module____qualname____firstlineno____doc__r   r   r   r%   r)   r-   r0   __static_attributes__ r   r   r   r   #   s+     ?""$M&r   r   c                   T   ^  \ rS rSrSrU 4S jr\S 5       rS rS r	S r
S rS	rU =r$ )
r!   V   a  
A `Composable` object made of a sequence of `!Composable`.

The object is usually created using `!Composable` operators and methods.
However it is possible to create a `!Composed` directly specifying a
sequence of `!Composable` as arguments.

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).
c                    > / nU H9  n[        U[        5      (       d  [        SU< S35      eUR                  U5        M;     [        TU ]  U5        g )Nz*Composed elements must be Composable, got z instead)r    r   	TypeErrorappendsuperr   )r   seqr   ir   s       r   r   Composed.__init__h   sU    Aa,,@XNP PNN1	  	!r   c                 ,    [        U R                  5      $ )z+The list of the content of the `!Composed`.)listr
   r   s    r   r>   Composed.seqr   s     DMM""r   c                     / nU R                    H#  nUR                  UR                  U5      5        M%     SR                  U5      $ )N )r
   r<   r   join)r   r   rvr?   s       r   r   Composed.as_stringw   s8    AIIakk'*+ wwr{r   c                 ,    [        U R                  5      $ r   )iterr
   r   s    r   __iter__Composed.__iter__}   s    DMM""r   c                     [        U[        5      (       a"  [        U R                  UR                  -   5      $ [        U[        5      (       a  [        U R                  U/-   5      $ [        $ r   )r    r!   r
   r   r"   r#   s     r   r%   Composed.__add__   sP    eX&&DMMENN:;;eZ((DMMUG344!!r   c                     [        U[        5      (       a  [        U5      nO [        U[        5      (       d  [        S5      eUR	                  U 5      $ )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"

z3Composed.join() argument must be a string or an SQL)r    strSQLr;   rF   )r   joiners     r   rF   Composed.join   sJ     fc""[FFC((EG G {{4  r   r7   )r   r2   r3   r4   r5   r   propertyr>   r   rK   r%   rF   r6   __classcell__r   s   @r   r!   r!   V   s:    "" # ##"! !r   r!   c                   N   ^  \ rS rSrSrU 4S jr\S 5       rS rS r	S r
SrU =r$ )	rQ      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 *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.

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"
c                 d   > [        U[        5      (       d  [        S5      e[        TU ]  U5        g )NzSQL values must be strings)r    rP   r;   r=   r   )r   stringr   s     r   r   SQL.__init__   s)    &#&&899 r   c                     U R                   $ )z(The string wrapped by the `!SQL` object.r	   r   s    r   rZ   
SQL.string        }}r   c                     U R                   $ r   r	   r   s     r   r   SQL.as_string   s    }}r   c                    / nSn[         R                  U R                  5       H  u  pVpxU(       a  [        S5      eU(       a  [        S5      eU(       a  UR	                  [        U5      5        Uc  MP  UR                  5       (       a3  U(       a  [        S5      eUR	                  U[        U5         5        SnM  U(       d(  Uc  [        S5      eUR	                  X   5        US-  nM  UR	                  X&   5        M     [        U5      $ )a  
Merge `Composable` objects into a template.

:param `Composable` args: parameters to replace to numbered
    (``{0}``, ``{1}``) or auto-numbered (``{}``) placeholders
:param `Composable` 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. Only `!Composable` objects can be passed to the
template.

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 {pkey} = %s")
    ...     .format(tbl=sql.Identifier('people'), pkey=sql.Identifier('id'))
    ...     .as_string(conn))
    select * from "people" where "id" = %s

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 automatic   )	
_formatterparser
   
ValueErrorr<   rQ   isdigitintr!   )	r   argskwargsrG   autonumprenamespecconvs	            r   format
SQL.format   s    @ %/%5%5dmm%D!Ct !KLL !HII		#c(#|||~~$PR R		$s4y/*?$PR R		$-(1 		&,'5 &E8 |r   c                     / n[        U5      n UR                  [        U5      5        U H%  nUR                  U 5        UR                  U5        M'     [	        U5      $ ! [         a     Nf = f)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"
)rJ   r<   nextStopIterationr!   )r   r>   rG   itr?   s        r   rF   SQL.join  si    $ #Y	IId2h 		$		!  |  		s   A 
A,+A,r7   )r   r2   r3   r4   r5   r   rT   rZ   r   ro   rF   r6   rU   rV   s   @r   rQ   rQ      s6    *!
  >@ r   rQ   c                   X   ^  \ rS rSrSrU 4S jr\S 5       r\S 5       rS r	S r
SrU =r$ )	
Identifieri"  a  
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/static/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"

c                    > U(       d  [        S5      eU H#  n[        U[        5      (       a  M  [        S5      e   [        TU ]  U5        g )NzIdentifier cannot be emptyz$SQL identifier parts must be strings)r;   r    rP   r=   r   )r   stringssr   s      r   r   Identifier.__init__A  sD    899Aa%% FGG  	!r   c                     U R                   $ )z5A tuple with the strings wrapped by the `Identifier`.r	   r   s    r   ry   Identifier.stringsK  r^   r   c                 h    [        U R                  5      S:X  a  U R                  S   $ [        S5      e)z0The string wrapped by the `Identifier`.
        rb   r   z2the Identifier wraps more than one than one string)lenr
   AttributeErrorr   s    r   rZ   Identifier.stringP  s6     t}}"==## DF Fr   c                     U R                   R                   SSR                  [        [        U R
                  5      5       S3$ )Nr   z, r   )r   r   rF   mapreprr
   r   s    r   r   Identifier.__repr__Z  s6    ..))*!DIIc$6N,O+PPQRRr   c                 N   ^ SR                  U4S jU R                   5       5      $ )N.c              3   R   >#    U  H  n[         R                  " UT5      v   M     g 7fr   )extquote_ident).0rz   r   s     r   	<genexpr>'Identifier.as_string.<locals>.<genexpr>^  s     K]733]s   $')rF   r
   r   s    `r   r   Identifier.as_string]  s    xxKT]]KKKr   r7   )r   r2   r3   r4   r5   r   rT   ry   rZ   r   r   r6   rU   rV   s   @r   rw   rw   "  sI    <"   F FSL Lr   rw   c                   .    \ rS rSrSr\S 5       rS rSrg)Literalia  aT  
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 <python-types-adaptation>` for Python objects.

Example::

    >>> s1 = sql.Literal("foo")
    >>> s2 = sql.Literal("ba'r")
    >>> s3 = sql.Literal(42)
    >>> print(sql.SQL(', ').join([s1, s2, s3]).as_string(conn))
    'foo', 'ba''r', 42

c                     U R                   $ )z%The object wrapped by the `!Literal`.r	   r   s    r   r   Literal.wrappedu  r^   r   c                    [        U[        R                  5      (       a  UnO7[        U[        R                  5      (       a  UR                  nO[	        S5      e[        R
                  " U R                  5      n[        US5      (       a  UR                  U5        UR                  5       n[        U[        5      (       a,  UR                  [        R                  UR                     5      nU$ )Nz(context must be a connection or a cursorprepare)r    r   
connectioncursorr;   adaptr
   hasattrr   	getquotedbytesdecode	encodingsencoding)r   r   connarG   s        r   r   Literal.as_stringz  s    gs~~..D,,%%DFGGIIdmm$1i  IIdO[[]b%  3==78B	r   r7   N)	r   r2   r3   r4   r5   rT   r   r   r6   r7   r   r   r   r   a  s     &  r   r   c                   L   ^  \ rS rSrSrSU 4S jjr\S 5       rS rS r	Sr
U =r$ )	Placeholderi  a  A `Composable` representing a placeholder for query parameters.

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

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

Examples::

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

    >>> q1 = sql.SQL("insert into table ({}) values ({})").format(
    ...     sql.SQL(', ').join(map(sql.Identifier, names)),
    ...     sql.SQL(', ').join(sql.Placeholder() * len(names)))
    >>> print(q1.as_string(conn))
    insert into table ("foo", "bar", "baz") values (%s, %s, %s)

    >>> q2 = sql.SQL("insert into table ({}) values ({})").format(
    ...     sql.SQL(', ').join(map(sql.Identifier, names)),
    ...     sql.SQL(', ').join(map(sql.Placeholder, names)))
    >>> print(q2.as_string(conn))
    insert into table ("foo", "bar", "baz") values (%(foo)s, %(bar)s, %(baz)s)

c                    > [        U[        5      (       a  SU;   a  [        SU< 35      eOUb  [        SU< 35      e[        TU ]  U5        g )Nr   zinvalid name: z%expected string or None as name, got )r    rP   re   r;   r=   r   )r   rl   r   s     r   r   Placeholder.__init__  sV    dC  d{ >$!:;;  CD8LMMr   c                     U R                   $ )zThe name of the `!Placeholder`.r	   r   s    r   rl   Placeholder.name  r^   r   c                     U R                   c  U R                  R                   S3$ U R                  R                   SU R                   < S3$ )Nz()r   r   )r
   r   r   r   s    r   r   Placeholder.__repr__  sG    == nn--.b11nn--.a/@BBr   c                 >    U R                   b  SU R                    S3$ g)Nz%(z)sz%sr	   r   s     r   r   Placeholder.as_string  s"    ==$b))r   r7   r   )r   r2   r3   r4   r5   r   rT   rl   r   r   r6   rU   rV   s   @r   r   r     s1    4  C r   r   NULLDEFAULT)r5   rZ   psycopg2r   r   	Formatterrc   r   r!   rQ   rw   r   r   r   r   r7   r   r   <module>r      s   4  & 
0& 0&fF!z F!R@* @F<L <L~*j *Z4* 4p 6{
i.r   