
    \dA                         d Z ddlmZ ddlmZmZ  G d de          Z G d d          Z G d d	          Z	 G d
 d          Z
d	dgZdS )zg
An asynchronous mapping to U{DB-API
2.0<http://www.python.org/topics/database/DatabaseAPI-2.0.html>}.
    )threads)logreflectc                       e Zd ZdZdS )ConnectionLostzb
    This exception means that a db connection has been lost.  Client code may
    try again.
    N)__name__
__module____qualname____doc__     9lib/python3.11/site-packages/twisted/enterprise/adbapi.pyr   r      s           r   r   c                   0    e Zd ZdZd Zd Zd Zd Zd ZdS )
Connectiona  
    A wrapper for a DB-API connection instance.

    The wrapper passes almost everything to the wrapped connection and so has
    the same API. However, the L{Connection} knows about its pool and also
    handle reconnecting should when the real connection dies.
    c                 J    || _         d | _        |                                  d S N)_pool_connection	reconnect)selfpools     r   __init__zConnection.__init__   s'    
r   c                     d S r   r   r   s    r   closezConnection.close$   s	     	r   c                 6   | j         j        s| j                                         d S 	 | j                                         | j                                        }|                    | j         j                   |                                 | j                                         d S # t          $ r t          j        d d           Y nw xY w| j                             | j                   | j         j        rt          j        d           t                      )NRollback failedzConnection lost.)r   r   r   rollbackcursorexecutegood_sqlr   commitBaseExceptionr   err
disconnectnoisymsgr   )r   curss     r   r   zConnection.rollback.   s   z# 	%%'''F	-%%'''#**,,DLL,---JJLLL##%%%F 	- 	- 	-GD+,,,,,	- 	
d.///: 	(G&'''s   A>B) )C
Cc                     | j         | j                            | j                    | j                                        | _         d S r   )r   r   r%   connectr   s    r   r   zConnection.reconnectD   s@    'J!!$"2333:--//r   c                 ,    t          | j        |          S r   )getattrr   r   names     r   __getattr__zConnection.__getattr__I   s    t'...r   N)	r   r	   r
   r   r   r   r   r   r/   r   r   r   r   r      si           
    ,0 0 0
/ / / / /r   r   c                   4    e Zd ZdZdZd Zd Zd Zd Zd Z	dS )Transactiona  
    A lightweight wrapper for a DB-API 'cursor' object.

    Relays attribute access to the DB cursor. That is, you can call
    C{execute()}, C{fetchall()}, etc., and they will be called on the
    underlying DB-API cursor object. Attributes will also be retrieved from
    there.
    Nc                 J    || _         || _        |                                  d S r   )r   r   reopen)r   r   
connections      r   r   zTransaction.__init__Y   s"    
%r   c                 J    | j         }d | _         |                                 d S r   )_cursorr   )r   r6   s     r   r   zTransaction.close^   s!    ,r   c                    | j         |                                  	 | j                                        | _         d S # t          $ r% | j        j        s t          j        d d           Y nw xY w| j        j	        rt          j
        d           |                                  | j                                        | _         d S )NzCursor creation failedzConnection lost, reconnecting)r6   r   r   r   r#   r   r   r   r$   r&   r'   r   s    r   r3   zTransaction.reopenc   s    <#JJLLL	8+2244DLF 	8 	8 	8:' 8677777		8 : 	5G3444'..00s   = ,A,+A,c                 F    | j                                          d | _        d S r   )r   r   r6   r   s    r   r   zTransaction.reconnectv   s"    ""$$$r   c                 ,    t          | j        |          S r   )r,   r6   r-   s     r   r/   zTransaction.__getattr__z   s    t|T***r   )
r   r	   r
   r   r6   r   r   r3   r   r/   r   r   r   r1   r1   M   sp          G  
  
