
    +hQ                     R   d Z ddlmZ ddlZddlZddlmZ ddlmZ ddlmZ ddlm	Z	  e	j                  d	      Z e	j                  d
      Z e	j                  d      Z G d de      Z G d de      Z G d dej"                        Z G d de      Z	 	 ddZi Z G d de      Zy)z'Base constructs for connection pools.

    )dequeN   )event)exc)log)utilreset_rollbackreset_commit
reset_nonec                   <    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
d Zy	)
_ConnDialectzpartial implementation of :class:`.Dialect`
    which provides DBAPI connection methods.

    When a :class:`_pool.Pool` is combined with an :class:`_engine.Engine`,
    the :class:`_engine.Engine` replaces this with its own
    :class:`.Dialect`.

    Fc                 $    |j                          y N)rollbackselfdbapi_connections     G/var/www/html/venv/lib/python3.12/site-packages/sqlalchemy/pool/base.pydo_rollbackz_ConnDialect.do_rollback)   s    !!#    c                 $    |j                          y r   )commitr   s     r   	do_commitz_ConnDialect.do_commit,   s    !r   c                 $    |j                          y r   closer   s     r   do_terminatez_ConnDialect.do_terminate/        r   c                 $    |j                          y r   r   r   s     r   do_closez_ConnDialect.do_close2   r   r   c                     t        d      )NzJThe ping feature requires that a dialect is passed to the connection pool.NotImplementedErrorr   s     r   do_pingz_ConnDialect.do_ping5   s    !-
 	
r   c                     |S r    )r   
connections     r   get_driver_connectionz"_ConnDialect.get_driver_connection;   s    r   N)__name__
__module____qualname____doc__is_asynchas_terminater   r   r   r    r$   r(   r&   r   r   r   r      s1     HM$"!!
r   r   c                       e Zd ZdZy)_AsyncConnDialectTN)r)   r*   r+   r-   r&   r   r   r0   r0   ?   s    Hr   r0   c                       e Zd ZdZ e       Z	 	 	 	 	 	 	 	 ddZej                  d        Z	e
d        Zej                  d        Zd ZddZd	 Zdd
Zd Zd Zd Zd Zd Zd Zd Zy)Poolz)Abstract base class for connection pools.Nc
           	         |r|x| _         | _        nd| _        t        j                  | |       || _        || _        d| _        || _        t        j                  j                  |t        ddgt        g dt        dgidd	
      | _        || _        |	r| j                   j#                  |	d	       |r|| _        |r"|D ]  \  }
}t'        j(                  | ||
        yy)a  
        Construct a Pool.

        :param creator: a callable function that returns a DB-API
          connection object.  The function will be called with
          parameters.

        :param recycle: If set to a value other than -1, number of
          seconds between connection recycling, which means upon
          checkout, if this timeout is surpassed the connection will be
          closed and replaced with a newly opened connection. Defaults to -1.

        :param logging_name:  String identifier which will be used within
          the "name" field of logging records generated within the
          "sqlalchemy.pool" logger. Defaults to a hexstring of the object's
          id.

        :param echo: if True, the connection pool will log
         informational output such as when connections are invalidated
         as well as when connections are recycled to the default log handler,
         which defaults to ``sys.stdout`` for output..   If set to the string
         ``"debug"``, the logging will include pool checkouts and checkins.

         The :paramref:`_pool.Pool.echo` parameter can also be set from the
         :func:`_sa.create_engine` call by using the
         :paramref:`_sa.create_engine.echo_pool` parameter.

         .. seealso::

             :ref:`dbengine_logging` - further detail on how to configure
             logging.

        :param reset_on_return: Determine steps to take on
         connections as they are returned to the pool, which were
         not otherwise handled by a :class:`_engine.Connection`.
         Available from :func:`_sa.create_engine` via the
         :paramref:`_sa.create_engine.pool_reset_on_return` parameter.

         :paramref:`_pool.Pool.reset_on_return` can have any of these values:

         * ``"rollback"`` - call rollback() on the connection,
           to release locks and transaction resources.
           This is the default value.  The vast majority
           of use cases should leave this value set.
         * ``"commit"`` - call commit() on the connection,
           to release locks and transaction resources.
           A commit here may be desirable for databases that
           cache query plans if a commit is emitted,
           such as Microsoft SQL Server.  However, this
           value is more dangerous than 'rollback' because
           any data changes present on the transaction
           are committed unconditionally.
         * ``None`` - don't do anything on the connection.
           This setting may be appropriate if the database / DBAPI
           works in pure "autocommit" mode at all times, or if
           a custom reset handler is established using the
           :meth:`.PoolEvents.reset` event handler.
         * ``True`` - same as 'rollback', this is here for
           backwards compatibility.
         * ``False`` - same as None, this is here for
           backwards compatibility.

         For further customization of reset on return, the
         :meth:`.PoolEvents.reset` event hook may be used which can perform
         any connection activity desired on reset.  (requires version 1.4.43
         or greater)

         .. seealso::

            :ref:`pool_reset_on_return`

        :param events: a list of 2-tuples, each of the form
         ``(callable, target)`` which will be passed to :func:`.event.listen`
         upon construction.   Provided here so that event listeners
         can be assigned via :func:`_sa.create_engine` before dialect-level
         listeners are applied.

        :param dialect: a :class:`.Dialect` that will handle the job
         of calling rollback(), close(), or commit() on DBAPI connections.
         If omitted, a built-in "stub" dialect is used.   Applications that
         make use of :func:`_sa.create_engine` should not use this parameter
         as it is handled by the engine creation strategy.

         .. versionadded:: 1.1 - ``dialect`` is now a public parameter
            to the :class:`_pool.Pool`.

        :param pre_ping: if True, the pool will emit a "ping" (typically
         "SELECT 1", but is dialect-specific) on the connection
         upon checkout, to test if the connection is alive or not.   If not,
         the connection is transparently re-connected and upon success, all
         other pooled connections established prior to that timestamp are
         invalidated.     Requires that a dialect is passed as well to
         interpret the disconnection error.

         .. versionadded:: 1.2

        N)echoflagr   r   T)noneNFr   reset_on_returnF)resolve_symbol_names)only_propagate)logging_name_orig_logging_namer   instance_logger_creator_recycle_invalidate_time	_pre_pingr   symbolparse_user_argumentr	   r   r
   _reset_on_returnechodispatch_update_dialectr   listen)r   creatorrecyclerC   r9   r6   eventsdialectpre_ping	_dispatchfntargets               r   __init__zPool.__init__I   s    Z :FFD 7&*D#D40 !! $ ? ?T 21xj
 !& !@ 	!
 	MM!!)E!B#DM$ /
