U
    @f<                     @   s  d dl m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 d dlmZ e ZG d	d
 d
eZdd ZG dd deZG dd deZG dd deZeZG dd dZejD ] ZefddZeeeee qe`[[G dd deZG dd dZdS )    )deque)contextmanagerN)Pool)timeout)hubs)Timer)GreenThreadc                   @   s   e Zd ZdS )ConnectTimeoutN)__name__
__module____qualname__ r   r   J/var/www/html/chatgpt/venv/lib/python3.8/site-packages/eventlet/db_pool.pyr	      s   r	   c                 C   s   |    d S N)rollback)connr   r   r   cleanup_rollback   s    r   c                       s   e Zd Zdddddef fdd	Zdd	 Zd
d Zdd Zdd ZdddZ	 fddZ
ef fdd	ZeefddZdd Zdd Z  ZS )BaseConnectionPoolr      
         c           
         sN   |st || _|| _|	| _|| _|| _|| _d| _|| _t	 j
||dd dS )a  
        Constructs a pool with at least *min_size* connections and at most
        *max_size* connections.  Uses *db_module* to construct new connections.

        The *max_idle* parameter determines how long pooled connections can
        remain idle, in seconds.  After *max_idle* seconds have elapsed
        without the connection being used, the pool closes the connection.

        *max_age* is how long any particular connection is allowed to live.
        Connections that have been open for longer than *max_age* seconds are
        closed, regardless of idle time.  If *max_age* is 0, all connections are
        closed on return to the pool, reducing it to a concurrency limiter.

        *connect_timeout* is the duration in seconds that the pool will wait
        before timing out on connect() to the database.  If triggered, the
        timeout will raise a ConnectTimeout from get().

        The remainder of the arguments are used as parameters to the
        *db_module*'s connection constructor.
        NT)min_sizemax_sizeZorder_as_stack)AssertionError
_db_module_args_kwargsmax_idlemax_ageconnect_timeout_expiration_timercleanupsuper__init__)
self	db_moduler   r   r   r   r    r"   argskwargs	__class__r   r   r$      s    zBaseConnectionPool.__init__c              	   C   s   | j dks| jdkrdS | jdk	r4t| jdds4dS zZt }| | | jd d | | j }tdd | jD }|| | j  }t||}W n  tt	fk
r   d| _Y dS X |dkrt
|tt jj| jg i | _| j  dS )a  Sets up a timer that will call _expire_old_connections when the
        oldest connection currently in the free pool is ready to expire.  This
        is the earliest possible time that a connection could expire, thus, the
        timer will be running as infrequently as possible without missing a
        possible expiration.

        If this function is called when a timer is already scheduled, it does
        nothing.

        If max_age or max_idle is 0, _schedule_expiration likewise does nothing.
        r   NZcalledFc                 S   s   g | ]}|d  qS )   r   ).0tr   r   r   
<listcomp>Z   s     z;BaseConnectionPool._schedule_expiration.<locals>.<listcomp>)r   r   r!   getattrtime_expire_old_connections
free_itemsmin
IndexError
ValueErrorr   r   r   Zget_hubZgreenletswitch_schedule_expirationZschedule)r%   nowZ
idle_delayZoldestZ	age_delayZ
next_delayr   r   r   r8   >   s.    

  z'BaseConnectionPool._schedule_expirationc                    s   t j} fddjD } fddjD }j  j|  j|t j 8  _|D ]}j|dd qhdS )a  Iterates through the open connections contained in the pool, closing
        ones that have remained idle for longer than max_idle seconds, or have
        been in existence for longer than max_age seconds.

        *now* is the current time, as returned by time.time().
        c                    s$   g | ]\}}}  ||r|qS r   _is_expiredr-   	last_used
created_atr   r9   r%   r   r   r/   q   s   z>BaseConnectionPool._expire_old_connections.<locals>.<listcomp>c                    s*   g | ]"\}}}  ||s|||fqS r   r:   r<   r?   r   r   r/   v   s   TquietN)lenr3   clearextendcurrent_size_safe_close)r%   r9   Zoriginal_countZexpiredZnew_freer   r   r?   r   r2   i   s    

z*BaseConnectionPool._expire_old_connectionsc                 C   s8   | j dks0| jdks0|| | j ks0|| | jkr4dS dS )z@Returns true and closes the connection if it's expired.
        r   TF)r   r   )r%   r9   r=   r>   r   r   r   r;      s    zBaseConnectionPool._is_expiredc                 C   s:   d}z|r|j }|  nd}W n tk
r4   Y nX |S )a$  If the connection was wrapped by a subclass of
        BaseConnectionWrapper and is still functional (as determined
        by the __nonzero__, or __bool__ in python3, method), returns
        the unwrapped connection.  If anything goes wrong with this
        process, returns None.
        N)_base_destroyAttributeError)r%   r   baser   r   r   _unwrap_connection   s    
z%BaseConnectionPool._unwrap_connectionFc                 C   sP   z|   W n> tk
r    Y n, tk
rJ   |sFtdt d   Y nX dS )zVCloses the (already unwrapped) connection, squelching any
        exceptions.
        zConnection.close raised: %sr,   N)closerI   	Exceptionprintsysexc_info)r%   r   rA   r   r   r   rF      s    zBaseConnectionPool._safe_closec                    sv   t   }|d krDz|  }W n$ tk
rB   |  jd8  _ Y nX t|trZ|\}}}nt }t|| }||_	|S )Nr,   )
r#   getcreaterM   rE   
isinstancetupler1   PooledConnectionWrapper_db_pool_created_at)r%   r   Z
_last_usedr>   wrappedr)   r   r   rQ      s    


zBaseConnectionPool.getc              
      s   t |dd}t }| |}| |||r@| j|dd d }nn|d k	r|tkrV| j}z|rd|| W nF tk
r } ztd||f  d }W 5 d }~X Y n   d } Y nX |d k	rt	 
|||f n(|  dkrt	 
d  n|  jd8  _|   d S )NrV   r   Fr@   zWARNING: cleanup %s raised: %sr,   )r0   r1   rK   r;   rF   _MISSINGr"   rM   rN   r#   putZwaitingrE   r8   )r%   r   r"   r>   r9   er)   r   r   rY      s0    
zBaseConnectionPool.putc              
   c   s(   |   }z
|V  W 5 | j||d X d S )N)r"   )rQ   rY   )r%   r"   r   r   r   r   item   s    
zBaseConnectionPool.itemc                 C   s`   | j r| j   | jt  }| _|D ]6}t|tr:|d n|}| j|dd |  jd8  _q$dS )zuClose all connections that this pool still holds a reference to,
        and removes all references to them.
           Tr@   r,   N)r!   cancelr3   r   rS   rT   rF   rE   )r%   r3   r[   r   r   r   r   rC      s    
zBaseConnectionPool.clearc                 C   s   |    d S r   )rC   r%   r   r   r   __del__  s    zBaseConnectionPool.__del__)F)r
   r   r   r   r$   r8   r2   r;   rK   rF   rQ   rX   rY   r   r[   rC   r_   __classcell__r   r   r)   r   r      s$     %+	
