
    j                     D   d dl Z d dlZd dlZd dlmZmZ d dlmZmZm	Z	 d dl
mZmZmZ d dlmZ d dlmZmZ d dlmZ d dlmZmZ d d	lmZmZmZmZ d d
lmZmZm Z  d dl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ erd dl0m1Z1  e j2        e3          Z4 G d d          ZdS )    N)IterableSequence)TYPE_CHECKINGAnyLiteral)falsefuncselect)NoSuchTableError)ColumnIndex)Table)and_
expression)ClauseElementColumnElementUnaryExpression	bindparam)MYSQL_LENGTH_TYPES
ColumnTypeTypes)
QUERY_STEPDatasetError
MutableRowOutRow
QueryError
ResultIterSQLWriteValueWriteRowensure_strings
index_namenormalize_column_keynormalize_column_namenormalize_table_namepad_chunk_columns)Databasec                   X   e Zd ZdZdZ	 	 	 	 dOdddedeed         z  dz  d	edz  d
edz  defdZ	e
defd            Ze
defd            Ze
deeef         fd            Ze
dee         fd            Zdedz  defdZdedefdZ	 	 dPdededz  deeef         dz  defdZ	 	 dPdedee         dedz  deeef         dz  def
dZ	 	 	 dQdee         dededz  deeef         dz  ddf
dZ	 	 	 dRdedee         dedz  deeef         dz  d edeez  fd!Z	 	 	 dQdee         dee         dededz  deeef         dz  ddfd"Z	 	 dPdedee         dedz  deeef         dz  def
d#Z	 	 	 dQdee         dee         dededz  deeef         dz  ddfd$Zd%ee         d&e defd'Z!dSd(Z"dSd)Z#d*ee$e                  ddfd+Z%	 dTdededz  deeef         dz  de&fd,Z'dedz  defd-Z(ded.ed/e dee         fd0Z)	 dUd2e&d%e*ee                  dee         fd3Z+d4eee         z  dz  dee,e                  fd5Z-dedee         de.e&e&f         fd6Z/ded7ed8e0ddfd9Z1ded/e ddfd:Z2deddfd;Z3dSd<Z4d*e*e         defd=Z5	 dTd*ee         dedz  d>e0ddfd?Z6dd@dde7dAdBee         dCedz  dDed4eee         z  dz  dEedFedz  d8e de8fdGZ9d2ee         d8e de:dz  fdHZ;dBee         d8e defdIZ<defdJZ=dd@dKd2eee         z  dCedz  dDedz  d8e de8f
dLZ>e9Z?de8fdMZ@defdNZAdS )Vr   z?Represents a table in a database and exposes common operations.idNFdatabaser&   
table_name
primary_idprimary_typeprimary_incrementauto_createc                    || _         t          |          | _        d| _        d| _        g | _        ||n| j        | _        ||nt          j	        | _
        || j
        t          j	        t          j        fv }|| _        || _        dS )z*Initialise the table from database schema.N)dbr$   name_table_columns_indexesPRIMARY_DEFAULT_primary_idr   integer_primary_typebigint_primary_increment_auto_create)selfr)   r*   r+   r,   r-   r.   s          T/home/ubuntu/.hermes/hermes-agent/venv/lib/python3.11/site-packages/dataset/table.py__init__zTable.__init__0   s     (44	(,/3(*$0JJd6J 	 )4LL%- 	 $ $ 2u}el6S S"3'    returnc                 0    | j         dS | j        | j        v S )z;Check to see if the table currently exists in the database.NT)r2   r1   r0   r<   s    r=   existszTable.existsJ   s      ;"4yDG##r?   c                 j    | j         |                     d           | j         
J d            | j         S )zGet a reference to the table, which may be reflected or created.

        This property guarantees to return a non-None SQLATable instance.
        If the table doesn't exist and auto_create is False, raises DatasetError.
        N z'_sync_table should ensure _table is set)r2   _sync_tablerB   s    r=   tablezTable.tableQ   s?     ;R   {&&(Q&&&{r?   c                    | j         si S | j        j        5  | j        | j        }i | _        |j        D ]q}t          |j                  }t          |          }|| j        v rt          
                    d|           |t          
                    d|           g|| j        |<   r| j        cddd           S # 1 swxY w Y   dS )z7Get a dictionary of all columns and their case mapping.NzDuplicate column: %szInvalid column name: %s)rC   r0   lockr3   rG   columnsr#   r1   r"   logwarning)r<   rG   columnr1   keys        r=   _column_keyszTable._column_keys]   s    { 	IW\ 	! 	!}$
 "#m . .F0==D.t44Cdm++$:DAAA{$=tDDD )-DM#&&=	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	!s   BB88B<?B<c                 N    t          | j                                                  S )z5Get a listing of all columns that exist in the table.)listrO   valuesrB   s    r=   rJ   zTable.columnsr   s!     D%,,..///r?   rM   c                 T    |dS t          t          |                    }|| j        v S )z;Check if a column with the given name exists on this table.NF)r"   r#   rO   )r<   rM   rN   s      r=   