FT62./ r   c                 .    | j                   j                  S r   )rF   r-   r   s    r   _is_asynciozPool._is_asyncio   s    }}%%%r   c                      | j                   d   S Nr<   )__dict__rR   s    r   r<   zPool._creator   s    }}Z((r   c                 N    || j                   d<   | j                  |      | _        y rU   )rV   _should_wrap_creator_invoke_creator)r   rH   s     r   r<   zPool._creator   s#    $+j!#88Ar   c                    	 t        j                  | j                  d      }|d   duxr t	        |d         xs d}t	        |d         |z
  }|d   |d   fdgdfk(  rS |d	k(  rS fd
S # t        $ r fdcY S w xY w)zlDetect if creator accepts a single argument, or is sent
        as a legacy style no-arg function.

        T)no_selfc                             S r   r&   crecrH   s    r   <lambda>z+Pool._should_wrap_creator.<locals>.<lambda>   	    	 r      Nr   connection_recordr      c                             S r   r&   r]   s    r   r_   z+Pool._should_wrap_creator.<locals>.<lambda>   r`   r   )r   get_callable_argspecr<   	TypeErrorlen)r   rH   argspec	defaultedpositionalss    `   r   rX   zPool._should_wrap_creator   s    	*//tLG AJd*>s71:C!	'!*o	1 AJ
#)<(=w'GGNAN *)!  	*))	*s   !A. .A?>A?c                 D   | j                   j                  d|rdnd|       	 |r| j                  j                  |       y | j                  j	                  |       y # t
        $ r9}| j                   j                  d|d       t        |t              s Y d }~y d }~ww xY w)Nz%s connection %rzHard-closingClosingzException closing connection %rTexc_info)	loggerdebugrF   r   r    BaseExceptionerror