1 1 1&  + + + + +r   r1   c                       e Zd ZdZd                                ZdZdZdZdZ	dZ
dZdZdZeZeZdZd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$dS )ConnectionPoola  
    Represent a pool of connections to a DB-API 2.0 compliant database.

    @ivar connectionFactory: factory for connections, default to L{Connection}.
    @type connectionFactory: any callable.

    @ivar transactionFactory: factory for transactions, default to
        L{Transaction}.
    @type transactionFactory: any callable

    @ivar shutdownID: L{None} or a handle on the shutdown event trigger which
        will be used to stop the connection pool workers when the reactor
        stops.

    @ivar _reactor: The reactor which will be used to schedule startup and
        shutdown events.
    @type _reactor: L{IReactorCore} provider
    z-min max name noisy openfun reconnect good_sqlF      Nzselect 1c                    || _         t          j        |          | _        t	          | j        dd          dk    rt          j        d           t	          | j        dd          dk     rt          j        d           |                    d	d          }|dd
lm	} || _
        || _        || _        | j        D ]%}d| }||v rt          | |||                    ||= &t          | j        | j                  | _        t!          | j        | j                  | _        i | _        ddlm}m} |j        | _        |                    | j        | j                  | _        | j
                            | j                  | _        dS )a  
        Create a new L{ConnectionPool}.

        Any positional or keyword arguments other than those documented here
        are passed to the DB-API object when connecting. Use these arguments to
        pass database names, usernames, passwords, etc.

        @param dbapiName: an import string to use to obtain a DB-API compatible
            module (e.g. C{'pyPgSQL.PgSQL'})

        @keyword cp_min: the minimum number of connections in pool (default 3)

        @keyword cp_max: the maximum number of connections in pool (default 5)

        @keyword cp_noisy: generate informational log messages during operation
            (default C{False})

        @keyword cp_openfun: a callback invoked after every C{connect()} on the
            underlying DB-API object. The callback is passed a new DB-API
            connection object. This callback can setup per-connection state
            such as charset, timezone, etc.

        @keyword cp_reconnect: detect connections which have failed and reconnect
            (default C{False}). Failed connections may result in
            L{ConnectionLost} exceptions, which indicate the query may need to
            be re-sent.

        @keyword cp_good_sql: an sql query which should always succeed and change
            no state (default C{'select 1'})

        @keyword cp_reactor: use this reactor instead of the global reactor
            (added in Twisted 10.2).
        @type cp_reactor: L{IReactorCore} provider
        apilevelNz2.0z'DB API module not DB API 2.0 compliant.threadsafetyr      z+DB API module not sufficiently thread-safe.
cp_reactor)reactorcp_)
threadable
threadpool)	dbapiNamer   namedModuledbapir,   r   r'   poptwisted.internetrC   _reactorconnargsconnkwCP_ARGSsetattrminmaxconnectionstwisted.pythonrE   rF   getThreadIDthreadID
ThreadPoolcallWhenRunning_startstartID)	r   rG   rM   rN   rC   argcpArgrE   rF   s	            r   r   zConnectionPool.__init__   s   F #(33
4:z400E99G=>>>4:~q11A55GABBB**\400?000000 < 	" 	"C#KKEc6%=1115Mtx**tx**  	:9999999".$//$(CC}44T[AAr   c                 8    d | _         |                                 S r   )rZ   startr   s    r   rY   zConnectionPool._start   s    zz||r   c                     | j         sH| j                                         | j                            dd| j                  | _        d| _         dS dS )z
        Start the connection pool.

        If you are using the reactor normally, this function does *not*
        need to be called.
        duringshutdownTN)runningrF   r^   rL   addSystemEventTrigger