has_columnzTable.has_columnw   s0    >5"#8#@#@AAd'''r?   r1   c                 |    t          |          }t          |          }||S | j                            ||          S )z9Find the best column name with case-insensitive matching.)r#   r"   rO   get)r<   r1   rN   s      r=   _get_column_namezTable._get_column_name~   s?    $T**"4((;K $$S$///r?   rowensuretypesc                 R   |                      |||          }| j        j                            | j                                                            |                    }| j                                         |j        %t          |j                  dk    r|j        d         S dS )ab  Add a ``row`` dict by inserting it into the table.

        If ``ensure`` is set, any of the keys of the row are not
        table columns, they will be created automatically.

        During column creation, ``types`` will be checked for a key
        matching the name of a column to be created, and the given
        SQLAlchemy column type will be used. Otherwise, the type is
        guessed from the row value, defaulting to a simple unicode
        field.
        ::

            data = dict(title='I am a banana!')
            table.insert(data)

        Returns the inserted row's primary key.
        rZ   Nr   T)
_sync_columnsr0   
executableexecuterG   insertrR   _auto_commitinserted_primary_keylen)r<   rX   rY   rZ   ress        r=   r`   zTable.insert   s    .   fE ::g (():):)<)<)C)CC)H)HII#/C8P4Q4QTU4U4U+A..tr?   keysc                    |                      |||          }|                     |          r|                     |           |                     ||          \  }} | j        di |dk    r|                     |d          S dS )a  Add a ``row`` dict into the table if the row does not exist.

        If rows with matching ``keys`` exist no change is made.

        Setting ``ensure`` results in automatically creating missing columns,
        i.e., keys of the row are not table columns.

        During column creation, ``types`` will be checked for a key
        matching the name of a column to be created, and the given
        SQLAlchemy column type will be used. Otherwise, the type is
        guessed from the row value, defaulting to a simple unicode
        field.
        ::

            data = dict(id=10, title='I am a banana!')
            table.insert_ignore(data, ['id'])
        r\   r   FrY   rE   )r]   _check_ensurecreate_index_keys_to_argscountr`   )r<   rX   re   rY   rZ   args_s          r=   insert_ignorezTable.insert_ignore   s    0   fE ::f%% 	$d###$$S$//a4:"";;s5;111ur?     rows
chunk_sizec                 p   i }|D ]?}t          |                                          fd|D             D ]}||         ||<   @|                     |||           |                                }g }	t          |          D ]\  }
}|	                    t          |                     t          |	          |k    s|
t          |          dz
  k    rbt          |	|          }	| j        j	        
                    | j                                        |	           | j                                         g }	dS )a  Add many rows at a time.

        This is significantly faster than adding them one by one. Per default
        the rows are processed in chunks of 1000 per commit, unless you specify
        a different ``chunk_size``.

        See :py:meth:`insert() <dataset.Table.insert>` for details on
        the other parameters.
        ::

            rows = [dict(name='Dolly')] * 10000
            table.insert_many(rows)
        c                     g | ]}|v|	S rE   rE   ).0k	sync_keyss     r=   
