
    Df:                        d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZ 	 ddlmZ ddlmZ n# e$ r ddlZddlmZ Y nw xY w	 ddlZn# e$ r dZY nw xY w	 ddlmZmZ n # e$ r ddlZej        Z e            ZY nw xY wg d	Zd
Z ej        e          ZdZdZ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'e'Z( G d de&          Z) G d d          Z*e*Z+d Z,d Z-d Z.d Z/d  Z0dNd"Z1d# Z2 G d$ d%          Z3 G d& d'e3          Z4 G d( d)e3          Z5 G d* d+          Z6 G d, d-          Z7 G d. d/e7          Z8 G d0 d1e7          Z9dOd2Z: G d3 d4e7          Z; G d5 d6e7          Z< G d7 d8e7          Z= G d9 d:e7          Z>d; Z?i Z@dOd<ZAd= ZB eBd>e9            eBd?e8            eBd@e;            eBdAe<            eBdBe=            eBdCe>           dD ZC G dE dFe&          ZD G dG dH          ZE G dI dJe&          ZFdK ZGdL ZHeIdMk    r)ddlJZJ eJjK                      eG              eH             dS dS )Pz
Database API
(part of web.py)
    N   )	iteritems)iterssafestrsafeunicodestoragethreadeddict)parse)unquote)debugconfig)UnknownParamstyle	UnknownDBTransactionErrorsqllistsqlorsreparamsqlquoteSQLQuerySQLParamsqlparam
SQLLiteral
sqlliteraldatabaseDBa  [ \f\t]*(\\\r?\n[ \f\t]*)*(#[^\r\n]*)?(((\d+[jJ]|((\d+\.\d*|\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+)[jJ])|((\d+\.\d*|\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+)|(0[xX][\da-fA-F]+[lL]?|0[bB][01]+[lL]?|(0[oO][0-7]+)|(0[0-7]*)[lL]?|[1-9]\d*[lL]?))|((\*\*=?|>>=?|<<=?|<>|!=|//=?|[+\-*/%&|^=<>]=?|~)|[][(){}]|(\r?\n|[:;.,`@]))|([uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'|[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*")|[a-zA-Z_]\w*))psycopg2)pymysqlMySQLdbmysql.connector)sqlite3pysqlite2.dbapi2sqlitec                       e Zd ZdZdS )r   zraised for unsupported dbmsN__name__
__module____qualname____doc__     5/var/www/media/lib/python3.11/site-packages/web/db.pyr   r   >   s        %%Dr*   r   c                       e Zd Zd Zd ZdS )
_ItplErrorc                 V    t                               |            || _        || _        d S N)
ValueError__init__textpos)selfr2   r3   s      r+   r1   z_ItplError.__init__E   s(    D!!!	r*   c                 >    dt          | j                  | j        fz  S )Nz&unfinished expression in %s at char %d)reprr2   r3   r4   s    r+   __str__z_ItplError.__str__J   s    74	??DH:UUUr*   N)r%   r&   r'   r1   r8   r)   r*   r+   r-   r-   D   s7          
V V V V Vr*   r-   c                       e Zd ZdS )r   N)r%   r&   r'   r)   r*   r+   r   r   N   s        Dr*   r   c                       e Zd ZdZdS )r   zl
    raised for unsupported db paramstyles

    (currently supported: qmark, numeric, format, pyformat)
    Nr$   r)   r*   r+   r   r   R   s          	Dr*   r   c                   J    e Zd ZdZdgZd ZddZd Zd Zd Z	d	 Z
d
 Zd ZdS )r   a  
    Parameter in SQLQuery.

        >>> q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam("joe")])
        >>> q
        <sql: "SELECT * FROM test WHERE name='joe'">
        >>> q.query()
        'SELECT * FROM test WHERE name=%s'
        >>> q.values()
        ['joe']
    valuec                     || _         d S r/   )r<   r4   r<   s     r+   r1   zSQLParam.__init__k   s    


r*   pyformatc                 P    |dk    rdS |dk    rdS ||dv rdS t          |          )Nqmark?numeric:1formatr?   %s)r   )r4   
paramstyles     r+   
get_markerzSQLParam.get_markern   sF      39$$4:1G#G#G4
+++r*   c                 "    t          | g          S r/   r   r7   s    r+   sqlqueryzSQLParam.sqlqueryw   s    r*   c                 0    |                                  |z   S r/   rL   r4   others     r+   __add__zSQLParam.__add__z   s    }}&&r*   c                 0    ||                                  z   S r/   rN   rO   s     r+   __radd__zSQLParam.__radd__}   s    t}}&&r*   c                 *    t          | j                  S r/   )strr<   r7   s    r+   r8   zSQLParam.__str__   s    4:r*   c                 L    t          |t                    o|j        | j        k    S r/   
isinstancer   r<   rO   s     r+   __eq__zSQLParam.__eq__        %**Hu{dj/HHr*   c                 0    dt          | j                  z  S )Nz<param: %s>)r6   r<   r7   s    r+   __repr__zSQLParam.__repr__   s    tDJ////r*   N)r?   )r%   r&   r'   r(   	__slots__r1   rI   rL   rQ   rS   r8   rY   r\   r)   r*   r+   r   r   \   s        
 
 	I  , , , ,     ' ' '' ' '  I I I0 0 0 0 0r*   r   c                       e Zd ZdZdgZddZd Zd Zd Zd Z	d	 Z
d
 ZddZd ZddZ ee          Zd Zd Zd Zd ZdS )r   aI  
    You can pass this sort of thing as a clause in any db function.
    Otherwise, you can pass a dictionary to the keyword argument `vars`
    and the function will call reparam for you.

    Internally, consists of `items`, which is a list of strings and
    SQLParams, which get concatenated to produce the actual query.
    itemsNc                    |g | _         nrt          |t                    r|| _         nUt          |t                    r	|g| _         n7t          |t                    rt          |j                   | _         n|g| _         t          | j                   D ]H\  }}t          |t                    r.t          |j        t                    r|j        j        | j         |<   IdS )a_  Creates a new SQLQuery.

        >>> SQLQuery("x")
        <sql: 'x'>
        >>> q = SQLQuery(['SELECT * FROM ', 'test', ' WHERE x=', SQLParam(1)])
        >>> q
        <sql: 'SELECT * FROM test WHERE x=1'>
        >>> q.query(), q.values()
        ('SELECT * FROM test WHERE x=%s', [1])
        >>> SQLQuery(SQLParam(1))
        <sql: '1'>
        N)	r_   rX   listr   r   	enumerater<   r   v)r4   r_   iitems       r+   r1   zSQLQuery.__init__   s     =DJJt$$ 	!DJJx(( 	!DJJx(( 	!ek**DJJDJ !,, 	- 	-GAt$)) -jZ.P.P - $

1	- 	-r*   c                 :    | j                             |           d S r/   )r_   appendr>   s     r+   rg   zSQLQuery.append   s    
%     r*   c                     t          |t                    r|g}n$t          |t                    r|j        }nt          S t          | j        |z             S r/   rX   rU   r   r_   NotImplementedr4   rP   r_   s      r+   rQ   zSQLQuery.__add__   sS    eS!! 	"GEEx(( 	"KEE!!
U*+++r*   c                     t          |t                    r|g}n$t          |t                    r|j        }nt          S t          || j        z             S r/   ri   rk   s      r+   rS   zSQLQuery.__radd__   sS    eS!! 	"GEEx(( 	"KEE!!
*+++r*   c                     t          |t          t          f          r| j                            |           n<t          |t
                    r | j                            |j                   nt          S | S r/   )rX   rU   r   r_   rg   r   extendrj   rO   s     r+   __iadd__zSQLQuery.__iadd__   si    ec8_-- 	"Je$$$$x(( 	"Jek****!!r*   c                 D    t          |                                           S r/   )lenqueryr7   s    r+   __len__zSQLQuery.__len__   s    4::<<   r*   c                 L    t          |t                    o|j        | j        k    S r/   )rX   r   r_   rO   s     r+   rY   zSQLQuery.__eq__   rZ   r*   c                 j   g }| j         D ]}t          |t                    r8|                    |          }|                    t          |                     Ot          |          }|dv rd|v rd|vr|                    dd          }|                    |           d                    |          S )a/  
        Returns the query part of the sql query.
            >>> q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam('joe')])
            >>> q.query()
            'SELECT * FROM test WHERE name=%s'
            >>> q.query(paramstyle='qmark')
            'SELECT * FROM test WHERE name=?'
        rE   %z%% )r_   rX   r   rI   rg   r   replacejoin)r4   rH   sxs       r+   rr   zSQLQuery.query   s      	 	A!X&& LL,,$$$$AJJ !777axxDMMIIc400wwqzzr*   c                 $    d | j         D             S )z
        Returns the values of the parameters used in the sql query.
            >>> q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam('joe')])
            >>> q.values()
            ['joe']
        c                 F    g | ]}t          |t                    |j        S r)   rW   ).0rd   s     r+   