isinstance	Exception)r   r'   	terminatees       r   _close_connectionzPool._close_connection   s    'NY	


	**:6&&z2 	KK1:   a+ ,		s   A A 	B&/BBc                     t        |       S )z6Called by subclasses to create a new ConnectionRecord.)_ConnectionRecordrR   s    r   _create_connectionzPool._create_connection  s     !&&r   c                     t        |dd      }|r| j                  |j                  k  rt        j                         | _        |r t        |dd      r|j	                  |       yyy)a  Mark all connections established within the generation
        of the given connection as invalidated.

        If this pool's last invalidate time is before when the given
        connection was created, update the timestamp til now.  Otherwise,
        no action is performed.

        Connections with a start time prior to this pool's invalidation
        time will be recycled upon next checkout.
        _connection_recordNis_validF)getattrr>   	starttimetime
invalidate)r   r'   	exception_checkinrecs        r   _invalidatezPool._invalidate  sX     j"6=d++cmm;$(IIKD!
J>!!), ?8r   c                     t               )a"  Return a new :class:`_pool.Pool`, of the same class as this one
        and configured with identical creation arguments.

        This method is used in conjunction with :meth:`dispose`
        to close out an entire :class:`_pool.Pool` and create a new one in
        its place.

        r"   rR   s    r   recreatezPool.recreate$  s     "##r   c                     t               )zDispose of this pool.

        This method leaves the possibility of checked-out connections
        remaining open, as it only affects connections that are
        idle in the pool.

        .. seealso::

            :meth:`Pool.recreate`

        r"   rR   s    r   disposezPool.dispose0  s     "##r   c                 ,    t         j                  |       S )zReturn a DBAPI connection from the pool.

        The connection is instrumented such that when its
        ``close()`` method is called, the connection will be returned to
        the pool.

        )_ConnectionFairy	_checkoutrR   s    r   connectzPool.connect?  s      ))$//r   c                 &    | j                  |       y)zGiven a _ConnectionRecord, return it to the :class:`_pool.Pool`.

        This method is called when an instrumented DBAPI connection
        has its ``close()`` method called.

        N)_do_return_conn)r   records     r   _return_connzPool._return_connI  s     	V$r   c                     t               )z7Implementation for :meth:`get`, supplied by subclasses.r"   rR   s    r   _do_getzPool._do_getR       "##r   c                     t               )z?Implementation for :meth:`return_conn`, supplied by subclasses.r"   )r   conns     r   r   zPool._do_return_connW  r   r   c                     t               r   r"   rR   s    r   statuszPool.status\  s    !##r   )NNTNNFNF)NT)r)   r*   r+   r,   r   rF   rP   r   hybridpropertyrS   propertyr<   setterrX   rw   rz   r   r   r   r   r   r   r   r   r&   r   r   r2   r2   C   s    3~H
 J/X 
