o
    8g9                     @   s   d Z ddlZddlmZ e ZG dd dZG dd deZG dd	 d	eZ	G d
d deZ
G dd deZG dd deZe	dZe	dZdS )zSQL composition utility module
    N)
extensionsc                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )
Composablea6  
    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                 C   s
   || _ d S N_wrapped)selfwrapped r	   N/var/www/html/ecg_monitoring/venv/lib/python3.10/site-packages/psycopg2/sql.py__init__1      
zComposable.__init__c                 C   s   | j j d| jdS )N())	__class____name__r   r   r	   r	   r
   __repr__4   s   zComposable.__repr__c                 C   s   t )aj  
        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   contextr	   r	   r
   	as_string7   s   zComposable.as_stringc                 C   s:   t |trt| g| S t |trt| gt|g S tS r   )
isinstanceComposedr   NotImplementedr   otherr	   r	   r
   __add__D   s
   

zComposable.__add__c                 C   s   t | g| S r   )r   )r   nr	   r	   r
   __mul__L   s   zComposable.__mul__c                 C   s   t | t |u o| j|jkS r   )typer   r   r	   r	   r
   __eq__O   s   zComposable.__eq__c                 C   s   |  | S r   )r    r   r	   r	   r
   __ne__R   s   zComposable.__ne__N)r   
__module____qualname____doc__r   r   r   r   r   r    r!   r	   r	   r	   r
   r   #   s    r   c                       sL   e Zd ZdZ fddZedd Zdd Zdd	 Zd
d Z	dd Z
  ZS )r   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                    sB   g }|D ]}t |tstd|d|| qt | d S )Nz*Composed elements must be Composable, got z instead)r   r   	TypeErrorappendsuperr   )r   seqr   ir   r	   r
   r   h   s   

zComposed.__init__c                 C   
   t | jS )z+The list of the content of the `!Composed`.)listr   r   r	   r	   r
   r(   r   s   
zComposed.seqc                 C   s*   g }| j D ]
}||| qd|S )N )r   r&   r   join)r   r   rvr)   r	   r	   r
   r   w   s   

zComposed.as_stringc                 C   r+   r   )iterr   r   r	   r	   r
   __iter__}   r   zComposed.__iter__c                 C   s8   t |trt| j|j S t |trt| j|g S tS r   )r   r   r   r   r   r   r	   r	   r
   r      s
   

zComposed.__add__c                 C   s0   t |tr
t|}n	t |tstd|| 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"

        z3Composed.join() argument must be a string or an SQL)r   strSQLr%   r.   )r   joinerr	   r	   r
   r.      s   



zComposed.join)r   r"   r#   r$   r   propertyr(   r   r1   r   r.   __classcell__r	   r	   r*   r
   r   V   s    

r   c                       sD   e Zd ZdZ fddZedd Zdd Zdd	 Zd
d Z	  Z
S )r3   aA  
    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                    s"   t |ts	tdt | d S )NzSQL values must be strings)r   r2   r%   r'   r   )r   stringr*   r	   r
   r      s   
zSQL.__init__c                 C      | j S )z(The string wrapped by the `!SQL` object.r   r   r	   r	   r
   r7         z
SQL.stringc                 C   r8   r   r   r   r	   r	   r
   r      s   zSQL.as_stringc           	      O   s   g }d}t | jD ]S\}}}}|rtd|rtd|r%|t| |du r*q
| r@|r4td||t|  d}q
|sV|du rJtd|||  |d7 }q
|||  q
t|S )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&   r3   isdigitintr   )	r   argskwargsr/   autonumprenamespecconvr	   r	   r
   format   s6    
z
SQL.formatc                 C   s^   g }t |}z	|t| W n ty   Y t|S w |D ]}||  || q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"
        )r0   r&   nextStopIterationr   )r   r(   r/   itr)   r	   r	   r
   r.     s   
zSQL.join)r   r"   r#   r$   r   r5   r7   r   rG   r.   r6   r	   r	   r*   r
   r3      s    
@r3   c                       sH   e Zd ZdZ fddZedd Zedd Zdd	 Zd
d Z	  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/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                    s8   |st d|D ]}t|tst dqt | d S )NzIdentifier cannot be emptyz$SQL identifier parts must be strings)r%   r   r2   r'   r   )r   stringssr*   r	   r
   r   A  s   
zIdentifier.__init__c                 C   r8   )z5A tuple with the strings wrapped by the `Identifier`.r   r   r	   r	   r
   rL   K  r9   zIdentifier.stringsc                 C   s    t | jdkr| jd S td)z0The string wrapped by the `Identifier`.
        r:   r   z2the Identifier wraps more than one than one string)lenr   AttributeErrorr   r	   r	   r
   r7   P  s
   
zIdentifier.stringc                 C   s"   | j j ddtt| j dS )Nr   z, r   )r   r   r.   mapreprr   r   r	   r	   r
   r   Z  s   "zIdentifier.__repr__c                    s   d  fdd| jD S )N.c                 3   s    | ]	}t | V  qd S r   )extquote_ident).0rM   r   r	   r
   	<genexpr>^  s    z'Identifier.as_string.<locals>.<genexpr>)r.   r   r   r	   rV   r
   r   ]  s   zIdentifier.as_string)r   r"   r#   r$   r   r5   rL   r7   r   r   r6   r	   r	   r*   r
   rK   "  s    


	rK   c                   @   s$   e Zd ZdZedd Zdd ZdS )Literala  
    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                 C   r8   )z%The object wrapped by the `!Literal`.r   r   r	   r	   r
   r   u  r9   zLiteral.wrappedc                 C   sv   t |tjr	|}nt |tjr|j}ntdt| j}t|dr'|| |	 }t |t
r9|tj|j }|S )Nz(context must be a connection or a cursorprepare)r   rS   
connectioncursorr%   adaptr   hasattrrY   	getquotedbytesdecode	encodingsencoding)r   r   connar/   r	   r	   r
   r   z  s   


zLiteral.as_stringN)r   r"   r#   r$   r5   r   r   r	   r	   r	   r
   rX   a  s
    
rX   c                       s>   e Zd ZdZd fdd	Zedd Zdd Zd	d
 Z  Z	S )Placeholdera  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)

    Nc                    sH   t |trd|v rtd|n|d urtd|t | d S )Nr   zinvalid name: z%expected string or None as name, got )r   r2   r=   r%   r'   r   )r   rD   r*   r	   r
   r     s   
zPlaceholder.__init__c                 C   r8   )zThe name of the `!Placeholder`.r   r   r	   r	   r
   rD     r9   zPlaceholder.namec                 C   s.   | j d u r| jj dS | jj d| j dS )Nz()r   r   )r   r   r   r   r	   r	   r
   r     s   
zPlaceholder.__repr__c                 C   s   | j d urd| j  dS dS )Nz%(z)sz%sr   r   r	   r	   r
   r     s   
zPlaceholder.as_stringr   )
r   r"   r#   r$   r   r5   rD   r   r   r6   r	   r	   r*   r
   re     s    

re   NULLDEFAULT)r$   r7   psycopg2r   rS   	Formatterr;   r   r   r3   rK   rX   re   rf   rg   r	   r	   r	   r
   <module>   s    3I ?-8