<listcomp>z#SQLQuery.values.<locals>.<listcomp>   s)    GGGAz!X/F/FGGGGr*   )r_   r7   s    r+   valueszSQLQuery.values   s     HGGGGGr*    c                    |t                      }|j        }|r|                    |           t          |           D ]r\  }}|dk    r|dk    r|                    |           t	          |t                     r|                    |j                   V|dk    r]|                    |           s|r|                    |           |S )a  
        Joins multiple queries.

        >>> SQLQuery.join(['a', 'b'], ', ')
        <sql: 'a, b'>

        Optionally, prefix and suffix arguments can be provided.

        >>> SQLQuery.join(['a', 'b'], ', ', prefix='(', suffix=')')
        <sql: '(a, b)'>

        If target argument is provided, the items are appended to target
        instead of creating a new SQLQuery.
        Nr   rw   )r   r_   rg   rb   rX   rn   )r_   sepprefixsuffixtargettarget_itemsrd   re   s           r+   ry   zSQLQuery.join   s     >ZZF| 	(''' '' 	* 	*GAtAvv#))##C((($)) *##DJ////##D)))) 	('''r*   c                     	 |                                  t          d |                                 D                       z  S # t          t          f$ r |                                  cY S w xY w)Nc                 ,    g | ]}t          |          S r)   )sqlifyr~   r{   s     r+   r   z!SQLQuery._str.<locals>.<listcomp>&  s    (J(J(Jq(J(J(Jr*   )rr   tupler   r0   	TypeErrorr7   s    r+   _strzSQLQuery._str$  sm    	 ::<<%(J(JDKKMM(J(J(J"K"KKKI& 	  	  	 ::<<	 s   ?A %A*)A*c                 D    t          |                                           S r/   )r   r   r7   s    r+   r8   zSQLQuery.__str__*  s    tyy{{###r*   c                 D    t          |                                           S r/   )r   r   r7   s    r+   __unicode__zSQLQuery.__unicode__-  s    499;;'''r*   c                 @    dt          t          |                     z  S )Nz	<sql: %s>)r6   rU   r7   s    r+   r\   zSQLQuery.__repr__0  s    T#d))__,,r*   r/   )r   NNN)r%   r&   r'   r(   r]   r1   rg   rQ   rS   ro   rs   rY   rr   r   ry   staticmethodr   r8   r   r\   r)   r*   r+   r   r      s          	I- - - -:! ! !, , ,, , ,  ! ! !I I I   2H H H# # # #J <D     $ $ $( ( (- - - - -r*   r   c                       e Zd ZdZd Zd ZdS )r   z
    Protects a string from `sqlquote`.

        >>> sqlquote('NOW()')
        <sql: "'NOW()'">
        >>> sqlquote(SQLLiteral('NOW()'))
        <sql: 'NOW()'>
    c                     || _         d S r/   rc   )r4   rc   s     r+   r1   zSQLLiteral.__init__>  s    r*   c                     d| j         z  S )Nz<literal: %r>r   r7   s    r+   r\   zSQLLiteral.__repr__A  s    ''r*   N)r%   r&   r'   r(   r1   r\   r)   r*   r+   r   r   4  s<           ( ( ( ( (r*   r   c                    g }|                     d           t          | t                    rt          |           } n1t          | t                    rt          t          |                     } t          |           D ]B\  }}|dk    r|                     d           |                     t          |                     C|                     d           t          |          S )z
    >>> _sqllist([1, 2, 3])
    <sql: '(1, 2, 3)'>
    >>> _sqllist(set([5, 1, 3, 2]))
    <sql: '(1, 2, 3, 5)'>
    >>> _sqllist((5, 1, 3, 2, 2, 5))
    <sql: '(1, 2, 3, 5)'>
    (r   , ))rg   rX   setra   r   rb   r   r   )r   r_   rd   rc   s       r+   _sqllistr   H  s     E	LL&# #f	FE	"	" #c&kk""&!! " "166LLXa[[!!!!	LLE??r*   c                 F    t                                          | |          S )a#  
    Takes a string and a dictionary and interpolates the string
    using values from the dictionary. Returns an `SQLQuery` for the result.

        >>> reparam("s = $s", dict(s=True))
        <sql: "s = 't'">
        >>> reparam("s IN $s", dict(s=[1, 2]))
        <sql: 's IN (1, 2)'>
    )
SafeEvalsafeevalcopyobject_interpolateevalrg   r   r   ry   )string_
dictionaryresultlivechunkrc   s         r+   r   r   a  s     ::w
333r*   c                     | dS | du rdS | du rdS t          | t                    rt          |           S t          | t          j                  r!t	          |                                           S t	          |           S )z
    converts `obj` to its proper SQL version

        >>> sqlify(None)
        'NULL'
        >>> sqlify(True)
        "'t'"
        >>> sqlify(3)
        '3'
    NNULLTz't'Fz'f')rX   intrU   datetimer6   	isoformat)objs    r+   r   r   z  s~     {v	u	u	C		 3xx	C*	+	+ CMMOO$$$Cyyr*   c                 Z    t          | t                    r| S d                    |           S )z
    Converts the arguments for use in something like a WHERE clause.

        >>> sqllist(['a', 'b'])
        'a, b'
        >>> sqllist('a')
        'a'
    r   )rX   rU   ry   )lsts    r+   r   r     s+     #s 