<listcomp>z%Table.insert_many.<locals>.<listcomp>   s#    ===a!9*<*<*<*<*<r?   r\      N)rQ   re   r]   	enumerateappenddictrc   r%   r0   r^   r_   rG   r`   ra   )r<   rp   rq   rY   rZ   sync_rowrX   rN   rJ   chunkindexrv   s              @r=   insert_manyzTable.insert_many   sJ   *  " 	) 	)CX]]__--I====3=== ) ) #C) 	8V5999 --//"$#D// 	 	JE3LLc### 5zzZ''5CIIM+A+A)%99"**4:+<+<+>+>FFF$$&&&	 	r?   return_countc                 ,   |                      |||          }|                     ||          \  }}|                     |          }t          |          s|                     |          S | j                                                            |                              |          }| j	        j
                            |          }	| j	                                         |	                                r|	j        S |r|                     |          S dS )a  Update a row in the table.

        The update is managed via the set of column names stated in ``keys``:
        they will be used as filters for the data to be updated, using the
        values in ``row``.
        ::

            # update all entries with id matching 10, setting their title
            # columns
            data = dict(id=10, title='I am a banana!')
            table.update(data, ['id'])

        If keys in ``row`` update columns not present in the table, they will
        be created based on the settings of ``ensure`` and ``types``, matching
        the behavior of :py:meth:`insert() <dataset.Table.insert>`.
        r\   F)r]   rj   _args_to_clauserc   rk   rG   updatewhererR   r0   r^   r_   ra   supports_sane_rowcountrowcount)
r<   rX   re   rY   rZ   r   rl   clausestmtrps
             r=   r   zTable.update   s    0   fE ::&&sD11	c%%d++3xx 	&::f%%%z  ""((0077<<W''--$$&& 	; 	&::f%%%ur?   c                     t                    g }g t          |          D ]:\  }}                    fd|D                        t          |          }	D ]%}
|	|
         |	d|
 <   |	                    |
           &|                    |	           t          |          |k    s|t          |          dz
  k    r fdD             } j                                        	                    t          dg|R                                d D                       } j        j                            ||            j                                         g }<dS )a[  Update many rows in the table at a time.

        This is significantly faster than updating them one by one. Per default
        the rows are processed in chunks of 1000 per commit, unless you specify
        a different ``chunk_size``.

        See :py:meth:`update() <dataset.Table.update>` for details on
        the other parameters.
        c              3   ,   K   | ]}|v|v