& & ) ) __B B*4$'
-"
$$0%$
$
$r   r2   c                   "   e Zd ZdZddZdZdZdZdZ	 e	d        Z
e	d        Zej                  d        ZdZej                  d	        Zej                  d
        Zed        ZddZddZe	d        Ze	d        Zd ZddZd Zd ZddZd Zy)ry   a  Internal object which maintains an individual DBAPI connection
    referenced by a :class:`_pool.Pool`.

    The :class:`._ConnectionRecord` object always exists for any particular
    DBAPI connection whether or not that DBAPI connection has been
    "checked out".  This is in contrast to the :class:`._ConnectionFairy`
    which is only a public facade to the DBAPI connection while it is checked
    out.

    A :class:`._ConnectionRecord` may exist for a span longer than that
    of a single DBAPI connection.  For example, if the
    :meth:`._ConnectionRecord.invalidate`
    method is called, the DBAPI connection associated with this
    :class:`._ConnectionRecord`
    will be discarded, but the :class:`._ConnectionRecord` may be used again,
    in which case a new DBAPI connection is produced when the
    :class:`_pool.Pool`
    next uses this record.

    The :class:`._ConnectionRecord` is delivered along with connection
    pool events, including :meth:`_events.PoolEvents.connect` and
    :meth:`_events.PoolEvents.checkout`, however :class:`._ConnectionRecord`
    still
    remains an internal object whose API and internals may change.

    .. seealso::

        :class:`._ConnectionFairy`

    c                 T    || _         |r| j                          t               | _        y r   )_ConnectionRecord__pool_ConnectionRecord__connectr   finalize_callback)r   poolr   s      r   rP   z_ConnectionRecord.__init__  s     NN!&r   FNc                 z    | j                   y| j                  j                  j                  | j                         S )a<  The connection object as returned by the driver after a connect.

        For normal sync drivers that support the DBAPI protocol, this object
        is the same as the one referenced by
        :attr:`._ConnectionRecord.dbapi_connection`.

        For adapted drivers, like the Asyncio ones, this is the actual object
        that was returned by the driver ``connect`` call.

        As :attr:`._ConnectionRecord.dbapi_connection` it may be ``None``
        if this :class:`._ConnectionRecord` has been marked as invalidated.

        .. versionadded:: 1.4.24

        N)r   r   rF   r(   rR   s    r   driver_connectionz#_ConnectionRecord.driver_connection  s9    $   (;;''==%% r   c                     | j                   S )zAn alias to :attr:`._ConnectionRecord.dbapi_connection`.

        This alias is deprecated, please use the new name.

        .. deprecated:: 1.4.24

        r   rR   s    r   r'   z_ConnectionRecord.connection       $$$r   c                     || _         y r   r   r   values     r   r'   z_ConnectionRecord.connection  
     %r   r   c                     i S )a`  The ``.info`` dictionary associated with the DBAPI connection.

        This dictionary is shared among the :attr:`._ConnectionFairy.info`
        and :attr:`_engine.Connection.info` accessors.

        .. note::

            The lifespan of this dictionary is linked to the
            DBAPI connection itself, meaning that it is **discarded** each time
            the DBAPI connection is closed and/or invalidated.   The
            :attr:`._ConnectionRecord.record_info` dictionary remains
            persistent throughout the lifespan of the
            :class:`._ConnectionRecord` container.

        r&   rR   s    r   infoz_ConnectionRecord.info  s	    " 	r   c                     i S )a  An "info' dictionary associated with the connection record
        itself.

        Unlike the :attr:`._ConnectionRecord.info` dictionary, which is linked
        to the lifespan of the DBAPI connection, this dictionary is linked
        to the lifespan of the :class:`._ConnectionRecord` container itself
        and will remain persistent throughout the life of the
        :class:`._ConnectionRecord`.

        .. versionadded:: 1.1

        r&   rR   s    r   record_infoz_ConnectionRecord.record_info  s	     	r   c                    j                         	 j                         }j                         t        |      }t        j                  |fd      x_
        }t        |<   rj                  j                  d|       |S # t        $ rB}t        j                         5  j                  |d       d d d         # 1 sw Y    xY wd }~ww xY w)NF_fairy_was_createdc                 6    t         xr t        d | d      S )NFtransaction_was_reset)_finalize_fairy)refrC   r   r   s    r   r_   z,_ConnectionRecord.checkout.<locals>.<lambda>  s$     c4d% r   z#Connection %r checked out from pool)r   get_connectionrq   r   safe_reraise_checkin_failed_should_log_debugr   weakrefr   	fairy_ref_strong_ref_connection_recordsro   rp   )clsr   r   errfairyr   rC   r   s    `    @@r   checkoutz_ConnectionRecord.checkout  s    lln	"113 %%' !13=%kk
 	
 /2&s+KK57G -  	""$ C##CE#BC 	C 	s/   B 	CC*C>	CC	CCc                 L    | j                  |       | j                  |       y )Nrv   r   )r   checkin)r   r   r   s      r   r   z!_ConnectionRecord._checkin_failed  s$    #1 	 	
r   c                    | j                   |rt        j                  d| z         y d | _         | j                  }| j                  }| j
                  r/| j
                  j                         } ||       | j
                  r/|j                  j                  r|j                  j                  ||        |j                  |        y )NzDouble checkin attempted on %s)