yy~~r*   c                 `    t          |t                    rAt          |          }t          |          }|dk    rt	          d          S |dk    r|d         }t          |t                    r1t	          dgt           fd|D             g           z   dgz             S  t          |          z   S )a  
    `left is a SQL clause like `tablename.arg = `
    and `lst` is a list of values. Returns a reparam-style
    pair featuring the SQL that ORs together the clause
    for each item in the lst.

        >>> sqlors('foo = ', [])
        <sql: '1=2'>
        >>> sqlors('foo = ', [1])
        <sql: 'foo = 1'>
        >>> sqlors('foo = ', 1)
        <sql: 'foo = 1'>
        >>> sqlors('foo = ', [1,2,3])
        <sql: '(foo = 1 OR foo = 2 OR foo = 3 OR 1=2)'>
    r   z1=2r   r   c                 4    g | ]}t          |          d gS )z OR r   )r~   r{   lefts     r+   r   zsqlors.<locals>.<listcomp>  s&    BBB$V4BBBr*   z1=2))rX   r   ra   rq   r   sumr   )r   r   lns   `  r+   r   r     s      #u 3iiXX77E??"77a&C#u $ECBBBBcBBBBGGG6(R
 
 	
 hsmm##r*    AND c                 L    t                               d | D             |          S )a  
    Converts a two-tuple (key, value) iterable `data` to an SQL WHERE clause
    `SQLQuery`.

        >>> sqlwhere((('cust_id', 2), ('order_id',3)))
        <sql: 'cust_id = 2 AND order_id = 3'>
        >>> sqlwhere((('order_id', 3), ('cust_id', 2)), grouping=', ')
        <sql: 'order_id = 3, cust_id = 2'>
        >>> sqlwhere((('a', 'a'), ('b', 'b'))).query()
        'a = %s AND b = %s'
    c                 >    g | ]\  }}|d z   t          |          z   S ) = r   )r~   krc   s      r+   r   zsqlwhere.<locals>.<listcomp>  s+    CCCda!e)hqkk1CCCr*   )r   ry   )datagroupings     r+   sqlwherer     s'     ==CCdCCCXNNNr*   c                     t          | t          t          t          f          rt	          |           S t          |                                           S )a8  
    Ensures `a` is quoted properly for use in a SQL query.

        >>> 'WHERE x = ' + sqlquote(True) + ' AND y = ' + sqlquote(3)
        <sql: "WHERE x = 't' AND y = 3">
        >>> 'WHERE x = ' + sqlquote(True) + ' AND y IN ' + sqlquote([2, 3])
        <sql: "WHERE x = 't' AND y IN (2, 3)">
        >>> 'WHERE x = ' + sqlquote(True) + ' AND y IN ' + sqlquote(set([3, 2, 3, 4]))
        <sql: "WHERE x = 't' AND y IN (2, 3, 4)">
        >>> 'WHERE x = ' + sqlquote(True) + ' AND y IN ' + sqlquote((3, 2, 3, 4))
        <sql: "WHERE x = 't' AND y IN (2, 3, 4)">
    )rX   ra   r   r   r   r   rL   )as    r+   r   r     sA     !dE3'(( &{{{{##%%%r*   c                   B    e Zd ZdZd Zd Zd Zd Zd ZeZ	d
dZ
d	 ZdS )BaseResultSetz<Base implementation of Result Set, the result of a db query.c                 N    || _         d |j        D             | _        d| _        d S )Nc                     g | ]
}|d          S )r   r)   r   s     r+   r   z*BaseResultSet.__init__.<locals>.<listcomp>  s    777qad777r*   r   )cursordescriptionnames_indexr4   r   s     r+   r1   zBaseResultSet.__init__  s,    77F$6777
r*   c                       fd j                                         D             } xj        t          |          z  c_        |S )Nc                 :    g | ]}                     |          S r)   )_prepare_row)r~   dr4   s     r+   r   z&BaseResultSet.list.<locals>.<listcomp>  s'    EEE!!!$$EEEr*   )r   fetchallr   rq   )r4   rowss   ` r+   ra   zBaseResultSet.list  sE    EEEEdk.B.B.D.DEEEs4yy r*   c                 `    t          t          t          | j        |                              S r/   )r   dictzipr   r4   rows     r+   r   zBaseResultSet._prepare_row  s$    tC
C0011222r*   c                     | S r/   r)   r7   s    r+   __iter__zBaseResultSet.__iter__      r*   c                     | j                                         }|t                      | xj        dz  c_        |                     |          S Nr   )r   fetchoneStopIterationr   r   r   s     r+   __next__zBaseResultSet.__next__  sH    k""$$;//!q  %%%r*   Nc                 `    	 t          t          |                     S # t          $ r |cY S w xY w)zReturns the first row of this ResultSet or None when there are no
        elements.

        If the optional argument default is specified, that is returned instead
        of None when there are no elements.
        )nextiterr   )r4   defaults     r+   firstzBaseResultSet.first  s?    	T

### 	 	 	NNN	s    --c                 T   || j         k     rt          dt          |          z             	 || j         k    r*t          |            | xj         dz  c_         || j         k    *| xj         dz  c_         t          |           S # t          $ r t          t          |                    w xY w)Nzalready passed r   )r   
IndexErrorrU   r   r   )r4   rd   s     r+   __getitem__zBaseResultSet.__getitem__  s    t{??.Q7888	%dk//T


q  dk// KK1KK:: 	% 	% 	%SVV$$$	%s   AB   'B'r/   )r%   r&   r'   r(   r1   ra   r   r   r   r   r   r   r)   r*   r+   r   r     s        FF  
  
3 3 3  & & & D
 
 
 
% % % % %r*   r   c                       e Zd ZdZd ZdS )	ResultSetzThe result of a database query.c                 4    t          | j        j                  S r/   )r   r   rowcountr7   s    r+   rs   zResultSet.__len__"  s    4;'(((r*   N)r%   r&   r'   r(   rs   r)   r*   r+   r   r     s)        ))) ) ) ) )r*   r   c                   .     e Zd ZdZd Z fdZd Z xZS )SqliteResultSetz\Result Set for sqlite.

    Same functionally as ResultSet except len is not supported.
    c                 J    t                               | |           d | _        d S r/   )r   r1   _headr   s     r+   r1   zSqliteResultSet.__init__,  s#    tV,,,


r*   c                     | j         | xj        dz  c_        | j         S t                                                      S r   )r   r   superr   )r4   	__class__s    r+   r   zSqliteResultSet.__next__0  s9    :!KK1KK:77##%%%r*   c                     | j         7	 t          |           | _         | xj        dz  c_        n# t          $ r Y dS w xY wdS )Nr   FT)r   r   r   r   r7   s    r+   __bool__zSqliteResultSet.__bool__7  sW     :!$ZZ
q     uuts   $. 
<<)r%   r&   r'   r(   r1   r   r   __classcell__)r   s   @r+   r   r   &  s`         
  & & & & &
 
 
 
 
 
 
r*   r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )TransactionzDatabase transaction.c                    | _         t          j                  x| _         G fdd          } G fdd          } G d d          }| j        r:| j                             d          r |            | _        n |            | _        n |            | _        | j                                         | j         j                            |            d S )Nc                   2    e Zd ZdZ fdZ fdZ fdZdS )0Transaction.__init__.<locals>.transaction_enginez2Transaction Engine used in top level transactions.c                 4                         d           d S )NF)unloadcommitr4   ctxs    r+   do_transactz<Transaction.__init__.<locals>.transaction_engine.do_transactN  s    