|V  d S NrE   )rt   colrJ   re   s     r=   	<genexpr>z$Table.update_many.<locals>.<genexpr>,  s:        s''9'94 r?   rm   rx   c                 \    g | ](}j         j        |         t          d |           k    )S )rm   )rG   cr   rt   ru   r<   s     r=   rw   z%Table.update_many.<locals>.<listcomp>9  s4    JJJdjl1o7q77););;JJJr?   Tc                 2    i | ]}|t          |d           S )F)required)r   )rt   r   s     r=   
<dictcomp>z%Table.update_many.<locals>.<dictcomp>=  s'    TTTSS)C%"@"@"@TTTr?   N)r    ry   extendr{   poprz   rc   rG   r   r   r   rR   r0   r^   r_   ra   )r<   rp   re   rq   rY   rZ   r}   r~   rX   row_rN   clr   rJ   s   ` `          @r=   update_manyzTable.update_many  s   " d##"$#D// 	 	JE3NN     "     
 99D  "&s)YYYLL 5zzZ''5CIIM+A+AJJJJTJJJJ%%''U4?r???++VTTGTTTUU 
 "**4777$$&&&-	 	r?   c                     |                      |||          }|                     |          r|                     |           |                     ||dd          }|dk    r|                     |d          S dS )a#  An UPSERT is a smart combination of insert and update.

        If rows with matching ``keys`` exist they will be updated, otherwise a
        new row is inserted in the table.
        ::

            data = dict(id=10, title='I am a banana!')
            table.upsert(data, ['id'])
        r\   FT)rY   r   r   rg   )r]   rh   ri   r   r`   )r<   rX   re   rY   rZ   	row_counts         r=   upsertzTable.upsertC  s        fE ::f%% 	$d###KKT%dKKK	>>;;s5;111tr?   c                 B    |D ]}|                      ||||           dS )z
        Sorts multiple input rows into upserts and inserts. Inserts are passed
        to insert and upserts are updated.

        See :py:meth:`upsert() <dataset.Table.upsert>` and
        :py:meth:`insert_many() <dataset.Table.insert_many>`.
        )rY   rZ   N)r   )r<   rp   re   rq   rY   rZ   rX   s          r=   upsert_manyzTable.upsert_many[  s:    "  	? 	?CKKT&K>>>>	? 	?r?   clausesfiltersc                     | j         sdS |                     ||          }| j                                                            |          }| j        j                            |          }| j                                         |j	        dk    S )a  Delete rows from the table.

        Keyword arguments can be used to add column-based filters. The filter
        criterion will always be equality:
        ::

            table.delete(place='Berlin')

        If no arguments are given, all records are deleted.
        Fr   r   )
rC   r   rG   deleter   r0   r^   r_   ra   r   )r<   r   r   r   r   r   s         r=   r   zTable.deleteo  s     { 	5%%gw%??z  ""((00W''--{Qr?   c                    | j         j        5  d| _        	 t          | j        | j         j        | j         j        | j         j                  | _        n# t          $ r
 d| _        Y nw xY wddd           dS # 1 swxY w Y   dS )z-Load the tables definition from the database.N)schemaautoload_with)
r0   rI   r3   	SQLATabler1   metadatar   r^   r2   r   rB   s    r=   _reflect_tablezTable._reflect_table  s    W\ 
	# 
	# DM#'IG$7>"&'"4	   $ # # #"#
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	# 
	#s4   A6;AA6A&#A6%A&&A66A:=A:c                     | j         j        r5t          j                    dk    r t	          j        dt          d           d S d S d S )Nrx   zChanging the database schema inside a transaction in a multi-threaded environment is likely to lead to race conditions and synchronization issues.   )
stacklevel)r0   in_transaction	threadingactive_countwarningswarnRuntimeWarningrB   s    r=   _threading_warnzTable._threading_warn  sc    7! 	i&<&>&>&B&BMA      	 	&B&Br?   rJ   c                    | j         |                                  | j         C| j        st          d| j                   | j        j        5  |                                  t          | j        | j        j	        | j        j
                  | _         | j        dur<t          | j        | j        d| j                  }| j                             |           |D ],}|j        | j        k    r| j                             |           -| j                             | j        j        d           d| _        | j                                         ddd           dS # 1 swxY w Y   dS t)          |          r| j        j        5  |                                  |                                  |D ]M}|                     |j                  s1| j        j                            | j        || j        j
                   N|                                  | j                                         ddd           dS # 1 swxY w Y   dS dS )a  Lazy load, create or adapt the table structure in the database.

        This method guarantees that self._table will be set to a non-None value
        after successful execution. If the table cannot be created or loaded,
        it raises DatasetError.
        NzTable does not exist: r   FT)primary_keyautoincrement
checkfirst)r2   r   r;   r   r1   r0   rI   r   r   r   r   r6   r   r8   r:   append_columncreater^   r3   ra   rc   rT   op
add_column)r<   rJ   rM   s      r=   rF   zTable._sync_table  s    ;!!!;$ I"#GDI#G#GHHH ' '$$&&&'Itw/   #500 $(*$(&*&=	  F K--f555% : :F{d&66611&999""47#5$"GGG $$$&&&)' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '* \\ 	' ' '##%%%$$&&&% X XF??6;77 X
--di-WWW##%%%$$&&&' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '	' 	's&   C?EE!EB&H55H9<H9c                                           |          }|pi } fd|                                D             }i }i }|                                D ]\  }}                     |          }                     |          r|||<   5|rN|                    |          }| j        j                            |          }t          ||          ||<   |||<    	                    t          |                                                     |S )zCreate missing columns (or the table) prior to writes.

        If automatic schema generation is disabled (``ensure`` is ``False``),
        this will remove any keys from the ``row`` for which there is no
        matching column.
        c                 B    i | ]\  }}                     |          |S rE   rW   )rt   ru   vr<   s      r=   r   z'Table._sync_columns.<locals>.<dictcomp>  s-    III!Q&&q))1IIIr?   )rh   itemsrW   rT   rV   r0   rZ   guessr   rF   rQ   rR   )	r<   rX   rY   rZ   outsync_columnsr1   value_types	   `        r=   r]   zTable._sync_columns  s    ##F++IIII5;;==III99;; 		" 		"KD%((..Dt$$ "!D		 "		$= GM//66E%+D%%8%8T"!D	l113344555