&r   c                   @   s$   e Zd ZdZdd Zedd ZdS )TpooledConnectionPoolzZA pool which gives out :class:`~eventlet.tpool.Proxy`-based database
    connections.
    c                 C   s*   t   }||| j| j| jf| j| jfS r   r1   connectr   r    r   r   r%   r9   r   r   r   rR     s     zTpooledConnectionPool.createc                 O   sP   t |t }z2ddlm} |j|jf||}|j|ddW S |  X d S )Nr   )tpool)cursor)Zautowrap_names)	r   Timeoutr	   r]   eventletre   executerc   ZProxy)clsr&   r    r'   kwr.   re   r   r   r   r   rc     s    zTpooledConnectionPool.connectNr
   r   r   __doc__rR   classmethodrc   r   r   r   r   ra     s   ra   c                   @   s$   e Zd ZdZdd Zedd ZdS )RawConnectionPoolz7A pool which gives out plain database connections.
    c                 C   s*   t   }||| j| j| jf| j| jfS r   rb   rd   r   r   r   rR   !  s     zRawConnectionPool.createc                 O   s.   t |t }z|j||W S |  X d S r   )r   rg   r	   r]   rc   )rj   r&   r    r'   rk   r.   r   r   r   rc   &  s    zRawConnectionPool.connectNrl   r   r   r   r   ro     s   ro   c                   @   s0   e Zd Zdd Zdd Zdd Zdd Zd	Zd