r   r   warnr   r   r   poprD   r   r   )r   r   r'   r   	finalizers        r   r   z_ConnectionRecord.checkin  s    >>!&8 II6=>**
{{$$..224Ij! $$ ==  MM!!*d3$r   c                     | j                   d uS r   )r   rR   s    r   in_usez_ConnectionRecord.in_use$  s    ~~T))r   c                     | j                   S r   )r   rR   s    r   last_connect_timez#_ConnectionRecord.last_connect_time(  s    ~~r   c                 >    | j                   | j                          y y r   )r   _ConnectionRecord__closerR   s    r   r   z_ConnectionRecord.close,  s      ,LLN -r   c                 X   | j                   y|r2| j                  j                  j                  | j                   | |       n1| j                  j                  j	                  | j                   | |       |L| j                  j
                  j                  d|rdnd| j                   |j                  j                  |       n5| j                  j
                  j                  d|rdnd| j                          |rt        j                         | _
        y| j                  d       d| _         y)a  Invalidate the DBAPI connection held by this
        :class:`._ConnectionRecord`.

        This method is called for all connection invalidations, including
        when the :meth:`._ConnectionFairy.invalidate` or
        :meth:`_engine.Connection.invalidate` methods are called,
        as well as when any
        so-called "automatic invalidation" condition occurs.

        :param e: an exception object indicating a reason for the
          invalidation.

        :param soft: if True, the connection isn't closed; instead, this
          connection will be recycled on next checkout.

         .. versionadded:: 1.0.3

        .. seealso::

            :ref:`pool_connection_invalidation`

        Nz*%sInvalidate connection %r (reason: %s:%s)zSoft  z%sInvalidate connection %rTru   )r   r   rD   soft_invalidater   ro   r   	__class__r)   r   _soft_invalidate_timer   r   rv   softs      r   r   z_ConnectionRecord.invalidate0  s    0   (KK  00%%tQ KK  ++D,A,A4K=KK##<R%%$$ KK##,R%% )-D&LL4L($(D!r   c                 T   d}| j                   ,| j                  j                          | j                          n%| j                  j
                  dkD  rkt        j                         | j                  z
  | j                  j
                  kD  r3| j                  j                  j                  d| j                          d}n| j                  j                  | j                  kD  r3| j                  j                  j                  d| j                          d}nK| j                  | j                  kD  r2| j                  j                  j                  d| j                          d}|r<| j                  d       | j                  j                          | j                          | j                   S )NFr   z)Connection %r exceeded timeout; recyclingTz=Connection %r invalidated due to pool invalidation; recyclingzCConnection %r invalidated due to local soft invalidation; recyclingr   )r   r   clearr   r   r=   r   r   ro   r>   r   r   )r   rI   s     r   r   z _ConnectionRecord.get_connectione  sB      (IIOONNKK  2%		dnn,t{{/C/CCKK##;%% G[[))DNN:KK##%%
 G''$..8KK##%%
 GLL4L(IIOONN$$$r   c                     | j                   d u xs> | j                  j                  | j                  kD  xs | j                  | j                  kD  S r   )r   r   r>   r   r   rR   s    r   _is_hard_or_soft_invalidatedz._ConnectionRecord._is_hard_or_soft_invalidated  sG    !!T) ={{++dnn<=**T^^;	
r   c                 4   | j                   j                          | j                  j                  j                  r0| j                  j                  j	                  | j
                  |        | j                  j                  | j
                  |       d | _        y )Nr   )r   r   r   rD   r   r   rw   )r   ru   s     r   __closez_ConnectionRecord.__close  ss    $$&;;%%KK  &&t'<'<dC%%!!Y 	& 	
 !%r   c                    | j                   }d | _        	 t        j                         | _        |j	                  |       x| _        }|j
                  j                  d|       d| _        |j                  j                  rI|j                  j                  j                  |j                        j                  | j                  |        |j                  j                  j                  |j                        j                  | j                  |        y # t        $ rU}t        j                          5  |j
                  j                  d|       d d d        n# 1 sw Y   nxY wY d }~y Y d }~y d }~ww xY w)NzCreated new connection %rTzError on connect(): %s)r   r   r   r   rY   ro   rp   freshrD   first_connect