r?   c                 "    || j         j        S |S r   )r0   ensure_schema)r<   rY   s     r=   rh   zTable._check_ensure  s    >7((r?   r   r   c                 \   |dv r%| j         j        |                             |          S |dv r%| j         j        |                             |          S |dv r%| j         j        |                             |          S |dv r%| j         j        |                             |          S |dv r| j         j        |         |k    S |dv r| j         j        |         |k     S |dv r| j         j        |         |k    S |dv r| j         j        |         |k    S |d	v r| j         j        |         |k    S |d
v r| j         j        |         |k    S |dv rft          |t          t          t          f          st          dt          |                     | j         j        |                             |          S |dv rft          |t          t          t          f          st          dt          |                     | j         j        |                             |          S |dv rit          |t          t          f          rt          |          dk    rt          d          |\  }}| j         j        |                             ||          S |dv rKt          |t                     st          d          | j         j        |                             |d          S |dv rKt          |t                     st          d          | j         j        |                             |d          S t'                      S )N)like)ilike)notlike)notilike)>gt)<lt)z>=gte)z<=lte)=z==is)z!=z<>not)inz!'in' filter requires a list, got )notinz$'notin' filter requires a list, got )betweenz..r   z.'between' filter requires a list of two values)
startswithz%'startswith' filter requires a stringT)
autoescape)endswithz#'endswith' filter requires a string)rG   r   r   r   r   r   
isinstancerQ   tuplesetr   typein_notin_rc   r   strr   r   r   )r<   rM   r   r   startends         r=   _generate_clausezTable._generate_clause  s)    ??:<',,U333:<'--e444:<'//666:<'00777:<'%//:<'%//:<'500:<'500""":<'500$$$:<'500==edE3%788 T !RT%[[!R!RSSS:<'++E222edE3%788 W !UU!U!UVVV:<'..u555"""edE]33 Ss5zzQ !QRRRJE3:<'//s;;;  eS)) J !HIII:<'225T2JJJeS)) H !FGGG:<'0040HHHwwr?   rE   rl   c           	         t          |          }|                                D ]#\  }}|                     |          }|                     |          s"|                    t                                 Rt          |t           t          t          f          r+|                    | 	                    |d|                     t          |t                    rE|                                D ]/\  }}|                    | 	                    |||                     0|                    | 	                    |d|                     %t          dg|R  S )Nr   r   T)rQ   r   rW   rT   rz   r   r   r   r   r   r{   r   )r<   rl   r   rM   r   r   op_values          r=   r   zTable._args_to_clause  sJ   
 w--!ZZ\\ 
	J 
	JMFE**622F??6** Juww''''ED%#566 Jt44VT5IIJJJJE4(( J$)KKMM P PLBNN4#8#8X#N#NOOOOP t44VS%HHIIIID#7####r?   order_byc                    g }t          |          D ]}||                    d          }|                     |          }|                     |          sE|                    d          r8|                    | j        j        |                                                    |                    | j        j        |         	                                           |S )N-)
r    lstriprW   rT   r   rz   rG   r   descasc)r<   r   	orderingsorderingrM   s        r=   _args_to_order_byzTable._args_to_order_by,  s     13	&x00 
	= 
	=H__S))F**622F??6** ""3'' =  f!5!:!:!<!<====  f!5!9!9!;!;<<<<r?   c                 ~      fdt          |          D             }t          |          fd|D             }|fS )Nc                 :    g | ]}                     |          S rE   r   r   s     r=   rw   z'Table._keys_to_args.<locals>.<listcomp>@  s'    GGGQ%%a((GGGr?   c                 >    i | ]}|                     |d           S r   )r   )rt   ru   r   s     r=   r   z'Table._keys_to_args.<locals>.<dictcomp>B  s)    333488At$$333r?   )r    r{   )r<   rX   re   rl   r   s   `   @r=   rj   zTable._keys_to_args=  sV     HGGG.2F2FGGGCyy3333d333Tzr?   r   kwargsc                    |                      |          }|                     |          rt                              d|            dS |                     t          ||fi |f           | j                                         dS )a  Create a new column ``name`` of a specified type.
        ::

            table.create_column('created_at', db.types.datetime)

        `type` corresponds to an SQLAlchemy type as described by
        `dataset.db.Types`. Additional keyword arguments are passed
        to the constructor of `Column`, so that default values, and
        options like `nullable` and `unique` can be set.
        ::

            table.create_column('key', unique=True, nullable=False)
            table.create_column('food', default='banana')
        zColumn exists: N)rW   rT   rK   debugrF   r   r0   ra   )r<   r1   r   r   s       r=   create_columnzTable.create_columnE  s    " $$T**??4   	II...///F&t66v668999r?   c                 p    | j         j                            |          }|                     ||           dS )a  
        Explicitly create a new column ``name`` with a type that is appropriate
        to store the given example ``value``.  The type is guessed in the same
        way as for the insert method with ``ensure=True``.
        ::

            table.create_column_by_example('length', 4.2)

        If a column of the same name already exists, no action is taken, even
        if it is not of the type we would have created.
        N)r0   rZ   r   r   )r<   r1   r   type_s       r=   create_column_by_examplezTable.create_column_by_example]  s7     ##E**4'''''r?   c                 z   | j         j        t          d          | j         j        j        j        dk    rt          d          |                     |          }| j         j        5  | j        r|                     |          s)t          
                    d|           	 ddd           dS |                                  | j         j                            | j        j        || j        j                   |                                  | j                                          ddd           dS # 1 swxY w Y   dS )zd
        Drop the column ``name``.
        ::

            table.drop_column('created_at')

        Nz0Cannot drop columns when no engine is available.sqlitez)SQLite does not support dropping columns.zColumn does not exist: %sr   )r0   engineRuntimeErrordialectr1   rW   rI   rC   rT   rK   r   r   r   drop_columnrG   r   r   ra   )r<   r1   s     r=   r  zTable.drop_columnl  s    7>!QRRR7>!&(22JKKK$$T**W\ 	# 	#; dood&;&; 		5t<<<	# 	# 	# 	# 	# 	# 	# 	#
   """GJ""4:?DAR"SSS!!!G  """	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#s   &9D0,A7D00D47D4c                 j   | j         j        5  | j        r|                                  | j                            | j         j        d           d| _        d| _        | j         j	        
                    | j        d           | j                                          ddd           dS # 1 swxY w Y   dS )zkDrop the table from the database.

        Deletes both the schema and all the contents within it.
        Tr   N)r0   rI   rC   r   rG   dropr^   r2   r3   _tablesr   r1   ra   rB   s    r=   r  z