S )GenericConnectionWrapperc                 C   s
   || _ d S r   )rG   )r%   baseconnr   r   r   r$   4  s    z!GenericConnectionWrapper.__init__c                 C   s
   | j  S r   )rG   	__enter__r^   r   r   r   rr   =  s    z"GenericConnectionWrapper.__enter__c                 C   s   | j |||S r   )rG   __exit__)r%   excvaluetbr   r   r   rs   @  s    z!GenericConnectionWrapper.__exit__c                 C   s
   | j  S r   )rG   __repr__r^   r   r   r   rw   C  s    z!GenericConnectionWrapper.__repr__)!Zaffected_rowsZ
autocommitbeginZchange_userZcharacter_set_namerL   commitrf   Zdump_debug_infoerrnoerrorZerrorhandlerZget_server_infoZ	insert_idliteralZpingqueryr   Z	select_dbZserver_capabilitiesZset_character_setZset_isolation_levelZset_server_optionZset_sql_modeZshow_warningsshutdownZsqlstatestatZstore_resultZstring_literal	thread_idZ
use_resultZwarning_countN)r
   r   r   r$   rr   rs   rw   _proxy_funcsr   r   r   r   rp   3  s
   	rp   c                    s&    fdd} |_  |_d  |_|S )Nc                    s   t | j ||S r   )r0   rG   )r%   r'   r(   
_proxy_funr   r   _proxy_methodn  s    z_wrapper.<locals>._proxy_methodzGenericConnectionWrapper.)	func_namer
   r   )r   r   r   r   r   _wrapperm  s
    
r   c                       sD   e Zd ZdZ fddZdd ZeZdd Zdd	 Zd
d Z	  Z
S )rU   zA connection wrapper where:
    - the close method returns the connection to the pool instead of closing it directly
    - ``bool(conn)`` returns a reasonable value
    - returns itself to the pool if it gets garbage collected
    c                    s   t  | || _d S r   )r#   r$   _pool)r%   rq   poolr)   r   r   r$     s    z PooledConnectionWrapper.__init__c                 C   s   t | dot| jS )NrG   )hasattrboolrG   r^   r   r   r   __nonzero__  s    z#PooledConnectionWrapper.__nonzero__c                 C   s(   d | _ z| `W n tk
r"   Y nX d S r   )r   rG   rI   r^   r   r   r   rH     s
    z PooledConnectionWrapper._destroyc                 C   s"   | r| j r| j |  |   dS )zReturn the connection to the pool, and remove the
        reference to it so that you can't use it again through this
        wrapper object.
        N)r   rY   rH   r^   r   r   r   rL     s    
zPooledConnectionWrapper.closec                 C   s   d S r   r   r^   r   r   r   r_     s    zPooledConnectionWrapper.__del__)r
   r   r   rm   r$   r   __bool__rH   rL   r_   r`   r   r   r)   r   rU   z  s   	rU   c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
DatabaseConnectorzr
    This is an object which will maintain a collection of database
    connection pools on a per-host basis.
    Nc                 O   s@   |st || _| jdkrt| _|| _|| _|| _|| _i | _dS )zconstructor
        *module*
            Database module to use.
        *credentials*
            Mapping of hostname to connect arguments (e.g. username and password)
        N)r   _conn_pool_classConnectionPool_moduler   r   _credentials
_databases)r%   modulecredentialsZ	conn_poolr'   r(   r   r   r   r$     s    
zDatabaseConnector.__init__c                 C   s&   || j kr| j | S | j dd S d S )Ndefault)r   rQ   )r%   hostr   r   r   credentials_for  s    

z!DatabaseConnector.credentials_forc                 C   sf   ||f}|| j kr\| j }||d< ||d< || | | j| jf| j|}|| j |< | j | S )z@Returns a ConnectionPool to the target host and schema.
        dbr   )r   r   copyupdater   r   r   r   )r%   r   ZdbnamekeyZ
new_kwargsZdbpoolr   r   r   rQ     s    


zDatabaseConnector.get)N)r
   r   r   rm   r$   r   rQ   r   r   r   r   r     s
    
r   )collectionsr   
contextlibr   rO   r1   Zeventlet.poolsr   rh   r   r   Zeventlet.hubs.timerr   Zeventlet.greenthreadr   objectrX   rM   r	   r   r   ra   ro   r   rp   r   r   r   setattrrU   r   r   r   r   r   <module>   s2    q8
&