for_modifyexec_once_unless_exceptionr   _exec_w_sync_on_first_runrq   r   r   )r   r   r'   rv   s       r   	__connectz_ConnectionRecord.__connect  s#   {{ !%	E!YY[DN151E1Ed1KKD!JKK9:FDJ }}**++66MM,,T-B-BDI MM!!,,''(=(=tD  	?""$ ?!!":A>? ? ? ? ?	?s0   AD 	E0E+/E	E+E	E++E0)TNFr   )r)   r*   r+   r,   rP   r   r   r   r   r   r   r'   r   r   r   memoized_propertyr   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r&   r   r   ry   ry   `  s   >) EII   0 % % & & 	 $ 
   8
 , * *  3)j/%b
%Er   ry   c                    |rt         j                  |d       n+|r)t         j                  t        j                  |      d       ||j                  |ury| J |j
                  } |j                  j                  xr |j                  j                   }|r| xs |}| }	n| }d}	| |r|r|j                  j                  d|        	 |xs t        | ||      }|j
                  | u sJ |	r|j                  ||       |r|r||_        |j                          |	rC|j                  j                   r|j                  j!                  |        |j#                  |        n5d| z  }
|j                  j%                  |
       t'        j(                  |
       |r|j                  |j3                          yyy# t*        $ rL}|j                  j%                  dd       |r|j-                  |       t/        |t0              s Y d}~qd}~ww xY w)ac  Cleanup for a :class:`._ConnectionFairy` whether or not it's already
    been garbage collected.

    When using an async dialect no IO can happen here (without using
    a dedicated thread), since this is called outside the greenlet
    context and with an already running loop. In this case function
    will only log a message and raise a warning.
    NTz$Connection %r being returned to poolad  The garbage collector is trying to clean up connection %r. This feature is unsupported on unsupported on asyncio dbapis that lack a "terminate" feature, since no IO can be performed at this stage to reset the connection. Please close out all connections when they are no longer used, calling ``close()`` or using a context manager to manage their lifetime.z!Exception during reset or similarrm   r   )r   r   r   r   r   r   rF   r-   r.   ro   rp   r   _reset_pooldetachrD   close_detachedrw   rr   r   r   rq   r   rs   rt   r   )r   rb   r   r   rC   r   r   dont_restore_gcedr   can_manipulate_connectionmessagerv   s               r   r   r     s   $ &**35	&**7;;u+=tD
&&c1''',== 	Bt}}'B'B#B  &&-#(+G!&&$(!#KK6 
*	 - !E
 ))-====(T#89$"&EKLLN,}}33445EF**+;<1 )
)G KK%%g.IIg& .88D!!# E  	KK3d   !!,,q,1a+ ,	s   
C
F5 5	H
>AHH
c                      e Zd ZdZd ZdZ	 dZ	 ed        Zed        Z	e	j                  d        Z	edd       Zd Zdd	ZeZdd
Zed        Zed        Zej(                  d        Zed        ZddZd Zd Zd Zd ZddZy)r   ab  Proxies a DBAPI connection and provides return-on-dereference
    support.

    This is an internal object used by the :class:`_pool.Pool` implementation
    to provide context management to a DBAPI connection delivered by
    that :class:`_pool.Pool`.

    The name "fairy" is inspired by the fact that the
    :class:`._ConnectionFairy` object's lifespan is transitory, as it lasts
    only for the length of a specific DBAPI connection being checked out from
    the pool, and additionally that as a transparent proxy, it is mostly
    invisible.

    .. seealso::

        :class:`._ConnectionRecord`

    c                 .    || _         || _        || _        y r   )r   r|   _echo)r   r   rb   rC   s       r   rP   z_ConnectionFairy.__init__?  s     0"3
r   Nc                 .    | j                   j                  S )a  The connection object as returned by the driver after a connect.

        .. versionadded:: 1.4.24

        .. seealso::

            :attr:`._ConnectionFairy.dbapi_connection`

            :attr:`._ConnectionRecord.driver_connection`

            :ref:`faq_dbapi_connection`

        )r|   r   rR   s    r   r   z"_ConnectionFairy.driver_connection[  s     &&888r   c                     | j                   S )zAn alias to :attr:`._ConnectionFairy.dbapi_connection`.

        This alias is deprecated, please use the new name.

        .. deprecated:: 1.4.24

        r   rR   s    r   r'   z_ConnectionFairy.connectionl  r   r   c                     || _         y r   r   r   s     r   r'   z_ConnectionFairy.connectionw  r   r   c                    |s?t         j                  |      }||_        d|_        |t	        j
                  |      |_        |j                  t        j                  d      |xj                  dz  c_        |j                  j                  s|j                  r|j                  dk7  r|S d}|dkD  r:j                  j                  }d|j                  _        	 |j                  r|s|j                  r&|j                  j!                  d|j                         |j"                  j%                  |j                        }|sx|j                  r&|j                  j!                  d|j                         t        j&                         |j                  r&|j                  j!                  d|j                         |j                  j                  |j                  |j                  |       |S |j                  j-                  d       j/                          t        j                  d      # t        j(                  $ r(}|j*                  rL|j                  j-                  d	|       |j                  j/                  |       |j1                  ||d
       nB|j                  j-                  d|j                  |       |j                  j/                  |       	 |j                  j3                         |_        n^# t4        $ rR}t7        j8                         5  |j                  j;                  |d       ~d d d        n# 1 sw Y   nxY wY d }~nd }~ww xY w|dz  }Y d }~n`d }~wt4        $ rQ}	t7        j8                         5  |j                  }