Table.drop  s    
 W\ 	' 	'{ '$$&&&
 2tDDD" $##DIt444$$&&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   BB((B,/B,c                      j         sdS  fdt          |          D             }| j        v rdS |D ]}                     |          s dS  j        j                             j         j        j                  }|D ]h}|	                    dg           }t          |                    |                    t          |          k    r j                            |            dS i j        j        jd  j        j        j        D             }t          |                    |                    t          |          k    r j                            |           dS dS )z8Check if an index exists to cover the given ``columns``.Fc                 :    h | ]}                     |          S rE   r   rt   r   r<   s     r=   	<setcomp>z"Table.has_index.<locals>.<setcomp>  s'    NNND))!,,NNNr?   Tr   column_namesNc                     g | ]	}|j         
S rE   )r1   rt   r   s     r=   rw   z#Table.has_index.<locals>.<listcomp>  s    IIIQ!&IIIr?   )rC   r    r4   rT   r0   inspectget_indexesr1   r   rV   rc   intersectionrz   rG   r   rJ   )r<   rJ   columns_rM   indexesr~   idx_columns
pk_columnss   `       r=   	has_indexzTable.has_index  sq   { 	5NNNNnW6M6MNNNt}$$4 	 	F??6** uu'/--di-OO 	 	E))NB77K8((5566#h--GG$$X...tt H :!-II$**@*HIIIJ8((4455XFF$$X...tur?   kwc                      fdt          |          D             } j        j        5   j        st	          d          |D ]%}                     |          s ddd           dS &                     |          s                                  |pt           j	        |          } fd|D             }i }|D ]&}t          |j        t                    r
d||j	        <   '||d<   t          |g|R i |}|                     j        j                    j                                         ddd           dS # 1 swxY w Y   dS )zCreate an index to speed up queries on a table.

        If no ``name`` is given a random name is created.
        ::

            table.create_index(['name', 'country'])
        c                 :    g | ]}                     |          S rE   r   r  s     r=   rw   z&Table.create_index.<locals>.<listcomp>  s'    MMM4((++MMMr?   zTable has not been created yet.Nc                 4    g | ]}j         j        |         S rE   )rG   r   r  s     r=   rw   z&Table.create_index.<locals>.<listcomp>  s!    ===DJLO===r?   
   mysql_length)r    r0   rI   rC   r   rT   r  r   r!   r1   r   r   r   r   r   r^   ra   )	r<   rJ   r1   r  rM   r  r  r   idxs	   `        r=   ri   zTable.create_index  s    NMMM^G5L5LMMMW\ 	' 	'; F"#DEEE!  v.. 	' 	' 	' 	' 	' 	' 	' 	'
 >>'** '$$&&&=z$)W======W===  "# 4 4C!#(,>?? 413SX.%1>"D28222r22