%
(((((r*   c                 0                                      d S r/   r   r   s    r+   	do_commitz:Transaction.__init__.<locals>.transaction_engine.do_commitQ  s    

r*   c                 0                                      d S r/   )rollbackr   s    r+   do_rollbackz<Transaction.__init__.<locals>.transaction_engine.do_rollbackT  s    r*   Nr%   r&   r'   r(   r   r  r  )r   s   r+   transaction_enginer   K  sf        DD) ) ) ) )          r*   r  c                   2    e Zd ZdZ fdZd Zd Zd ZdS )3Transaction.__init__.<locals>.subtransaction_enginez,Transaction Engine used in sub transactions.c                     j                                         }                    |t          |z                       d S r/   )dbr   
db_executer   )r4   q	db_cursorr   transaction_counts      r+   rr   z9Transaction.__init__.<locals>.subtransaction_engine.queryZ  s:    FMMOO	y(17H3H*I*IJJJJJr*   c                 0    |                      d           d S )NzSAVEPOINT webpy_sp_%srr   r7   s    r+   r   z?Transaction.__init__.<locals>.subtransaction_engine.do_transact^  s    

233333r*   c                 0    |                      d           d S )NzRELEASE SAVEPOINT webpy_sp_%sr  r7   s    r+   r  z=Transaction.__init__.<locals>.subtransaction_engine.do_commita  s    

:;;;;;r*   c                 0    |                      d           d S )Nz!ROLLBACK TO SAVEPOINT webpy_sp_%sr  r7   s    r+   r  z?Transaction.__init__.<locals>.subtransaction_engine.do_rollbackd  s    

>?????r*   N)r%   r&   r'   r(   rr   r   r  r  )r   r  s   r+   subtransaction_enginer  W  sq        >>K K K K K K4 4 4< < <@ @ @ @ @r*   r  c                        e Zd ZdZd xZxZZdS )*Transaction.__init__.<locals>.dummy_enginezmTransaction Engine used instead of subtransaction_engine
            when sub transactions are not supported.c                     d S r/   r)   r7   s    r+   <lambda>z3Transaction.__init__.<locals>.dummy_engine.<lambda>k  s     r*   Nr  r)   r*   r+   dummy_enginer  g  s-        8 8 5F4EEKE)kkkr*   r  ignore_nested_transactions)r   rq   transactionsr  getenginer   rg   )r4   r   r  r  r  r  s    `   @r+   r1   zTransaction.__init__G  sP   589I5J5JJ!2
	 
	 
	 
	 
	 
	 
	 
	 
	 
		@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	F 	F 	F 	F 	F 	F 	F 	F ! 	/x||899 6*lnn3355,,..DK!!!$$T*****r*   c                     | S r/   r)   r7   s    r+   	__enter__zTransaction.__enter__y  r   r*   c                 ^    ||                                   d S |                                  d S r/   )r  r   )r4   exctypeexcvalue	tracebacks       r+   __exit__zTransaction.__exit__|  s*    MMOOOOOKKMMMMMr*   c                     t          | j        j                  | j        k    r>| j                                         | j        j        d | j                 | j        _        d S d S r/   )rq   r   r  r  r  r  r7   s    r+   r   zTransaction.commit  s\    tx$%%(>>>K!!###$(H$9:RD<R:R$SDH!!! ?>r*   c                     t          | j        j                  | j        k    r>| j                                         | j        j        d | j                 | j        _        d S d S r/   )rq   r   r  r  r  r  r7   s    r+   r  zTransaction.rollback  s\    tx$%%(>>>K##%%%$(H$9:RD<R:R$SDH!!! ?>r*   N)	r%   r&   r'   r(   r1   r  r#  r   r  r)   r*   r+   r   r   D  sn        0+ 0+ 0+d    T T T
T T T T Tr*   r   c                       e Zd ZdZd Zd Z ee          Zd Zd Z	d Z
d Zd Zd	 Zd
 Zd Zd Zd ZddZd Z	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 d dZd Zd Zd!dZd Zd!dZd!dZd"dZd Zd ZdS )#r   Databasec                 r   |                     dd           || _        || _        t                      | _        t          j        dt          j        dd                    | _        d| _        	 ddl	}d| _
        n# t          $ r
 d| _
        Y nw xY w| j                             dd          o| j
        | _
        dS )	zCreates a database.driverN	debug_sqlr   Fr   Tpooling)pop	db_modulekeywordsr	   _ctxr   r  printingsupports_multiple_insertDBUtilshas_poolingImportError)r4   r-  r.  r2  s       r+   r1   zDB.__init__  s     	Xt$$$"  NN	
;
7E0J0JKK(-%	%NNN  $D 	% 	% 	%$D	%  =,,Y==R$BRs   -A9 9BBc                 x    | j                             d          s|                     | j                    | j         S )Nr
  )r/  r  _load_contextr7   s    r+   _getctxz
DB._getctx  s6    y}}T"" 	*ty)))yr*   c                     d_         g _         j        r                       j                  _        n                      j                  _         j        _        t          j        d          sd j        _
        t          j        d          sd j        _        d	 fd	} fd}|_
        |_        d S )
Nr   r   c                      d S r/   r)   r)   r*   r+   r  z"DB._load_context.<locals>.<lambda>  s    D r*   r  c                      d S r/   r)   r)   r*   r+   r  z"DB._load_context.<locals>.<lambda>  s    d r*   Tc                     j                                          | r#j        r                    j                   d S d S d S r/   )r
  r   r3  _unload_contextr/  )r   r   r4   s    r+   r   z DB._load_context.<locals>.commit  sT    FMMOOO 0$* 0$$TY/////0 0 0 0r*   c                       j                                          j        r                    j                   d S d S r/   )r
  r  r3  r<  r/  )r   r4   s   r+   r  z"DB._load_context.<locals>.rollback  sF    FOO 0$$TY/////0 0r*   )T)	dbq_countr  r3  _connect_with_poolingr.  r
  _connect_db_executer  hasattrr   r  )r4   r   r   r  s   ``  r+   r6  zDB._load_context  s     	2//>>CFF]]4=11CF)svx(( 	)(LCFMsvz** 	+*lCFO	0 	0 	0 	0 	0 	0 	0	0 	0 	0 	0 	0 	0 
r*   c                 
    |` d S r/   )r
  r   s     r+   r<  zDB._unload_context  s    FFFr*   c                 &     | j         j        di |S )Nr)   )r-  connect)r4   r.  s     r+   r@  zDB._connect  s    %t~%11111r*   c                       fd}t           dd            |             _         j                                        S )Nc                      ddl m}  | j                            d          d                    d          k     r | j        ddj        iS  | j        ddj        iS )Nr   )PooledDB.z0.9.3dbapicreatorr)   )r2  rH  __version__splitr-  )rH  r.  r4   s    r+   get_pooled_dbz/DB._connect_with_pooling.<locals>.get_pooled_db  s    ((((((
 #))#..s1C1CCC(x(JJt~JJJJ(x(LLL8LLLr*   	_pooleddb)getattrrO  
connection)r4   r.  rN  s   `` r+   r?  zDB._connect_with_pooling  s]    		M 		M 		M 		M 		M 		M 4d++3*]__DN~((***r*   c                 >    | j         j                                        S r/   )r   r
  r   r7   s    r+   
_db_cursorzDB._db_cursor  s    x{!!###r*   c                 n    t          | dd          }|dk    rdS |dk    rdS |dv rdS t          |          )	zHReturns parameter marker based on paramstyle attribute if this database.rH   r?   rA   rB   rC   rD   rE   rG   )rP  r   )r4   styles     r+   _param_markerzDB._param_marker  sR    lJ77G3i4,,,4&&&r*   c           	      l   | j         xj        dz  c_        	 t          j                    }|                     |          \  }}|                    ||          }t          j                    }n{#  | j        r$t          dt          |          t                     | j         j	        r%| j         j	        d         
                                 n| j         
                                  xY w| j        rFt          t          ||z
  d          d| j         j        dt          |          t                     |S )zexecutes an sql queryr   zERR:)file    (z): )r   r>  time_process_queryexecuter0  printrU   r   r  r  round)r4   cur	sql_queryr   rr   paramsoutbs           r+   rA  zDB._db_execute  s(   a		A //	::ME6++eV,,C	AA	} :fc)nn59999x$ $%b)224444!!###= 	!&q1ua$(2D2D2Dc)nnnU    
s   AA, ,A8C$c                 ~    t          | dd          }|                    |          }|                                }||fS zBTakes the SQLQuery object and returns query string and parameters.rH   r?   )rP  rr   r   r4   rb  rH   rr   rc  s        r+   r]  zDB._process_query  s?    T<<<

++!!##f}r*   c                    t          |t                    rdt          |          z   }nt          |t          t          f          r0t          |          dk    rt          |d         |d                   }nQt          |t                    r|                     |          }n&t          |t                    rnt          ||          }|S )Nid = rZ  r   r   )
rX   r   r   ra   r   rq   r   r   _where_dictr   )r4   wherevarss      r+   _wherez	DB._where  s    eS!! 
	)huoo-EEe}-- 	)#e**//U1XuQx00EEt$$ 	)$$U++EEx(( 	)E4((Er*   c                     g }t          t          |          d           D ]-\  }}|                    |dz   t          |          z              .|rt                              |d          S d S )Nc                     | d         S Nr   r)   ts    r+   r  z DB._where_dict.<locals>.<lambda>&  s
    1Q4 r*   keyr   r   )sortedr   rg   r   r   ry   )r4   rl  where_clausesr   rc   s        r+   rk  zDB._where_dict#  sx    9U++@@@ 	: 	:DAq  UXa[[!89999 	==8884r*   NFc                 J   |i }|s%t          |t                    st          ||          }|r|S |                                 }|                     ||           |j        r|                     |          }n|j        }| j        j	        s| j        
                                 |S )a]  
        Execute SQL query `sql_query` using dictionary `vars` to interpolate it.
        If `processed=True`, `vars` is a `reparam`-style list to use
        instead of interpolating.

            >>> db = DB(None, {})
            >>> db.query("SELECT * FROM foo", _test=True)
            <sql: 'SELECT * FROM foo'>
            >>> db.query("SELECT * FROM foo WHERE x = $x", vars=dict(x='f'), _test=True)
            <sql: "SELECT * FROM foo WHERE x = 'f'">
            >>> db.query("SELECT * FROM foo WHERE x = " + sqlquote('f'), _test=True)
            <sql: "SELECT * FROM foo WHERE x = 'f'">
        )rX   r   r   rS  rA  r   create_result_setr   r   r  r   )r4   rb  rm  	processed_testr  rd  s          r+   rr   zDB.query-  s     <D 	1Ix!@!@ 	1	400I 	OO%%	I...  	%((33CC$Cx$ 	HOO
r*   c                      t          |          S r/   )r   r   s     r+   ry  zDB.create_result_setP  s       r*   *c
           	           i                       |||||||          }
 fd|
