
    Vi$3                        S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	   SSK
Jr  SSK
Jr  SSK
Jr   SSKJr  SS	KJr  SS
KJr  SSKJr  \R*                  " S5      rS r " S S\5      r\" SS5      r " S S\5      rS r " S S\5      r " S S\\5      r " S S\5      r  " S S\ \5      r! SSK"J#r#   " S S\ \#5      r$ SS K%J&r&   " S! S"\\&5      r' " S# S$\5      r( " S% S&\(\5      r) SS'K*J+r+   " S( S)\(\+5      r, SS*K*J-r-   " S+ S,\(\-5      r.g! \ a	    S=r=rr Nf = f! \ a     Nf = f! \ a    Sr$ Nyf = f! \ a    Sr' Ntf = f! \ a    Sr, NXf = f! \ a    Sr. gf = f)-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                 X    U b&  [        U [        [        45      (       d  [        U 5      $ U $ N)
isinstanceintfloat)vals    a/home/james-whalen/.local/share/pipx/venvs/semgrep/lib/python3.13/site-packages/playhouse/pool.pymake_intr   >   s%    
z#U|<<3xJ    c                       \ rS rSrSrg)MaxConnectionsExceededD    N__name__
__module____qualname____firstlineno____static_attributes__r   r   r   r   r   D   s    $r   r   PoolConnection)	timestamp
connectionchecked_outc                       \ rS rSrS rSrg)	_sentinelJ   c                     gNTr   )selfothers     r   __lt___sentinel.__lt__K   s    r   r   N)r   r   r   r   r*   r   r   r   r   r$   r$   J   s    r   r$   c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )Nc                 j   > U R                      T" U /UQ70 UD6sS S S 5        $ ! , (       d  f       g = fr   )
_pool_lock)r(   argskwargsfns      r   innerlocked.<locals>.innerP   s&    __d,T,V, __s   $
2)	functoolswraps)r1   r2   s   ` r   lockedr6   O   s%    __R- - Lr   c                      ^  \ rS rSr  SU 4S jjr  SU 4S jjrSU 4S jjr\U 4S j5       rS r	S r
S r\SU 4S	 jj5       r\S
 5       r\S 5       r\SS j5       r\S 5       rSrU =r$ )PooledDatabaseW   c                 6  > [        U5      U l        [        U5      U l        [        U5      U l        U R                  S:X  a  [	        S5      U l        [
        R                  " 5       U l        / U l        0 U l	        [        U l        [        [        U ]:  " U40 UD6  g Nr   inf)r   _max_connections_stale_timeout_wait_timeoutr   	threadingRLockr.   _connections_in_useidconn_keysuperr8   __init__)r(   databasemax_connectionsstale_timeouttimeoutr0   	__class__s         r   rG   PooledDatabase.__init__X   s     ( 9&}5%g."!&uD#//+ 
  nd,X@@r   c                    > [         [        U ]
  " U40 UD6  Ub  [        U5      U l        Ub  [        U5      U l        Ub2  [        U5      U l        U R                  S:X  a  [        S5      U l        g g g r;   )rF   r8   initr   r=   r>   r?   r   )r(   rH   rI   rJ   rK   connect_kwargsrL   s         r   rO   PooledDatabase.initr   st    nd(D^D&$,_$=D!$"*="9D!)'!2D!!Q&%*5\" ' r   c                   > U R                   (       d  [        [        U ]  U5      $ [        R                  " 5       U R                   -   nU[        R                  " 5       :  a   [        [        U ]  U5      nU$ [        S5      e! [
         a    [        R                  " S5         Of = fU[        R                  " 5       :  a  Mb  NM)Ng?z:Max connections exceeded, timed out attempting to connect.)r?   rF   r8   connecttimer   sleep)r(   reuse_if_openexpiresretrL   s       r   rS   PooledDatabase.connect~   s    !!6}EE))+ 2 22		#ND9-H 
$ &> ? 	?	 *  

3  		#s   "B  B%$B%c                 N  >   [         R                  " U R                  5      u  pnUnU R                  U5      nU R	                  U5      (       a  [
        R                  SU5        S =pOTU R                  (       aB  U R                  U5      (       a,  [
        R                  SU5        U R                  US5        S =pOOM  Uc  U R                  (       a.  [        U R                  5      U R                  :  a  [        S5      e[        [         U ]G  5       n[$        R$                  " 5       nU R                  U5      n[
        R                  SU5        ['        X[$        R$                  " 5       5      U R                  W'   U$ ! [         a    S =p[
        R                  S5         M  f = f)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heappoprB   rE   
_is_closedloggerdebugr>   	_is_stale_close
IndexErrorr=   lenrC   r   rF   r8   _connectrT   r   )r(   ts_c_connconnkeyrL   s         r   rd   PooledDatabase._connect   s^    %d.?.? @vmmD) ??4(( LL!<cB $$B((T^^B-?-?
 LL!DcJKKd+ $$B9 < <$$%)>)>>,-LMM79DB--%CLL5s;*2TYY[ASE    ?@s   6E> >"F$#F$c                 L    [         R                   " 5       U-
  U R                  :  $ r   )rT   r>   )r(   r    s     r   r`   PooledDatabase._is_stale   s      		i'4+>+>>>r   c                     g)NFr   r(   rh   s     r   r]   PooledDatabase._is_closed   s    r   c                     gr'   r   rn   s     r   