47-...$$&&&3	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   1D;'CD;;D?D?r   )_limit_offsetr   	_streamed_step_clausesr  r  r  r  c                   | j         st          d| j        j                  S | j        j        t          d          |du s|dk    rd}|                     |          }|                     ||          }	| j        	                                
                    |	                              |                              |          }
t          |          r
 |
j        | }
d}| j        j        }|r4| j        j                                        }|                    d          }t          |                    |
          | j        j        ||	          S )
a8  Perform a simple search on the table.

        Simply pass keyword arguments as ``filter``.
        ::

            results = table.find(country='France')
            results = table.find(country='France', year=1980)

        Using ``_limit``::

            # just return the first 10 rows
            results = table.find(country='France', _limit=10)

        You can sort the results by single or multiple columns. Append a minus
        sign to the column name for descending order::

            # sort results by a column 'year'
            results = table.find(country='France', order_by='year')
            # return all rows sorted by multiple columns (descending by year)
            results = table.find(order_by=['country', '-year'])

        You can also submit filters based on criteria other than equality,
        see :ref:`advanced_filters` for details.

        To run more complex queries with JOINs, or to perform GROUP BY-style
        aggregation, you can also use :py:meth:`db.query() <dataset.Database.query>`
        to run raw SQL queries instead.
        Nrow_typez/Cannot run queries when no engine is available.Fr   r   T)stream_results)r#  step
connection)rC   r   r0   r#  r   r   r   r   rG   r
   r   limitoffsetrc   r   r^   connectexecution_optionsr_   )r<   r  r  r   r  r  r   r   r   rl   querystream_connconns                r=   findz
Table.find  sQ   L { 	?dTW-=>>>>7>!PQQQE>>UaZZE**844	##FH#==
!!##))$//55f==DDWMMy>> 	/"ENI.Ew! 	F'.0022K000EEDLLW%"	
 
 
 	
r?   c                     | j         sdS  | j        |ddd|}	 |D ]}|c |                                 S 	 |                                 n# |                                 w xY wdS )zGet a single result from the table.

        Works just like :py:meth:`find() <dataset.Table.find>` but returns one
        result, or ``None``.
        ::

            row = table.find_one(country='United States')
        Nrx   )r  r  )rC   r.  close)r<   rl   r   resiterrX   s        r=   find_onezTable.find_one  s     { 	4$)T!4BB6BB	  

MMOOOO MMOOOOGMMOOOOts   A A#c                 t   | j         sdS |                     ||          }t          t          j                                                  |          }|                    | j                  }| j        j	        
                    |          }|                                }|t          |d                   S dS )z5Return the count of results for the given filter set.r   r   )rC   r   r
   r	   rk   r   select_fromrG   r0   r^   r_   fetchoneint)r<   r   r   rl   r+  r   rd   s          r=   rk   zTable.count%  s    
 { 	1##FH#==tz||$$**400!!$*--W''..kkmm?s1v;;qr?   c                 *    |                                  S )z'Return the number of rows in the table.)rk   rB   s    r=   __len__zTable.__len__6  s    zz||r?   )r  r  c                   | j         st          d| j        j                  S g }g }|D ]y}t	          |t
                    r|                    |           -|                     |          st          d|           |                    | j	        j
        |                    z|                     ||          }t          |          st          d| j        j                  S  t          j        |                                                     |                              |                              |          j        d |D              }	| j                            |	          S )a  Return all the unique (distinct) values for the given ``columns``.
        ::

            # returns only one row per year, ignoring the rest
            table.distinct('year')
            # works with multiple columns, too
            table.distinct('year', 'country')
            # you can also combine this with a filter
            table.distinct('year', country='China')
        Nr"  zNo such column: r   c                 6    g | ]}|                                 S rE   )r   r  s     r=   rw   z"Table.distinct.<locals>.<listcomp>b  s     111A111r?   )rC   r   r0   r#  r   r   rz   rT   r   rG   r   r   rc   r   r
   distinctr   r'  r(  r   r+  )