D             }t                              |          }|	r|S                      |d          S )aT  
        Selects `what` from `tables` with clauses `where`, `order`,
        `group`, `limit`, and `offset`. Uses vars to interpolate.
        Otherwise, each clause can be a SQLQuery.

            >>> db = DB(None, {})
            >>> db.select('foo', _test=True)
            <sql: 'SELECT * FROM foo'>
            >>> db.select(['foo', 'bar'], where="foo.bar_id = bar.id", limit=5, _test=True)
            <sql: 'SELECT * FROM foo, bar WHERE foo.bar_id = bar.id LIMIT 5'>
            >>> db.select('foo', where={'id': 5}, _test=True)
            <sql: 'SELECT * FROM foo WHERE id = 5'>
        Nc                 H    g | ]\  }}|                     ||          S r/   )
gen_clause)r~   sqlvalr4   rm  s      r+   r   zDB.select.<locals>.<listcomp>p  s:     
 
 
S OOCd++r*   T)rz  )sql_clausesr   ry   rr   )r4   tablesrm  whatrl  ordergrouplimitoffsetr{  r  clausesqouts   ` `          r+   selectz	DB.selectS  s    2 <D&&tVUE5%QWXX
 
 
 
 
'
 
 

 }}W%% 	Kzz$$z///r*   c           
      f    |                      |          }	|                     ||||||||	          S )a  
        Selects from `table` where keys are equal to values in `kwargs`.

            >>> db = DB(None, {})
            >>> db.where('foo', bar_id=3, _test=True)
            <sql: 'SELECT * FROM foo WHERE bar_id = 3'>
            >>> db.where('foo', source=2, crust='dewey', _test=True)
            <sql: "SELECT * FROM foo WHERE crust = 'dewey' AND source = 2">
            >>> db.where('foo', _test=True)
            <sql: 'SELECT * FROM foo'>
        )r  r  r  r  r  r{  rl  )rk  r  )
r4   tabler  r  r  r  r  r{  kwargsrl  s
             r+   rl  zDB.where|  sJ    ,   (({{  	
 	
 		
r*   c           
          d|fdt          |          fd|fd|fd|fd|o t          |                                          fd|o t          |                                          ffS )NSELECTFROMWHEREGROUP BYORDER BYLIMITOFFSET)r   r   rL   r4   r  r  rl  r  r  r  r  s           r+   r  zDB.sql_clauses  s|    tWV__%e e: 8 8 : :;v=(6"2"2";";"="=>
 	
r*   c                    t          |t                    r)|dk    rdt          |          z   }nt          |          }nt          |t          t
          f          r0t          |          dk    rt          |d         |d                   }nY|dk    r+t          |t                    r|                     |          }n(t          |t                    r|}nt          ||          }d } |||          S )Nr  rj  rZ  r   r   c                 "    | r
|r| dz   |z   S | p|S )Nr   r)   )r   re  s     r+   xjoinzDB.gen_clause.<locals>.xjoin  s(     Q 3w{"vAr*   )
rX   r   r   r   ra   r   rq   r   rk  r   )r4   r  r  rm  noutr  s         r+   r  zDB.gen_clause  s    c3 	&g~~#.}}dE]++ 	&CACFCF++DDG^^
3 5 5^##C((DDX&& 	&DD3%%D	 	 	 uS$r*   c                 `   d }|rt          |                                d           }t                              t	          d |          d          }t                              d t	          d |          D             d          }d|z   ||          z   d	z    ||          z   }	n"t          |                     |                    }	|r|	S |                                 }
|d
ur|                     |	||          }	t          |	t                    r2|	\  }}| 
                    |
|           | 
                    |
|           n| 
                    |
|	           	 |
                                d         }n# t          $ r d}Y nw xY w| j        j        s| j                                         |S )a3  
        Inserts `values` into `tablename`. Returns current sequence ID.
        Set `seqname` to the ID if it's not the default, or to `False`
        if there isn't one.

            >>> db = DB(None, {})
            >>> q = db.insert('foo', name='bob', age=2, created=SQLLiteral('NOW()'), _test=True)
            >>> q
            <sql: "INSERT INTO foo (age, created, name) VALUES (2, NOW(), 'bob')">
            >>> q.query()
            'INSERT INTO foo (age, created, name) VALUES (%s, NOW(), %s)'
            >>> q.values()
            [2, 'bob']
        c                     d| z   dz   S )Nr   r   r)   )r{   s    r+   r  zDB.insert.<locals>.q  s    7S= r*   c                     | d         S rq  r)   rr  s    r+   r  zDB.insert.<locals>.<lambda>  s
    1 r*   rt  c                     | d         S rq  r)   rr  s    r+   r  zDB.insert.<locals>.<lambda>  s
    ! r*   r   c                 ,    g | ]}t          |          S r)   r   )r~   rc   s     r+   r   zDB.insert.<locals>.<listcomp>  s    III!IIIr*   c                     | d         S r   r)   rr  s    r+   r  zDB.insert.<locals>.<lambda>  s
    AaD r*   zINSERT INTO %s z VALUES Fr   N)rv  r_   r   ry   map _get_insert_default_values_queryrS  _process_insert_queryrX   r   rA  r   	Exceptionr   r  r   )r4   	tablenameseqnamer{  r   r  sorted_values_keys_valuesrb  r  q1q2rd  s                 r+   insertz	DB.insert  s    	! 	! 	!  	S"6<<>>~~FFFMMM#nnm"D"DdKKEmmIIc..-&H&HIII4 G "I-%8:E'

R I !!F!Fy!Q!QRRI 	OO%%	%229iQQIi'' 	3 FBY+++Y++++Y	222	$$&&q)CC 	 	 	CCC	 x$ 	HOO
s   E7 7FFc                     d|z  S )NzINSERT INTO %s DEFAULT VALUESr)   r4   r  s     r+   r  z#DB._get_insert_default_values_query  s    .66r*   c                     |sg S  j         s fd|D             }du rdS |S |d                                         }|D ])}|                                |k    rt          d          *t          |          }t	          ddd                    |          d	          }t          |          D ]K\  }	|	dk    r|                    d           t                              fd
|D             d|dd           Lr|S                                  }
dur 	                    |          }t          |t                    r2|\  }}                     |
|                                |
|           n                     |
|           	 |
                                d         } j        j        t           v r!t#          ||t%          |          z             }n&t#          |t%          |          z
  dz   |dz             }n# t&          $ r d}Y nw xY w j        j        s j                                         |S )a  
        Inserts multiple rows into `tablename`. The `values` must be a list of
        dictionaries, one for each row to be inserted, each with the same set
        of keys. Returns the list of ids of the inserted rows.
        Set `seqname` to the ID if it's not the default, or to `False`
        if there isn't one.

            >>> db = DB(None, {})
            >>> db.supports_multiple_insert = True
            >>> values = [{"name": "foo", "email": "foo@example.com"}, {"name": "bar", "email": "bar@example.com"}]
            >>> db.multiple_insert('person', values=values, _test=True)
            <sql: "INSERT INTO person (email, name) VALUES ('foo@example.com', 'foo'), ('bar@example.com', 'bar')">
        c                 2    g | ]} j         fd |S ))r  r{  )r  )r~   rc   r{  r4   r  r  s     r+   r   z&DB.multiple_insert.<locals>.<listcomp>  sD        IIweIIqII  r*   FNr   zNot all rows have the same keyszINSERT INTO r[  r   z	) VALUES c                 :    g | ]}t          |                   S r)   )r   )r~   r   r   s     r+   r   z&DB.multiple_insert.<locals>.<listcomp>/  s%    000a#a&!!000r*   r   r   )r   r   r   r   r   )r1  keysr0   rv  r   ry   rb   rg   rS  r  rX   r   rA  r   r-  r%   mysql_driversrangerq   r  r   r  r   )r4   r  r   r  r{  rd  r  rc   rb  rd   r  r  r  r   s   `` ``        @r+   multiple_insertzDB.multiple_insert  s     	I, 	        C %t
