
    h8'h$3                        d Z ddlZddlZddl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 	 ddlmZ dd	lmZ dd
lmZ ddlmZ  ej*                  d      Zd Z G d de      Z edd      Z G d de      Zd Z G d de      Z G d dee      Z G d de      Z  G d de e      Z!	 ddl"m#Z#  G d de e#      Z$	 dd l%m&Z&  G d! d"ee&      Z' G d# d$e      Z( G d% d&e(e      Z)	 dd'l*m+Z+  G d( d)e(e+      Z,	 dd*l*m-Z-  G d+ d,e(e-      Z.y# e$ r	 dxZxZZY w xY w# e$ r Y w xY w# e$ r dZ$Y vw xY w# e$ r dZ'Y pw xY w# e$ r dZ,Y Sw xY w# e$ r dZ.Y yw xY w)-aG  
Lightweight connection pooling for peewee.

In a multi-threaded application, up to `max_connections` will be opened. Each
thread (or, if using gevent, greenlet) will have it's own connection.

In a single-threaded application, only one connection will be created. It will
be continually recycled until either it exceeds the stale timeout or is closed
explicitly (using `.manual_close()`).

By default, all your application needs to do is ensure that connections are
closed when you are finished with them, and they will be returned to the pool.
For web applications, this typically means that at the beginning of a request,
you will open a connection, and when you return a response, you will close the
connection.

Simple Postgres pool example code:

    # Use the special postgresql extensions.
    from playhouse.pool import PooledPostgresqlExtDatabase

    db = PooledPostgresqlExtDatabase(
        'my_app',
        max_connections=32,
        stale_timeout=300,  # 5 minutes.
        user='postgres')

    class BaseModel(Model):
        class Meta:
            database = db

That's it!
    N)
namedtuple)chain)TRANSACTION_STATUS_IDLE)TRANSACTION_STATUS_INERROR)TRANSACTION_STATUS_UNKNOWN)TransactionStatus)MySQLDatabase)PostgresqlDatabase)SqliteDatabasezpeewee.poolc                 L    | !t        | t        t        f      st        |       S | S N)
isinstanceintfloat)vals    J/var/www/html/trade_iq/venv/lib/python3.12/site-packages/playhouse/pool.pymake_intr   >   s"    
z#U|<3xJ    c                       e Zd Zy)MaxConnectionsExceededN__name__
__module____qualname__ r   r   r   r   D   s    r   r   PoolConnection)	timestamp
connectionchecked_outc                       e Zd Zd Zy)	_sentinelc                      yNTr   )selfothers     r   __lt__z_sentinel.__lt__K   s    r   N)r   r   r   r&   r   r   r   r!   r!   J   s    r   r!   c                 B     t        j                          fd       }|S )Nc                 `    | j                   5   | g|i |cd d d        S # 1 sw Y   y xY wr   )
_pool_lock)r$   argskwargsfns      r   innerzlocked.<locals>.innerP   s1    __ 	-d,T,V,	- 	- 	-s   $-)	functoolswraps)r,   r-   s   ` r   lockedr0   O   s%    __R- - Lr   c                        e Zd Z	 	 d fd	Z	 	 d fd	Zd fd	Ze fd       Zd Zd Z	d Z
ed fd	       Zed	        Zed
        Zedd       Zed        Z xZS )PooledDatabasec                 0   t        |      | _        t        |      | _        t        |      | _        | j                  dk(  rt	        d      | _        t        j                         | _        g | _        i | _	        t        | _        t        t        | :  |fi | y Nr   inf)r   _max_connections_stale_timeout_wait_timeoutr   	threadingRLockr)   _connections_in_useidconn_keysuperr2   __init__)r$   databasemax_connectionsstale_timeouttimeoutr+   	__class__s         r   r@   zPooledDatabase.__init__X   s     ( 9&}5%g."!&uD#//+ 
  nd,X@@r   c                     t        t        | 
  |fi | |t        |      | _        |t        |      | _        |1t        |      | _        | j                  dk(  rt        d      | _        y y y r4   )r?   r2   initr   r6   r7   r8   r   )r$   rA   rB   rC   rD   connect_kwargsrE   s         r   rG   zPooledDatabase.initr   st    nd(D^D&$,_$=D!$"*="9D!)'!2D!!Q&%*5\" ' r   c                 n   | j                   st        t        |   |      S t	        j                         | j                   z   }|t	        j                         kD  r	 t        t        |   |      }|S t        d      # t
        $ r t	        j                  d       Y nw xY w|t	        j                         kD  r]H)Ng?z:Max connections exceeded, timed out attempting to connect.)r8   r?   r2   connecttimer   sleep)r$   reuse_if_openexpiresretrE   s       r   rJ   zPooledDatabase.connect~   s    !!6}EE))+ 2 22		#ND9-H 