r<   r  r  rl   r   rJ   r   rM   r   qs
             r=   r;  zTable.distinct:  s[   " { 	?dTW-=>>>> 	5 	5F&-00 5v&&&&v.. D&'B&'B'BCCCtz|F34444%%fg%>>7|| 	?dTW-=>>>>Jw'XZZU6]]U6]]VG__111113 	
 w}}Qr?   c                 *    |                                  S )a  Return all rows of the table as simple dictionaries.

        Allows for iterating over all rows in the table without explicitly
        calling :py:meth:`find() <dataset.Table.find>`.
        ::

            for row in table:
                print(row)
        )r.  rB   s    r=   __iter__zTable.__iter__i  s     yy{{r?   c                 "    d| j         j         dS )zGet table representation.z<Table(z)>)rG   r1   rB   s    r=   __repr__zTable.__repr__u  s    ,,,,,r?   )NNNF)NN)ro   NN)NNF)r@   Nr   )rE   )B__name__
__module____qualname____doc__r5   r   r   r   boolr>   propertyrC   r   rG   r{   rO   rQ   rJ   rT   rW   r   r   r`   r   rn   r6  r   r   r   r   r   r   r   r   r   r   r   rF   r   r]   rh   r   r   r   r   r   r   rj   objectr   r   r  r  r  ri   r   r   r.  r   r2  rk   r8  r;  allr>  r@  rE   r?   r=   r   r   +   s>	       IIO 37*.)-!( (( ( '%.(4/	(
 !4'(  $;( ( ( ( (4 $ $ $ $ X$ 	y 	 	 	 X	 !d38n ! ! ! X!( 0c 0 0 0 X0(t ( ( ( ( (0S 0S 0 0 0 0 #.2	  t CO$t+	
 
   D #.2  sm t	
 CO$t+ 
   F ".2* *x * * t	*
 CO$t+* 
* * * *` #.2"$ $$ sm$ t	$
 CO$t+$ $ 
$ $ $ $T ".2+ +x + sm+ 	+
 t+ CO$t++ 
+ + + +b #.2  sm t	
 CO$t+ 
   8 ".2? ?x ? sm? 	?
 t? CO$t+? 
? ? ? ?(}T2 } QU    &# # # #   ,'8F3K#8 ,'T ,' ,' ,' ,'d /3	  t CO$t+	
 
   <D4K D    
,,",+8,	t	, , , ,b 24$ $$ --.$ 
t		$ $ $ $&hsm+d2	oc"	#   "#+C=	z:%	&   )5;	   0(S ( (4 ( ( ( (# # # # # #.' ' ' '# 4    0 :>$' $'}$',/$J$'EK$'	$' $' $' $'R "/3&?
 ?
 ?
 &?
 d
?
 	?

 %,?
 ?
 Tz?
  ?
 
?
 ?
 ?
 ?
B"4(4A	$   ,}T2 m PS    "     "	*  *  * ]4((*  d
*  t	* 
  *  
*  *  *  * Z C
* 
 
 
 
-# - - - - - -r?   r   )5loggingr   r   collections.abcr   r   typingr   r   r   
sqlalchemyr   r	   r
   sqlalchemy.excr   sqlalchemy.schemar   r   r   r   sqlalchemy.sqlr   r   sqlalchemy.sql.expressionr   r   r   r   dataset.typesr   r   r   dataset.utilr   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   dataset.databaser&   	getLoggerrA  rK   rE   r?   r=   <module>rU     s2         . . . . . . . . . . . . . . . . . . * * * * * * * * * * + + + + + + + + + + + + + + 0 0 0 0 0 0 + + + + + + + +            @ ? ? ? ? ? ? ? ? ?                               "  *))))))g!!L- L- L- L- L- L- L- L- L- L-r?   