ay~~  	D 	DAvvxx4 !BCCC   d||H-6YY		$H
 
	  '' 		 		FAsAvv  &&&MM00004000        	OO%%	%229iQQIi'' 	3 FBY+++Y++++Y	222
	$$&&q)C ~&-77Cs6{{!233C#f++-137;; 	 	 	CCC	 x$ 	HOO
s   A4H	 	HHc                    |i }|                      ||          }t          |                                d           }dt          |          z   dz   t	          |d          z   dz   |z   }|r|S |                                 }|                     ||           | j        j        s| j        	                                 |j
        S )ag  
        Update `tables` with clause `where` (interpolated using `vars`)
        and setting `values`.

            >>> db = DB(None, {})
            >>> name = 'Joseph'
            >>> q = db.update('foo', where='name = $name', name='bob', age=2,
            ...     created=SQLLiteral('NOW()'), vars=locals(), _test=True)
            >>> q
            <sql: "UPDATE foo SET age = 2, created = NOW(), name = 'bob' WHERE name = 'Joseph'">
            >>> q.query()
            'UPDATE foo SET age = %s, created = NOW(), name = %s WHERE name = %s'
            >>> q.values()
            [2, 'bob', 'Joseph']
        Nc                     | d         S rq  r)   rr  s    r+   r  zDB.update.<locals>.<lambda>j  s
    ad r*   rt  zUPDATE z SET r    WHERE )rn  rv  r_   r   r   rS  rA  r   r  r   r   )r4   r  rl  rm  r{  r   rr   r  s           r+   updatez	DB.updateV  s      <DE4((NN;;; foo vt$$% 	
  	  	LOO%%	E***x$ 	HOO!!r*   c                 6   |i }|                      ||          }d|z   }|r|dt          |          z   z  }|r|d|z   z  }|r|S |                                 }|                     ||           | j        j        s| j                                         |j        S )a  
        Deletes from `table` with clauses `where` and `using`.

            >>> db = DB(None, {})
            >>> name = 'Joe'
            >>> db.delete('foo', where='name = $name', vars=locals(), _test=True)
            <sql: "DELETE FROM foo WHERE name = 'Joe'">
        NzDELETE FROM z USING r  )rn  r   rS  rA  r   r  r   r   )r4   r  rl  usingrm  r{  r  r  s           r+   deletez	DB.delete~  s     <DE4((U" 	,WU^^++A 	#U""A 	HOO%%	A&&&x$ 	HOO!!r*   c                     |S r/   r)   r4   rr   r  r  s       r+   r  zDB._process_insert_query  s    r*   c                 *    t          | j                  S )zStart a transaction.)r   r   r7   s    r+   transactionzDB.transaction  s    48$$$r*   )NFF)Nr}  NNNNNF)r}  NNNNF)NF)NNF)r%   r&   r'   r(   r1   r7  propertyr   r6  r<  r@  r?  rS  rV  rA  r]  rn  rk  rr   ry  r  rl  r  r  r  r  r  r  r  r  r  r)   r*   r+   r   r     s       NS S S2  
 (7

C     >  2 2 2+ + +"$ $ $
' 
' 
'  2      ! ! ! !F! ! ! '0 '0 '0 '0X  
  
  
  
D
 
 
     09 9 9 9v7 7 7R R R Rh&" &" &" &"P" " " "<  % % % % %r*   r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )
PostgresDBzPostgres driver.c                    d|v r|                     d          |d<   t          t          |                     dd                     }|j        dk    r(dd l}|j                            |j        j                   d|v r|                     d          |d<   d	| _        |j	        | _	        t                              | ||           d
| _        d | _        d S )Npwpasswordr)  	preferredr   r   r
  r   postgresT)r,  import_driver
pg_driversr%   psycopg2.extensions
extensionsregister_typeUNICODEdbnamerH   r   r1   r1  
_sequences)r4   r.  r-  r   s       r+   r1   zPostgresDB.__init__  s    8#+<<#5#5HZ !*Xt8T8TUUU	++&&&&--h.A.IJJJ 8#+<<#5#5HZ  #.
D)X...(,%r*   c                 X    ||dz   }||                                  vrd }|r|d|z  z  }|S )N_id_seqz; SELECT currval('%s'))_get_all_sequencesr  s       r+   r  z PostgresDB._process_insert_query  sJ    ?)+Gd557777 	8-77Er*   c                     | j         3d}t          d |                     |          D                       | _         | j         S )zDQuery postgres to find names of all sequences used in this database.Nz6SELECT c.relname FROM pg_class c WHERE c.relkind = 'S'c                     g | ]	}|j         
S r)   )relname)r~   cs     r+   r   z1PostgresDB._get_all_sequences.<locals>.<listcomp>  s    "D"D"D19"D"D"Dr*   )r  r   rr   )r4   r  s     r+   r  zPostgresDB._get_all_sequences  s?    ?"HA!"D"Ddjjmm"D"D"DEEDOr*   c                 f    t                               | |          }|                    d           |S NUTF8)r   r@  set_client_encodingr4   r.  conns      r+   r@  zPostgresDB._connect  s.    {{4**  (((r*   c                 z    t                               | |          }|j        j                            d           |S r  )r   r?  _conr  r  s      r+   r?  z PostgresDB._connect_with_pooling  s4    ''h77	**6222r*   N)	r%   r&   r'   r(   r1   r  r  r@  r?  r)   r*   r+   r  r    se          *
 
 
    
    r*   r  c                        e Zd Zd Zd Zd ZdS )MySQLDBc                    t          t          |                    dd                     }|j        dk    rd|v r|d         |d<   |d= n[|j        dk    rd|v r|                    d          |d<   n3|j        dk    r(|                    d	d
           d|v r|d         |d<   |d= d|vrd|d<   n|d         |d= dx| _        |_        d| _        t                              | ||           d
| _	        d S )Nr)  r  r   r  r  r   passwdr   bufferedTcharsetutf8r?   mysql)
r  r  r,  r%   
setdefaultrH   r  r   r1   r1  r4   r.  r
  s      r+   r1   zMySQLDB.__init__  s'   =HLL44P4PQQQ;)##x'/~$TN[I%%x%-\\$%7%7"[---
D111x'/~$TNH$$"(HYi (#*44"-
D"h'''(,%%%r*   c                 $    |t          d          fS )NzSELECT last_insert_id();rK   r  s       r+   r  zMySQLDB._process_insert_query  s    h9::::r*   c                     d|z  S )NzINSERT INTO %s () VALUES()r)   r  s     r+   r  z(MySQLDB._get_insert_default_values_query  s    +e33r*   N)r%   r&   r'   r1   r  r  r)   r*   r+   r  r    sA        - - ->; ; ;4 4 4 4 4r*   r  c                     |r|f} | D ]'}	 t          |dddg          c S # t          $ r Y $w xY wt          dd                    |           z             )z6Import the first available driver or preferred driver.Nr{   zUnable to import z or )
__import__r4  ry   )driversr  r   s      r+   r  r    s     ,  	atcU33333 	 	 	D	
)FKK,@,@@
A
AAs    
--c                        e Zd Zd Zd Zd ZdS )SqliteDBc                 H   t          t          |                    dd                     }|j        dv rd|_        |                    d|j                   d| _        |j        | _        |                    d          |d<   d	|d
<   t          	                    | ||           d S )Nr)  r  )r    r!   rA   detect_typesr"   r
  r   Fr+  )
r  sqlite_driversr,  r%   rH   r  PARSE_DECLTYPESr  r   r1   r  s      r+   r1   zSqliteDB.__init__  s    >X\\(D5Q5QRRR;999#BM 	NB,>???-'||D11 $
D"h'''''r*   c                 $    |t          d          fS )NzSELECT last_insert_rowid();rK   r  s       r+   r  zSqliteDB._process_insert_query$  s    h<====r*   c                      t          |          S r/   )r   r   s     r+   ry  zSqliteDB.create_result_set'  s    v&&&r*   N)r%   r&   r'   r1   r  ry  r)   r*   r+   r  r    sA        ( ( (*> > >' ' ' ' 'r*   r  c                   &    e Zd ZdZd ZddZd ZdS )
FirebirdDBzFirebird Database.c                     	 dd l }n# t          $ r d }Y nw xY wd|v r|                    d          |d<   |                    d          |d<   |j        | _        t                              | ||           d S )Nr   r  r  r
  r   )kinterbasdbr  r,  rH   r   r1   r  s      r+   r1   zFirebirdDB.__init__.  s    	$$$$$ 	 	 	BD	 8#+<<#5#5HZ '||D11-
D"h'''''s    NFc                 D    d }t                               | |||||          S r/   )r   r  )r4   r  rl  r  rm  r{  s         r+   r  zFirebirdDB.delete<  s#    yyueUD%@@@r*   c           	      L    dd|fd|fd|fdt          |          fd|fd|fd|ffS )	N)r  rw   FIRSTSKIPrw   r  r  r  r  r   r  s           r+   r  zFirebirdDB.sql_clausesA  sL    eVJWV__%e	
 		