finalClose
shutdownIDr   s    r   r^   zConnectionPool.start   s[     | 	 O!!###"mAA*do DO  DLLL	  	 r   c                 P    t          j        | j        | j        | j        |g|R i |S )a  
        Execute a function with a database connection and return the result.

        @param func: A callable object of one argument which will be executed
            in a thread with a connection from the pool. It will be passed as
            its first argument a L{Connection} instance (whose interface is
            mostly identical to that of a connection object for your DB-API
            module of choice), and its results will be returned as a
            L{Deferred}. If the method raises an exception the transaction will
            be rolled back. Otherwise, the transaction will be committed.
            B{Note} that this function is B{not} run in the main thread: it
            must be threadsafe.

        @param args: positional arguments to be passed to func

        @param kw: keyword arguments to be passed to func

        @return: a L{Deferred} which will fire the return value of
            C{func(Transaction(...), *args, **kw)}, or a
            L{twisted.python.failure.Failure}.
        )r   deferToThreadPoolrL   rF   _runWithConnection)r   funcargskws       r   runWithConnectionz ConnectionPool.runWithConnection   sC    , (M4?D,CT
LP
 
 
TV
 
 	
r   c                    |                      |           }	  ||g|R i |}|                                 |S # t          $ r= 	 |                                 n%# t          $ r t	          j        d d           Y nw xY w w xY wNr   )connectionFactoryr"   r#   r   r   r$   )r   ri   rj   rk   connresults         r   rh   z!ConnectionPool._runWithConnection  s    %%d++		T$,,,,,,FKKMMMM 	 	 	1  1 1 1/000001	s-   !9 
B AB A;8B :A;;B c                 P    t          j        | j        | j        | j        |g|R i |S )a  
        Interact with the database and return the result.

        The 'interaction' is a callable object which will be executed in a
        thread using a pooled connection. It will be passed an L{Transaction}
        object as an argument (whose interface is identical to that of the
        database cursor for your DB-API module of choice), and its results will
        be returned as a L{Deferred}. If running the method raises an
        exception, the transaction will be rolled back. If the method returns a
        value, the transaction will be committed.

        NOTE that the function you pass is *not* run in the main thread: you
        may have to worry about thread-safety in the function you pass to this
        if it tries to use non-local objects.

        @param interaction: a callable object whose first argument is an
            L{adbapi.Transaction}.

        @param args: additional positional arguments to be passed to
            interaction

        @param kw: keyword arguments to be passed to interaction

        @return: a Deferred which will fire the return value of
            C{interaction(Transaction(...), *args, **kw)}, or a
            L{twisted.python.failure.Failure}.
        )r   rg   rL   rF   _runInteraction)r   interactionrj   rk   s       r   runInteractionzConnectionPool.runInteraction$  sJ    8 (MO 	

 
 
 
 
 
 	
r   c                 .     | j         | j        g|R i |S )aY  
        Execute an SQL query and return the result.

        A DB-API cursor which will be invoked with C{cursor.execute(*args,
        **kw)}. The exact nature of the arguments will depend on the specific
        flavor of DB-API being used, but the first argument in C{*args} be an
        SQL statement. The result of a subsequent C{cursor.fetchall()} will be
        fired to the L{Deferred} which is returned. If either the 'execute' or
        'fetchall' methods raise an exception, the transaction will be rolled
        back and a L{twisted.python.failure.Failure} returned.

        The C{*args} and C{**kw} arguments will be passed to the DB-API
        cursor's 'execute' method.

        @return: a L{Deferred} which will fire the return value of a DB-API
            cursor's 'fetchall' method, or a L{twisted.python.failure.Failure}.
        )ru   	_runQueryr   rj   rk   s      r   runQueryzConnectionPool.runQueryI  s)    $ #t"4>?D???B???r   c                 .     | j         | j        g|R i |S )aK  
        Execute an SQL query and return L{None}.

        A DB-API cursor which will be invoked with C{cursor.execute(*args,
        **kw)}. The exact nature of the arguments will depend on the specific
        flavor of DB-API being used, but the first argument in C{*args} will be
        an SQL statement. This method will not attempt to fetch any results
        from the query and is thus suitable for C{INSERT}, C{DELETE}, and other
        SQL statements which do not return values. If the 'execute' method
        raises an exception, the transaction will be rolled back and a
        L{Failure} returned.

        The C{*args} and C{*kw} arguments will be passed to the DB-API cursor's
        'execute' method.

        @return: a L{Deferred} which will fire with L{None} or a
            L{twisted.python.failure.Failure}.
        )ru   _runOperationrx   s      r   runOperationzConnectionPool.runOperation]  s*    & #t"4#5CCCCCCCr   c                     | j         r&| j                            | j                    d| _         | j        r&| j                            | j                   d| _        |                                  dS )zC
        Close all pool connections and shutdown the pool.
        N)re   rL   removeSystemEventTriggerrZ   rd   r   s    r   r   zConnectionPool.closer  sl     ? 	#M224?CCC"DO< 	 M224<@@@DLr   c                     d| _         | j                                         d| _        | j                                        D ]}|                     |           | j                                         dS )zE
        This should only be called by the shutdown trigger.
        NF)re   rF   stoprb   rS   values_closeclearr   rp   s     r   rd   zConnectionPool.finalClose~  st     $++-- 	 	DKK     r   c                 0   |                                  }| j                            |          }|e| j        rt	          j        d| j                     | j        j        | j	        i | j
        }| j        |                     |           || j        |<   |S )a  
        Return a database connection when one becomes available.

        This method blocks and should be run in a thread from the internal
        threadpool. Don't call this method directly from non-threaded code.
        Using this method outside the external threadpool may exceed the
        maximum number of connections in the pool.

        @return: a database connection from the pool.
        Nzadbapi connecting: )rV   rS   getr&   r   r'   rG   rI   r*   rM   rN   openfun)r   tidrp   s      r   r*   zConnectionPool.connect  s     mmoo##C((<z @>dn>>???%4:%t}DDDD|'T"""$(DS!r   c                     |                                  }|| j                            |          urt          d          ||                     |           | j        |= dS dS )a  
        Disconnect a database connection associated with this pool.

        Note: This function should only be used by the same thread which called
        L{ConnectionPool.connect}. As with C{connect}, this function is not
        used in normal non-threaded Twisted code.
        zwrong connection for threadN)rV   rS   r   	Exceptionr   )r   rp   r   s      r   r%   zConnectionPool.disconnect  sm     mmoot'++C00009:::KK %%% r   c                     | j         rt          j        d| j                    	 |                                 d S # t
          $ r t          j        d d           Y d S w xY w)Nzadbapi closing: zConnection close failed)r&   r   r'   rG   r   r#   r$   r   s     r   r   zConnectionPool._close  st    : 	9G7t~77888	5JJLLLLL 	5 	5 	5GD3444444	5s   ; AAc                 Z   |                      |           }|                     | |          }	  ||g|R i |}|                                 |                                 |S # t          $ r= 	 |                                 n%# t          $ r t          j        d d           Y nw xY w w xY wrn   )ro   transactionFactoryr   r"   r#   r   r   r$   )r   rt   rj   rk   rp   transrq   s          r   rs   zConnectionPool._runInteraction  s    %%d++''d33
	 [444444FKKMMMKKMMMM 	 	 	1  1 1 1/000001	s/   5A# #
B*.BB*B%"B*$B%%B*c                 D     |j         |i | |                                S r   )r    fetchallr   r   rj   rk   s       r   rw   zConnectionPool._runQuery  s)    t"r"""~~r   c                       |j         |i | d S r   )r    r   s       r   r{   zConnectionPool._runOperation  s    t"r"""""r   c           	      h    | j         | j        | j        | j        | j        | j        | j        | j        dS )NrG   rQ   rR   r&   r   r!   rM   rN   r   r   s    r   __getstate__zConnectionPool.__getstate__  s9    88Zk	
 	
 		
r   c                 T    || _          | j        | j        g| j        R i | j         d S r   )__dict__r   rG   rM   rN   )r   states     r   __setstate__zConnectionPool.__setstate__  s7    dnDt}DDDDDDDDr   )%r   r	   r
   r   splitrO   r&   rQ   rR   r.   r   r   r!   rb   r   ro   r1   r   re   r   rY   r^   rl   rh   ru   ry   r|   r   rd   r*   r%   r   rs   rw   r{   r   r   r   r   r   r;   r;   ~   s        & >CCEEGE
C
CDGIHG"$ JEB EB EBN       
 
 
4  #
 #
 #
J@ @ @(D D D*
 
 
	! 	! 	!  .& & &5 5 5       # # #

 

 

E E E E Er   r;   N)r   rK   r   rT   r   r   r   r   r   r1   r;   __all__r   r   r   <module>r      s  
  % $ $ $ $ $ ' ' ' ' ' ' ' '    Y   4/ 4/ 4/ 4/ 4/ 4/ 4/ 4/n.+ .+ .+ .+ .+ .+ .+ .+b]E ]E ]E ]E ]E ]E ]E ]E@ *
+r   