_can_reusePooledDatabase._can_reuse   s    r   c                 \  > U R                  U5      nU(       a  [        [        U ]  U5        g X0R                  ;   a  U R                  R                  U5      nU R                  (       aJ  U R                  UR                  5      (       a*  [        R                  SU5        [        [        U ]  U5        g U R                  U5      (       aM  [        R                  SU5        [        R                  " U R                  UR                  [        5       U45        g [        R                  SU5        g g )NzClosing stale connection %s.zReturning %s to pool.z
Closed %s.)rE   rF   r8   ra   rC   popr>   r`   r    r^   r_   rq   r[   heappushrB   r$   )r(   rh   
close_connri   	pool_connrL   s        r   ra   PooledDatabase._close   s    mmD!.$.t4LL ((-I""t~~i6I6I'J'J;SAnd248&&4c:t00 ) 3 3Y[$GI \3/ !r   c                     U R                  5       (       a  gU R                  5       nU R                  R                  U R	                  U5      S5        U R                  5         U R                  USS9  g)zC
Close the underlying connection without returning it to the pool.
FNTrv   )	is_closedr!   rC   rt   rE   closera   rn   s     r   manual_closePooledDatabase.manual_close   sZ    
 >>   	t,d3

DT*r   c                 ^    U R                    H  u    pU R                  USS9  M     / U l         g NTrz   )rB   ra   )r(   rf   rh   s      r   
close_idlePooledDatabase.close_idle   s0     ++JAqKKK. ,r   c                     0 n[         R                   " 5       U-
  nSnU R                  R                  5        H:  u  pVUR                  U:  a!  U R	                  UR
                  SS9  US-  nM6  XbU'   M<     X l        U$ )Nr   Trz      )rT   rC   itemsr"   ra   r!   )r(   agein_usecutoffnri   rw   s          r   close_stalePooledDatabase.close_stale   sw     s""ll002NC$$v-I00TBQ's 3 r   c                    U R                  5         U R                   H  u    pU R                  USS9  M     U R                  R	                  5        H  nU R                  UR
                  SS9  M     / U l        0 U l        g r   )r|   rB   ra   rC   valuesr!   )r(   rf   rh   rw   s       r   	close_allPooledDatabase.close_all   sm     	

++JAqKKK. ,,,.IKK	,,K> /r   )rB   rC   r=   r.   r>   r?   rE   )   NN)NNNF)iX  )r   r   r   r   rG   rO   rS   r6   rd   r`   r]   rq   ra   r}   r   r   r   r   __classcell__)rL   s   @r   r8   r8   W   s    CGA4 BF
2? ) )V?
 0 0  + +$     	 	r   r8   c                       \ rS rSrS rSrg)PooledMySQLDatabasei  c                 b    U R                   S   S:X  a  SnOSn UR                  " U6   g!    g= f)Nr      r   r   FT)server_versionping)r(   rh   r/   s      r   r]   PooledMySQLDatabase._is_closed  s?    q!Q&DD	IIt 	s   * .r   Nr   r   r   r   r]   r   r   r   r   r   r     s    
r   r   c                        \ rS rSrS rS rSrg)_PooledPostgresqlDatabasei  c                     UR                   (       a  gUR                  5       nU[        :X  a  gU[        :w  a  UR	                  5         gNTF)closedget_transaction_statusr   r   rollbackr(   rh   
txn_statuss      r   r]   $_PooledPostgresqlDatabase._is_closed  s;    ;;002
3322MMOr   c                     UR                  5       nU[        :X  a  gU[        :X  a  UR                  5         gU[        :w  a  UR                  5         gNFT)r   r   r   resetr   r   r   s      r   rq   $_PooledPostgresqlDatabase._can_reuse'  sL    002
 3355JJL  22MMOr   r   Nr   r   r   r   r]   rq   r   r   r   r   r   r     s    	r   r   c                       \ rS rSrSrg)PooledPostgresqlDatabasei4  r   Nr   r   r   r   r   r   4      r   r   )PostgresqlExtDatabasec                       \ rS rSrSrg)PooledPostgresqlExtDatabasei:  r   Nr   r   r   r   r   r   :      r   r   )Psycopg3Databasec                        \ rS rSrS rS rSrg)PooledPsycopg3DatabaseiC  c                     UR                   (       a  gUR                  R                  nU[        R                  :X  a  gU[        R
                  :w  a  UR                  5         gr   )r   pgconntransaction_statusr   UNKNOWNIDLEr   r   s      r   r]   !PooledPsycopg3Database._is_closedD  sH    {{77J.6660555r   c                     UR                   R                  nU[        R                  :X  a  gU[        R                  :X  a  UR                  5         gU[        R                  :w  a  UR                  5         gr   )r   r   r   r   INERRORr   r   r   r   s      r   rq   !PooledPsycopg3Database._can_reuseO  s_    77J .6660888

  0555r   r   Nr   r   r   r   r   r   C  s    			r   r   c                       \ rS rSrS rSrg)_PooledSqliteDatabasei_  c                 ,     UR                     g!    g= fr   )total_changesrn   s     r   r]    _PooledSqliteDatabase._is_closed`  s    	 	s    r   Nr   r   r   r   r   r   _  s    r   r   c                       \ rS rSrSrg)PooledSqliteDatabaseih  r   Nr   r   r   r   r   r   h  r   r   r   )SqliteExtDatabasec                       \ rS rSrSrg)PooledSqliteExtDatabasein  r   Nr   r   r   r   r   r   n  r   r   r   )CSqliteExtDatabasec                       \ rS rSrSrg)PooledCSqliteExtDatabaseiv  r   Nr   r   r   r   r   r   v  r   r   r   )/__doc__r4   r[   loggingr@   rT   collectionsr   	itertoolsr   psycopg2.extensionsr   r   r   ImportError
psycopg.pqr   peeweer	   r
   r   	getLoggerr^   r   
ValueErrorr   r   objectr$   r6   r8   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D6 E 2E E  D'&D'*D32D36E EEEEE E+*E+