$ &> ? 	?	 *  

3  		#s   A: :BBc                     	 	 t        j                  | j                        \  }}}|}| j                  |      }| j	                  |      rt
        j                  d|       d x}}nK| j                  r>| j                  |      r-t
        j                  d|       | j                  |d       d x}}nn|| j                  r-t        | j                        | j                  k\  rt        d      t        t         | G         }t%        j$                         }| j                  |      }t
        j                  d|       t'        ||t%        j$                               | j                  <   |S # t        $ r d x}}t
        j                  d       Y w xY w)NTzConnection %s was closed.z!Connection %s was stale, closing.z No connection available in pool.zExceeded maximum connections.zCreated new connection %s.)heapqheappopr;   r>   
_is_closedloggerdebugr7   	_is_stale_close
IndexErrorr6   lenr<   r   r?   r2   _connectrK   r   )r$   ts_c_connconnkeyrE   s         r   rZ   zPooledDatabase._connect   s^    %d.?.? @AvmmD) ??4( LL!<cB $$B((T^^B-?
 LL!DcJKKd+ $$B9 < <$$%)>)>>,-LMM79DB--%CLL5s;*2tTYY[ASE    T?@s   6E( ("FFc                 J    t        j                          |z
  | j                  kD  S r   )rK   r7   )r$   r   s     r   rV   zPooledDatabase._is_stale   s      		i'4+>+>>>r   c                      y)NFr   r$   r^   s     r   rS   zPooledDatabase._is_closed   s    r   c                      yr#   r   rb   s     r   
_can_reusezPooledDatabase._can_reuse   s    r   c                 0   | j                  |      }|rt        t        |   |       y || j                  v r| j                  j                  |      }| j                  rE| j                  |j                        r*t        j                  d|       t        t        |   |       y | j                  |      rLt        j                  d|       t        j                  | j                  |j                  t               |f       y t        j                  d|       y y )NzClosing stale connection %s.zReturning %s to pool.z
Closed %s.)r>   r?   r2   rW   r<   popr7   rV   r   rT   rU   rd   rQ   heappushr;   r!   )r$   r^   
close_connr_   	pool_connrE   s        r   rW   zPooledDatabase._close   s    mmD!.$.t4DLL ((-I""t~~i6I6I'J;SAnd248&4c:t00 ) 3 3Y[$GI \3/ !r   c                     | j                         ry| j                         }| j                  j                  | j	                  |      d       | j                          | j                  |d       y)zS
        Close the underlying connection without returning it to the pool.
        FNTrh   )	is_closedr   r<   rf   r>   closerW   rb   s     r   manual_closezPooledDatabase.manual_close   sW    
 >>   	t,d3

DT*r   c                 b    | j                   D ]  \  }}}| j                  |d        g | _         y NTrk   )r;   rW   )r$   r\   r^   s      r   
close_idlezPooledDatabase.close_idle   s7     ++ 	/JAq$KKK.	/r   c                     i }t        j                          |z
  }d}| j                  j                         D ]<  \  }}|j                  |k  r#| j	                  |j
                  d       |dz  }8|||<   > || _        |S )Nr   Trk      )rK   r<   itemsr   rW   r   )r$   agein_usecutoffnr_   ri   s          r   close_stalezPooledDatabase.close_stale   s     s""ll002 	(NC$$v-I00TBQ's	( r   c                    | j                          | j                  D ]  \  }}}| j                  |d        | j                  j	                         D ]  }| j                  |j
                  d       ! g | _        i | _        y rp   )rm   r;   rW   r<   valuesr   )r$   r\   r^   ri   s       r   	close_allzPooledDatabase.close_all   sy     	