r*   )NNNF)r%   r&   r'   r(   r1   r  r  r)   r*   r+   r  r  +  sP        ( ( (A A A A


 

 

 

 

r*   r  c                   &    e Zd Zd Zd Zd Zd ZdS )MSSQLDBc                     dd l }d|v r|                    d          |d<   |                    d          |d<   d| _        t                              | ||           d S )Nr   r  r  r
  r   mssql)pymssqlr,  r  r   r1   r  s      r+   r1   zMSSQLDB.__init__O  sh    8#+<<#5#5HZ '||D11
D"h'''''r*   c                     t          | dd          }|                    |          }|                                }|t          |          fS rg  )rP  rr   r   r   rh  s        r+   r]  zMSSQLDB._process_queryX  sH     T<<<

++!!##eFmm##r*   c                 J    d|fd|fdt          |          fd|fd|fd|fd|ffS )Nr  TOPr  r  r  r  r  r  r  s           r+   r  zMSSQLDB.sql_clausesa  sI    tENWV__%ev
 	
r*   c                     dS )an  Test LIMIT.

        Fake presence of pymssql module for running tests.
        >>> import sys
        >>> sys.modules['pymssql'] = sys.modules['sys']

        MSSQL has TOP clause instead of LIMIT clause.
        >>> db = MSSQLDB(db='test', user='joe', pw='secret')
        >>> db.select('foo', limit=4, _test=True)
        <sql: 'SELECT * TOP 4 FROM foo'>
        Nr)   r7   s    r+   r{  zMSSQLDB._testl  s	     	r*   N)r%   r&   r'   r1   r]  r  r{  r)   r*   r+   r  r  N  sP        ( ( ($ $ $	
 	
 	
    r*   r  c                       e Zd Zd Zd ZdS )OracleDBc                    dd l }d|v r|                    d          |d<   |                    d          |d<   d| _        d|_        |j        | _        |                    dd            t                              | ||           d S )	Nr   r  r  r
  dsnoraclerC   r+  )	cx_Oracler,  r  rH   r   r1   r  s      r+   r1   zOracleDB.__init__|  s    8#+<<#5#5HZ  #,,t,,!- 	Y%%%
D"h'''''r*   c                     ||S |d|z  z   S )Nz; SELECT %s.currval FROM dualr)   r  s       r+   r  zOracleDB._process_insert_query  s    ?L:WDDDr*   N)r%   r&   r'   r1   r  r)   r*   r+   r  r  {  s7        ( ( ( E E E E Er*   r  c                     t          j         t          |                     }|j        dk    r|j        |j        dd         dS |j        |j        |j        |j        dd         |j        |j        dS )a%  
    Takes a URL to a database and parses it into an equivalent dictionary.

        >>> dburl2dict('postgres:///mygreatdb') == {'pw': None, 'dbn': 'postgres', 'db': 'mygreatdb', 'host': None, 'user': None, 'port': None}
        True
        >>> dburl2dict('postgres://james:day@serverfarm.example.net:5432/mygreatdb') == {'pw': 'day', 'dbn': 'postgres', 'db': 'mygreatdb', 'host': 'serverfarm.example.net', 'user': 'james', 'port': 5432}
        True
        >>> dburl2dict('postgres://james:day@serverfarm.example.net/mygreatdb') == {'pw': 'day', 'dbn': 'postgres', 'db': 'mygreatdb', 'host': 'serverfarm.example.net', 'user': 'james', 'port': None}
        True
        >>> dburl2dict('postgres://james:d%40y@serverfarm.example.net/mygreatdb') == {'pw': 'd@y', 'dbn': 'postgres', 'db': 'mygreatdb', 'host': 'serverfarm.example.net', 'user': 'james', 'port': None}
        True
        >>> dburl2dict('mysql://james:d%40y@serverfarm.example.net/mygreatdb') == {'pw': 'd@y', 'dbn': 'mysql', 'db': 'mygreatdb', 'host': 'serverfarm.example.net', 'user': 'james', 'port': None}
        True
        >>> dburl2dict('sqlite:///mygreatdb.db')
        {'db': 'mygreatdb.db', 'dbn': 'sqlite'}
        >>> dburl2dict('sqlite:////absolute/path/mygreatdb.db')
        {'db': '/absolute/path/mygreatdb.db', 'dbn': 'sqlite'}
    r"   r   N)dbnr
  )r  userr  r
  hostport)urlparser   schemepathusernamer  hostnamer  )urlpartss     r+   
dburl2dictr    sx    & gcll++E|x|5:abb>::: <N.*QRR.NJ
 
 	
r*   c                     | s|st           j        d         } | rt          |           }|                    d          }|t          v rt	          |         di |S t          |          )zCreates appropriate database using params.

    Pooling will be enabled if DBUtils module is available.
    Pooling can be disabled by passing pooling=False in params.
    DATABASE_URLr  Nr)   )osenvironr  r,  
_databasesr   )dburlrc  r  s      r+   r   r     st      + +
>* #E""
**U

C
j#(((((nnr*   c                     |t           | <   dS )a  
    Register a database.

        >>> class LegacyDB(DB):
        ...     def __init__(self, **params):
        ...        pass
        ...
        >>> register_database('legacy', LegacyDB)
        >>> db = database(dbn='legacy', db='test', user='joe', passwd='secret')
    N)r$  )nameclazzs     r+   register_databaser)    s     Jtr*   r  r  r"   firebirdr  r  c                    d }d}g }d}	 |                      d|          }|dk     rn| |dz            }|dk    r|                    d| ||         f           |dz   d}}|rB || |          \  }}|j        d         \  }	}
| |	|
         }|dk    r|dz   }n|d	k    r|dz
  }|B|                    d| |dz   |dz
           f           nN||v r|                    d| ||         f            || |dz             \  }}|t          |           k     r| |         d