|
|
j;                  |	d       ~d d d         # 1 sw Y    xY wd }	~	ww xY w|dkD  r)Nr   zThis connection is closedrc   r   FzPool pre-ping on connection %sz;Pool pre-ping on connection %s failed, will invalidate poolz)Connection %s is fresh, skipping pre-pingzoDisconnection detected on checkout, invalidating all pooled connections prior to current timestamp (reason: %r))r   zVDisconnection detected on checkout, invalidating individual connection %s (reason: %r)Tr   z+Reconnection attempts exhausted on checkout)ry   r   r   _counterr   r   currentr   r   InvalidRequestErrorrD   r?   r|   r   r   ro   rp   rF   r$   InvalidatePoolErrorDisconnectionErrorinvalidate_poolr   r   r   r   rq   r   r   r   )r   r   threadconnsr   attemptsconnection_is_freshresultrv   r   be_outerr   s              r   r   z_ConnectionFairy._checkout{  sW   %..t4EEKEN&&-kk%&8#!!)))*EFF!&&t~~^^q L l"'":":"@"@-2E$$*N>>. ;; KK-- @ % 6 6 "&!6!6u7M7M!N%${{ $ 1 1%;$)$:$:!"
 #&"9"9";;))G!22
 &&**E,D,De l 	FG%%&ABBo )) $$$KK$$9 	 ,,77:$$UA$>KK$$M..	 ,,77:"00??A * % "**, "00@@/3 A  "" " "" A  &&( 
22C++$/3 ,  
 
 G ls   DH- -OBM$K<;M$<	MMM8	MM
MM$MM$$O0N<#N0'	N<0N9	5N<<Oc                 D    t         j                  | j                  |       S )N)r   )r   r   r   rR   s    r   _checkout_existingz#_ConnectionFairy._checkout_existing  s    ))$**D)AAr   c           	          t        | j                  | j                  | j                  d | j                  ||        d | _        d | _        y )N)r   r   )r   r   r|   r   r   )r   r   s     r   r   z_ConnectionFairy._checkin  sE    !!##JJJJ"7	
 !%"&r   c                 h   |j                   j                  r&|j                   j                  | | j                         |j                  t        u r|r3| j
                  ru|j                  j                  d| j                         y | j
                  r&|j                  j                  d| j                         |j                  j                  |        y y |j                  t        u rN| j
                  r&|j                  j                  d| j                         |j                  j                  |        y y )Nz.Connection %s reset, transaction already resetz Connection %s rollback-on-returnzConnection %s commit-on-return)rD   resetr|   rB   r	   r   ro   rp   r   rF   r   r
   r   )r   r   r   s      r   r   z_ConnectionFairy._reset  s    ==MMd&=&=>  N2$::KK%%H--
 ::KK%%:-- ))$/  ""l2zz!!4)) MM##D) 3r   c                 .    | j                   j                  S r   )r   ro   rR   s    r   _loggerz_ConnectionFairy._logger  s    zz   r   c                     | j                   duS )zbReturn True if this :class:`._ConnectionFairy` still refers
        to an active DBAPI connection.Nr   rR   s    r   r}   z_ConnectionFairy.is_valid  s    
 $$D00r   c                 .    | j                   j                  S )a  Info dictionary associated with the underlying DBAPI connection
        referred to by this :class:`.ConnectionFairy`, allowing user-defined
        data to be associated with the connection.

        The data here will follow along with the DBAPI connection including
        after it is returned to the connection pool and used again
        in subsequent instances of :class:`._ConnectionFairy`.  It is shared
        with the :attr:`._ConnectionRecord.info` and
        :attr:`_engine.Connection.info`
        accessors.

        The dictionary associated with a particular DBAPI connection is
        discarded when the connection itself is discarded.

        )r|   r   rR   s    r   r   z_ConnectionFairy.info"  s    " &&+++r   c                 H    | j                   r| j                   j                  S y)a  Info dictionary associated with the :class:`._ConnectionRecord
        container referred to by this :class:`.ConnectionFairy`.

        Unlike the :attr:`._ConnectionFairy.info` dictionary, the lifespan
        of this dictionary is persistent across connections that are
        disconnected and/or invalidated within the lifespan of a
        :class:`._ConnectionRecord`.

        .. versionadded:: 1.1

        N)r|   r   rR   s    r   r   z_ConnectionFairy.record_info5  s"     ""**666r   c                     | j                   t        j                  d       y| j                  r| j                  j	                  ||       |sd| _         | j                          yy)a  Mark this connection as invalidated.

        This method can be called directly, and is also called as a result
        of the :meth:`_engine.Connection.invalidate` method.   When invoked,
        the DBAPI connection is immediately closed and discarded from
        further use by the pool.  The invalidation mechanism proceeds
        via the :meth:`._ConnectionRecord.invalidate` internal method.

        :param e: an exception object indicating a reason for the invalidation.

        :param soft: if True, the connection isn't closed; instead, this
         connection will be recycled on next checkout.

         .. versionadded:: 1.0.3

        .. seealso::

            :ref:`pool_connection_invalidation`

        Nz.Can't invalidate an already-closed connection.)rv   r   )r   r   r   r|   r   r   r   s      r   r   z_ConnectionFairy.invalidateG  s[    ,   (IIFG""##...>$(D!MMO r   c                 :     | j                   j                  |i |S )zReturn a new DBAPI cursor for the underlying connection.

        This method is a proxy for the ``connection.cursor()`` DBAPI
        method.

        )r   cursor)r   argskwargss      r   r  z_ConnectionFairy.cursorf  s"     ,t$$++T<V<<r   c                 .    t        | j                  |      S r   )r~   r   )r   keys     r   __getattr__z_ConnectionFairy.__getattr__o  s    t,,c22r   c                    | j                   | j                   }d|_        d|_        | j                  j	                  | j                          | j
                  j                         | _        d| _         | j                  j                  j                  r1| j                  j                  j                  | j                  |       yyy)a"  Separate this connection from its Pool.

        This means that the connection will no longer be returned to the
        pool when closed, and will instead be literally closed.  The
        containing ConnectionRecord is separated from the DB-API connection,
        and will create a new connection when next used.

        Note that any overall connection limiting constraints imposed by a
        Pool implementation may be violated after a detach, as the detached
        connection is removed from the pool's knowledge and control.
        N)	r|   r   r   r   r   r   copyrD   r   )r   r   s     r   r   z_ConnectionFairy.detachr  s     "".))C CM#'C JJ&&t'>'>?		(DI&*D#zz""))

##**4+@+@#F * /r   c                 n    | xj                   dz  c_         | j                   dk(  r| j                          y y )Nrc   r   r   r   rR   s    r   r   z_ConnectionFairy.close  s*    ==AMMO r   c                 r    | xj                   dz  c_         | j                   dk(  r| j                  |       y y )Nrc   r   r   r  )r   transaction_resets     r   _close_specialz_ConnectionFairy._close_special  s0    ==AMM0AMB r   )NNr   r   )r)   r*   r+   r,   rP   r   r|   r   r   r'   r   r   r   r  r   _closer   r	  r}   r   r   r   r   r   r  r  r   r   r  r&   r   r   r   r   *  s   &
   9 9  % % & & nC nC`B' F*2 ! ! 1 1 
, ,$  ">=3G2
Cr   r   )FN)r,   collectionsr   r   r   r   r   r   r   r   r@   r	   r
   r   objectr   r0   
Identifiedr2   ry   r   r   r   r&   r   r   <module>r      s           -.t{{>*T[[&
 6  F Z$3>> Z$z`E `ER  
]$H "$ iCv iCr   