++ 	/JAq$KKK.	/,,. 	?IKK	,,K>	?r   )   NN)NNNF)iX  )r   r   r   r@   rG   rJ   r0   rZ   rV   rS   rd   rW   rn   rq   ry   r|   __classcell__)rE   s   @r   r2   r2   W   s    CGA4 BF
2? ) )V?
 0 0  + +$     	 	r   r2   c                       e Zd Zd Zy)PooledMySQLDatabasec                 `    | j                   d   dk(  rd}nd}	  |j                  |  y#  Y yxY w)Nr      r   r~   FT)server_versionping)r$   r^   r*   s      r   rS   zPooledMySQLDatabase._is_closed  sA    q!Q&DD	DIIt 	s   ) -Nr   r   r   rS   r   r   r   r   r     s    
r   r   c                       e Zd Zd Zd Zy)_PooledPostgresqlDatabasec                     |j                   ry|j                         }|t        k(  ry|t        k7  r|j	                          yNTF)closedget_transaction_statusr   r   rollbackr$   r^   
txn_statuss      r   rS   z$_PooledPostgresqlDatabase._is_closed  s;    ;;002
3322MMOr   c                     |j                         }|t        k(  ry|t        k(  r|j                          y|t        k7  r|j                          yNFT)r   r   r   resetr   r   r   s      r   rd   z$_PooledPostgresqlDatabase._can_reuse'  sL    002
 3355JJL  22MMOr   Nr   r   r   rS   rd   r   r   r   r   r     s    	r   r   c                       e Zd Zy)PooledPostgresqlDatabaseNr   r   r   r   r   r   4      r   r   )PostgresqlExtDatabasec                       e Zd Zy)PooledPostgresqlExtDatabaseNr   r   r   r   r   r   :      r   r   )Psycopg3Databasec                       e Zd Zd Zd Zy)PooledPsycopg3Databasec                     |j                   ry|j                  j                  }|t        j                  k(  ry|t        j
                  k7  r|j                          yr   )r   pgconntransaction_statusr   UNKNOWNIDLEr   r   s      r   rS   z!PooledPsycopg3Database._is_closedD  sH    {{77J.6660555r   c                     |j                   j                  }|t        j                  k(  ry|t        j                  k(  r|j                          y|t        j                  k7  r|j                          yr   )r   r   r   r   INERRORr   r   r   r   s      r   rd   z!PooledPsycopg3Database._can_reuseO  s_    77J .6660888

  0555r   Nr   r   r   r   r   r   C  s    			r   r   c                       e Zd Zd Zy)_PooledSqliteDatabasec                 ,    	 |j                    y#  Y yxY wr   )total_changesrb   s     r   rS   z _PooledSqliteDatabase._is_closed`  s    	 	s    Nr   r   r   r   r   r   _  s    r   r   c                       e Zd Zy)PooledSqliteDatabaseNr   r   r   r   r   r   h  r   r   r   )SqliteExtDatabasec                       e Zd Zy)PooledSqliteExtDatabaseNr   r   r   r   r   r   n  r   r   r   )CSqliteExtDatabasec                       e Zd Zy)PooledCSqliteExtDatabaseNr   r   r   r   r   r   v  r   r   r   )/__doc__r.   rQ   loggingr9   rK   collectionsr   	itertoolsr   psycopg2.extensionsr   r   r   ImportError
psycopg.pqr   peeweer	   r
   r   	getLoggerrT   r   
ValueErrorr   r   objectr!   r0   r2   r   r   r   playhouse.postgres_extr   r   playhouse.psycopg3_extr   r   r   r   playhouse.sqlite_extr   r   r   r   r   r   r   <module>r      s   B      " .;>>
	, ! % !			=	) /Z . , /> ? 
sV sl.-  2	8:L 	'<&?AV "71A 8N 	0. 	#6"79J 
$7#8:L Q
  . *.. .&&.  		P  '"&'>  "!"*  #"#  $#$sj   D D) 5D4 E 2E E D&%D&)D10D14D>=D>E
EEEE%$E%