k    r6|dz   t          |           k     r | |dz            |v r || |dz             \  }}n_| |         dv rT|dz   d}}|rJ || |          \  }}|j        d         \  }	}
| |	|
         }|d         dv r|dz   }n|d         dv r|dz
  }|Jnn|t          |           k     |                    d| |dz   |         f           n.|                    d| ||dz            f           |dz   |dk    z   }|t          |           k     r|                    d| |d         f           |S )z
    Takes a format string and returns a list of 2-tuples of the form
    (boolean, string) where boolean says whether string should be evaled
    or not.

    from <http://lfw.org/python/Itpl.py> (public domain, Ka-Ping Yee)
    c                     t                               | |          }|t          | |          ||                                fS r/   )	tokenprogmatchr-   end)r2   r3   r.  s      r+   matchorfailz!_interpolate.<locals>.matchorfail  s=    c**=T3'''eiikk!!r*   ?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_r   r   ${rZ     }rI  z([z)]N)findrg   regsrq   )rF   r0  	namecharschunksr3   dollarnextcharlevelr.  tstarttendtokens               r+   r   r     s   " " " RIF
C,1S#&&A::&1*%s??MM1fSZ01222!QC &([55
s$z!}vd{+C<<!AIEEc\\!AIE  & MM1fVaZ#'%9:;<<<<""MM1fSZ01222$VVaZ88JE3F##3K3&&a#f++--sQw944!,VS1W!=!=JE33C[D((!$q!C .%0[%=%=
s',z!} &vd{ 3 8t++$)AIEE"1X--$)AIE   . % F##& MM1fVaZ#%5678888MM1fS6A:%5678881*C0CY,1\ S[[q&,'(((Mr*   c                   "    e Zd ZddZd Zd ZdS )_NodeNc                 0    || _         || _        || _        d S r/   typer   second)r4   rD  r   rE  s       r+   r1   z_Node.__init__)  s    	
r*   c                     t          |t                    o/| j        |j        k    o| j        |j        k    o| j        |j        k    S r/   )rX   rA  rD  r   rE  rO   s     r+   rY   z_Node.__eq__.  sI    ue$$ ,	UZ',
ek), u|+		
r*   c                 8    d| j         d| j        d| j        dS )NzNode(r   r   rC  r7   s    r+   r\   z_Node.__repr__6  s#     %)YYY


DKKKHHr*   r/   )r%   r&   r'   r1   rY   r\   r)   r*   r+   rA  rA  (  sK           

 
 
I I I I Ir*   rA  c                   @    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
S )ParserzParser to parse string templates like "Hello $name".

    Loosely based on <http://lfw.org/python/Itpl.py> (public domain, Ka-Ping Yee)
    r1  c                 .    |                                   d S r/   )resetr7   s    r+   r1   zParser.__init__B  s    

r*   c                 0    d| _         d| _        d| _        d S )Nr   rw   )r3   r<  r2   r7   s    r+   rK  zParser.resetE  s    
			r*   c                 `    |                                   || _        |                                 S )z/Parses the given text and returns a parse tree.)rK  r2   	parse_allr4   r2   s     r+   r
   zParser.parseJ  s&    

	~~r*   c              #   4  K   	 | j                             d| j                  }|dk     rn)| j         |dz            }|| j        v rEt	          d| j         | j        |                   V  |dz   | _        |                                 V  n|dk    r|| j        }|dz   | _        |                                 }| j         | j                 dk    r9| xj        dz  c_        t	          d| j         | j        |                   V  |V  nO|| _        nIt	          d| j         | j        |dz                      V  |dz   | _        |dk    r| xj        dz  c_        Q| j        t          | j                   k     r&t	          d| j         | j        d                    V  d S d S )	NTr2  r   r   r2   r3  rZ  r5  )r2   r6  r3   r8  rA  
parse_exprrq   )r4   r:  r;  	saved_posexprs        r+   rN  zParser.parse_allP  s     	"Y^^C22Fzzy!,H4>))FDIdh.?$@AAAAA!A:oo'''''' S H	!A:((9TX&#--HHMHH	$(V2C(DEEEEEJJJJ(DHFDIdh!.C$DEEEEE!A:s??HHMHH7	": 8c$)nn$$	$(** 56666666 %$r*   c                     t                               | j        | j                  }|t	          | j        | j                  ||                                fS r/   )r-  r.  r2   r3   r-   r/  )r4   r.  s     r+   r.  zParser.matchq  sE    	4844=TY111eiikk!!r*   c                     |o	|d         dv S )Nr   z0123456789"'r)   rO  s     r+   
is_literalzParser.is_literalw  s    2Q?22r*   c                    |                                  \  }}|                     |                                          r#t          d|                                          }n"t          d| j        | j        |                   }|| _        | j        t          | j                  k     rF| j        | j                 dk    r| j        dz   t          | j                  k     rp| j        | j        dz            | j        v rT| xj        dz  c_        |                                  \  }}|                                }t          d||          }|| _        n| j        | j                 dk    rk| j        }| xj        dz  c_        |                                 }| j        | j                 dk    r"| xj        dz  c_        t          d||          }n	|| _        nn| j        t          | j                  k     F|S )	NliteralparamrI  r   rP  []getitem)	r.  rV  r  rA  r2   r3   rq   r8  rQ  )r4   r.  r3   rS  attrrR  ru  s          r+   rQ  zParser.parse_exprz  s   ZZ\\
s??5;;==)) 	=EKKMM22DD$)DHsN";<<DhTY''	$(#s**HqL3ty>>11Idhl+t~==A!ZZ\\
s{{}}Yd3348$++ H	Aoo''9TX&#--HHMHH D#66DD(DH- hTY''. r*   N)r%   r&   r'   r(   r8  r1   rK  r
   rN  r.  rV  rQ  r)   r*   r+   rI  rI  :  s         
 UI    
     7 7 7B" " "3 3 3    r*   rI  c                   $    e Zd ZdZd Zd Zd ZdS )r   z0Safe evaluator for binding params to db queries.c                      t                                          |          }t                               fd|D             d          S )Nc                 <    g | ]}                     |          S r)   )	eval_node)r~   nodemappingr4   s     r+   r   z%SafeEval.safeeval.<locals>.<listcomp>  s'    NNNdnnT7;;NNNr*   rw   )rI  r
   r   ry   )r4   r2   rc  nodess   ` ` r+   r   zSafeEval.safeeval  sF    t$$}}NNNNNNNNPRSSSr*   c                 l    |j         dk    r|j        S t          |                     ||                    S )Nr2   )rD  r   r   	eval_exprr4   rb  rc  s      r+   ra  zSafeEval.eval_node  s3    9:DNN499:::r*   c                 z   |j         dk    rt          j        |j                  S |j         dk    r.t	          |                     |j        |          |j                  S |j         dk    r:|                     |j        |          |                     |j        |                   S |j         dk    r||j                 S d S )NrX  rP  r\  rY  )rD  astliteral_evalr   rP  rf  rE  rg  s      r+   rf  zSafeEval.eval_expr  s    9	!!#DJ///Y)##4>>$*g>>LLLY)##>>$*g66t{G44  Y'!!4:&& "!r*   N)r%   r&   r'   r(   r   ra  rf  r)   r*   r+   r   r     sJ        ::T T T; ; ;
' 
' 
' 
' 
'r*   r   c                  H   d }  | dt          dd          g            | dt          dd          t          dd          g            | dt          dd          t          d	t          dd          d
          g            | dt          dd          t          d	t          ddd           d          t          dd          g            | dt          dd          t          dt          ddd           t          dd                    t          dd          g           d S )Nc                     t                      }t          |                    |                     }t          t	          |           |           ||k    sJ d|z              d S )NzExpected %r)rI  ra   r
   r_  r6   )r2   expectedprd  s       r+   fztest_parser.<locals>.f  s\    HHQWWT]]##d4jj%      -(":     r*   Hellor2   zHello $namezHello rY  r'  zHello $name.foorP  foozWHERE id=$self.id LIMIT 1	WHERE id=r4   idz LIMIT 1zWHERE id=$self['id'] LIMIT 1r\  rX  z'id')rA  ro  s    r+   test_parserru    sV   ; ; ; Agfg&&'(((AmeFH--uWf/E/EFGGGA	vx	 	 %	5&3I3I5"Q"QR   A#&+&&)U7FD994@@&*%%	
   A&&+&&)U7FD995F;S;STT&*%%	
    r*   c                      d } t           | dddi          j                    | dddi          j        dt          d          gk    sJ d S )Nc                 F    t                                          | |          S r/   )r   r   )r  rm  s     r+   ro  ztest_safeeval.<locals>.f  s    zz""1d+++r*   zWHERE id=$idrs  r   rr  )r_  r_   r   rt  s    r+   test_safeevalrx    si    , , , 
!!NT1I
&
&
,---1^dAY''-+x{{1KKKKKKKr*   __main__)r   r/   )Lr(   r   r"  rer\  
py3helpersr   utilsr   r   r   r   r	   urllibr
   r  urllib.parser   r4  ri  webapir   r   sysstderr__all__TOKENcompiler-  r  r  r  r  r   r0   r-   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r$  r   r)  r   rA  rI  r   ru  rx  r%   doctesttestmodr)   r*   r+   <module>r     s   
  				 				  ! ! ! ! ! ! E E E E E E E E E E E E E E(((((($$$$$$$   OOOJJJJ   
CCC%%%%%%%%%   JJJJEWYYFFF	  " 	^BJu	 
9:	 	 	 	 		 	 	 	V V V V V V V V	 	 	 	 	y 	 	 		 	 	 	 		 	 	 	+0 +0 +0 +0 +0v +0 +0 +0\ d- d- d- d- d-v d- d- d-N( ( ( ( ( ( ( (" 
  2% % %2  8  $ $ $@O O O O & & &&4% 4% 4% 4% 4% 4% 4% 4%n) ) ) ) ) ) ) )    m   <FT FT FT FT FT FT FT FTRT% T% T% T% T% T% T% T%n3 3 3 3 3 3 3 3l$4 $4 $4 $4 $4b $4 $4 $4N
B 
B 
B 
B' ' ' ' 'r ' ' ': 
  
  
  
  
  
  
  
F* * * * *b * * *ZE E E E Er E E E2
 
 
D 
   &    '7 # # #  *j ) ) )  (H % % %  *j ) ) )  '7 # # #  (H % % %C C CLI I I I IF I I I$^ ^ ^ ^ ^ ^ ^ ^B' ' ' ' 'v ' ' '4  @L L L zNNNGOKMMMMOOOOO s3   5 AAA AAA' 'BB