
    j6                        d dl Z d dlZd dlmZmZ d dlmZmZ d dlm	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 d d	lmZ d d
l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#m$Z$m%Z%  e j&        e'          Z( G d d          Z)dS )    N)AnyLiteral)parse_qsurlparse)MigrationContext)
Operations)
ConnectionEnginecreate_engineeventinspect)	Inspector)MetaData)text)
Executable)Table)
ColumnTypeTypes)
QUERY_STEP
ResultIter
RowFactorynormalize_table_namerow_factorysafe_urlc                      e Zd ZdZdddeddfdededz  deeef         dz  dede	d	ed
e
e         dz  ddfdZedefd            Zedefd            Zedefd            ZdedefdZedefd            Zedefd            Zd1dZd1dZd1dZd1dZd1dZd1dZd2dZdedededdfdZd1dZ ede
e         fd             Z!ede
e         fd!            Z"d"edefd#Z#	 	 	 d3d"ed$ee$d%         z  dz  d&e%dz  d'edz  de&f
d(Z'd"ede&fd)Z(	 	 	 d3d"ed$ee$d%         z  dz  d&e%dz  d'edz  de&f
d*Z)d"ede&fd+Z*de
e         fd,Z+d-ee,z  d.ede-fd/Z.defd0Z/dS )4DatabasezAA database object represents a SQL database with multiple tables.NTurlschemaengine_kwargsensure_schemarow_typesqlite_wal_modeon_connect_statementsreturnc                    |i }t          |          }t          j                    | _        t          j                    | _        i | _        t          |j                  rct          |j                  }	|M|		                    d|		                    dg                     }
t          |
          r|

                                }|| _        t          |fi || _        | j        J | j        j        j        dk    | _        | j        j        j        dk    | _        d| j        j        j        v | _        g dt&          dt&          d	dffd
}| j        r"|j        dk    r|r                    d           t                    rt-          j        | j        d|           t1          | j                  | _        || _        || _        || _        i | _        dS )z&Configure and connect to the database.Nr   
searchpath
postgresqlsqlitemysql	dbapi_con
con_recordr$   c                 <    D ]}|                      |           d S )N)execute)r*   r+   	statementr#   s      W/home/ubuntu/.hermes/hermes-agent/venv/lib/python3.11/site-packages/dataset/database.py_run_on_connectz*Database.__init__.<locals>._run_on_connectG   s5     3 - -	!!),,,,- -     zPRAGMA journal_mode=WALconnect)is_postgres)r   	threadingRLocklocklocalconnectionslenqueryr   getpopr   r   enginedialectnamer4   	is_sqliteis_mysqlr   pathappendr   listenr   typesr   r!   r    _tables)selfr   r   r   r    r!   r"   r#   
parsed_urlr;   	schema_qsr0   s          `    r/   __init__zDatabase.__init__   s     Mc]]
 O%%	_&&
24z   	-Z-..E~!IIh		,0K0KLL	y>> -&]]__F%23%H%H-%H%H{&&&;.3|C,1X=4;#6#;; ($&!	-s 	- 	- 	- 	- 	- 	- 	- 	- > 	Djo333!(()BCCC$%% 	BLiAAAt'7888
$,*)+r1   c                    | j         5  t          j                    }|| j        vr7| j        t          d          | j                                        | j        |<   | j        |         cddd           S # 1 swxY w Y   dS )z5Connection against which statements will be executed.NzDatabase is closed)r7   r5   	get_identr9   r>   RuntimeErrorr3   )rH   tids     r/   
executablezDatabase.executable[   s     Y 	) 	)%''C$***;&&';<<<(,(;(;(=(= %#C(	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)s   A A55A9<A9c                 R    t          j        | j                  }t          |          S )z"Get an alembic operations context.)r   	configurerP   r   )rH   ctxs     r/   opzDatabase.opf   s"     (99#r1   c                 *    t          | j                  S )zGet a SQLAlchemy inspector.)r   rP   rH   s    r/   r   zDatabase.inspectl   s     t'''r1   r@   c                 D    | j                             || j                  S )Nr   )r   	has_tabler   )rH   r@   s     r/   rY   zDatabase.has_tableq   s    |%%d4;%???r1   c                 ,    t          | j                  S )z(Return a SQLAlchemy schema cache object.rX   )r   r   rV   s    r/   metadatazDatabase.metadatat   s     t{++++r1   c                 j    t          | j        d          sdS t          | j        j                  dk    S )z5Check if this database is in a transactional context.txFr   )hasattrr8   r:   r]   rV   s    r/   in_transactionzDatabase.in_transactiony   s4     tz4(( 	54:=!!A%%r1   c                     | j         5  t          j                    }| j                            |d          }||                                 ddd           dS # 1 swxY w Y   dS )zCClose and release the current thread's connection back to the pool.N)r7   r5   rM   r9   r=   close)rH   rO   conns      r/   _release_connectionzDatabase._release_connection   s    Y 	 	%''C#''T22D

		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   AAA!Ac                 L    | j                                         D ]	}d|_        
dS )z5Clear the table metadata after transaction rollbacks.N)rG   values_table)rH   tables     r/   _flush_tableszDatabase._flush_tables   s2    \((** 	  	 EELL	  	 r1   c                 J    | j         s| j                                         dS dS )aQ  Commit pending changes when not in an explicit transaction.

        In SQLAlchemy 2.x, connections use "autobegin" which starts a
        transaction on first use. This method commits that transaction
        after each write operation when the user has not started an
        explicit transaction via ``begin()``/``with db:``.
        N)r_   rP   commitrV   s    r/   _auto_commitzDatabase._auto_commit   s3     " 	%O""$$$$$	% 	%r1   c                 (   t          | j        d          sg | j        _        | j                                        s8| j        j                            | j                                                   dS | j        j                            d           dS )zsEnter a transaction explicitly.

        No data will be written until the transaction has been committed.
        r]   TN)r^   r8   r]   rP   r_   rD   beginrV   s    r/   rm   zDatabase.begin   s    
 tz4(( 	DJM--// 	'JM  !6!6!8!899999 JM  &&&&&r1   c                 4   t          | j        d          r~| j        j        rt| j        j                                        }| j        j        sL|dur|                                 n| j                                         |                                  dS dS dS dS )zyCommit the current transaction.

        Make all statements executed since the transaction was begun permanent.
        r]   TN)r^   r8   r]   r=   rj   rP   rc   rH   r]   s     r/   rj   zDatabase.commit   s    
 4:t$$ 	+ 	+""$$B:= +T>>IIKKKKO**,,,((*****	+ 	+ 	+ 	++ +r1   c                 X   t          | j        d          r| j        j        r| j        j                                        }| j        j        sF|dur|                                 n| j                                         |                                  |                                  dS dS dS )zuRoll back the current transaction.

        Discard all statements executed since the transaction was begun.
        r]   TN)r^   r8   r]   r=   rollbackrP   rc   rh   ro   s     r/   rq   zDatabase.rollback   s    
 4:t$$ 	! 	!""$$B:= +T>>KKMMMMO,,...((***     	! 	! 	! 	!r1   c                 .    |                                   | S )zStart a transaction.)rm   rV   s    r/   	__enter__zDatabase.__enter__   s    

r1   
error_typeerror_value	tracebackc                     |:	 |                                   dS # t          $ r |                                   w xY w|                                  dS )z0End a transaction by committing or rolling back.N)rj   	Exceptionrq   )rH   rt   ru   rv   s       r/   __exit__zDatabase.__exit__   s^         MMOOOOOs     :c                 2   | j         5  | j                                        D ]}|                                 | j                                         ddd           n# 1 swxY w Y   | j        | j                                         i | _        d| _        dS )a  Close all database connections and dispose of the engine.

        Releases all pooled connections and makes this object unusable.
        This should be called when the database is no longer needed,
        especially in multi-threaded or connection-pooled setups.
        N)r7   r9   re   ra   clearr>   disposerG   )rH   rb   s     r/   ra   zDatabase.close   s     Y 	% 	%(//11  

""$$$	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% ;"K!!!s   A
AA"%A"c                 B    | j                             | j                  S )z7Get a listing of all tables that exist in the database.rX   )r   get_table_namesr   rV   s    r/   tableszDatabase.tables   s     |++4;+???r1   c                 B    | j                             | j                  S )z6Get a listing of all views that exist in the database.rX   )r   get_view_namesr   rV   s    r/   viewszDatabase.views   s     |**$+*>>>r1   
table_namec                 l    	 t          |          }|| j        v rdS || j        v S # t          $ r Y dS w xY w)z5Check if the given table name exists in the database.TF)r   r   r   
ValueErrorrH   r   s     r/   __contains__zDatabase.__contains__   sU    	-j99JT[((t++ 	 	 	55	s   % % 
33
primary_idFprimary_typeprimary_incrementc           	         t          |t                    r
J d            t          |          }| j        5  || j        vrt          | ||||d          | j        |<   | j        |         cddd           S # 1 swxY w Y   dS )a&  Create a new table.

        Either loads a table or creates it if it doesn't exist yet. You can
        define the name and type of the primary key field, if a new table is to
        be created. The default is to create an auto-incrementing integer,
        ``id``. You can also set the primary key to be a string or big integer.
        The caller will be responsible for the uniqueness of ``primary_id`` if
        it is defined as a text type. You can disable auto-increment behaviour
        for numeric primary keys by setting `primary_increment` to `False`.

        Returns a :py:class:`Table <dataset.Table>` instance.
        ::

            table = db.create_table('population')

            # custom id and type
            table2 = db.create_table('population2', 'age')
            table3 = db.create_table('population3',
                                     primary_id='city',
                                     primary_type=db.types.text)
            # custom length of String
            table4 = db.create_table('population4',
                                     primary_id='city',
                                     primary_type=db.types.string(25))
            # no primary key
            table5 = db.create_table('population5',
                                     primary_id=False)
        z9Text-based primary_type support is dropped, use db.types.T)r   r   r   auto_createN)
isinstancestrr   r7   rG   r   rH   r   r   r   r   s        r/   create_tablezDatabase.create_table   s    F lC00 	
 	
G	
 	
0 **55
Y 
	, 
	,--+0)!-&7 $, , ,Z( <
+
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	, 
	,s   3A66A:=A:c                     t          |          }| j        5  || j        vrt          | |          | j        |<   | j        |         cddd           S # 1 swxY w Y   dS )ae  Load a table.

        This will fail if the tables does not already exist in the database. If
        the table exists, its columns will be reflected and are available on
        the :py:class:`Table <dataset.Table>` object.

        Returns a :py:class:`Table <dataset.Table>` instance.
        ::

            table = db.load_table('population')
        N)r   r7   rG   r   r   s     r/   
load_tablezDatabase.load_table-  s     **55
Y 	, 	,--+0z+B+BZ(<
+	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	,s   .AAAc                 j    | j         s|                     |          S |                     ||||          S )zLoad or create a table.

        This is now the same as ``create_table``.
        ::

            table = db.get_table('population')
            # you can also use the short-hand syntax:
            table = db['population']
        )r    r   r   r   s        r/   	get_tablezDatabase.get_table?  sC      ! 	/??:...  
L2C
 
 	
r1   c                 ,    |                      |          S )zGet a given table.)r   r   s     r/   __getitem__zDatabase.__getitem__U  s    ~~j)))r1   c                     | j         S )z(Completion for table names with IPython.)r   rV   s    r/   _ipython_key_completions_z"Database._ipython_key_completions_Y  s
    {r1   r;   kwargsc                 6   t          |t                    rt          |          }|                    dt                    }|du s|dk    rd}|r| j                            ||          }n| j                            |          }t          || j        |          S )aa  Run a statement on the database directly.

        Allows for the execution of arbitrary read/write queries. A query can
        either be a plain text string, or a `SQLAlchemy expression
        <https://docs.sqlalchemy.org/en/21/tutorial/data_select.html#tutorial-selecting-data>`_.
        If a plain string is passed in, it will be converted to an expression
        automatically.

        Keyword arguments will be used for parameter binding. Use a named bind
        parameter in the query (i.e. ``SELECT * FROM tbl WHERE a = :foo``) and
        pass the value as a keyword argument (i.e. ``foo='bar'``).
        ::

            statement = 'SELECT user, COUNT(*) c FROM photos GROUP BY user'
            for row in db.query(statement):
                print(row['user'], row['c'])

        The returned iterator will yield each result sequentially.
        _stepFr   N)r!   step)	r   r   r   r=   r   rP   r-   r   r!   )rH   r;   r   r   rps        r/   r;   zDatabase.query]  s    ( eS!! 	 KKE

7J//E>>UaZZE 	0((77BB((//B"t}5AAAAr1   c                 2    dt          | j                   dS )z%Text representation contains the URL.z
<Database(z)>)r   r   rV   s    r/   __repr__zDatabase.__repr__|  s    2HTX..2222r1   )r$   N)r$   r   )NNN)0__name__
__module____qualname____doc__r   r   dictr   boolr   listrK   propertyr	   rP   r   rT   r   r   rY   r   r[   r_   rc   rh   rk   rm   rj   rq   rs   objectry   ra   r   r   r   r   r   r   r   r   r   r   r   r   r   r;   r    r1   r/   r   r      sv       KK
 "/3"* $26:, :,:, d
:, CH~,	:,
 :, :, :,  $Cy4/:, 
:, :, :, :,x )J ) ) ) X) J    X
 ( ( ( ( X(@c @d @ @ @ @ ,( , , , X, & & & & X&          
	% 	% 	% 	%' ' ' '+ + + +! ! ! !   
 /5BH	        @S	 @ @ @ X@ ?tCy ? ? ? X?s t     37*.)-1, 1,1, '%.(4/1, !4'	1,
  $;1, 
1, 1, 1, 1,f,S ,U , , , ,* 37*.)-
 

 '%.(4/
 !4'	

  $;
 

 
 
 
,*c *e * * * *49    B3+ Bs Bz B B B B>3# 3 3 3 3 3 3r1   r   )*loggingr5   typingr   r   urllib.parser   r   alembic.migrationr   alembic.operationsr   
sqlalchemyr	   r
   r   r   r   sqlalchemy.engine.reflectionr   sqlalchemy.schemar   sqlalchemy.sqlr   sqlalchemy.sql.expressionr   dataset.tabler   dataset.typesr   r   dataset.utilr   r   r   r   r   r   	getLoggerr   logr   r   r1   r/   <module>r      s                + + + + + + + + . . . . . . ) ) ) ) ) ) H H H H H H H H H H H H H H 2 2 2 2 2 2 & & & & & &       0 0 0 0 0 0       + + + + + + + +                g!!b3 b3 b3 b3 b3 b3 b3 b3 b3 b3r1   