Ë
    ÒªïiŽ  ã                  ó  — U d Z ddlmZ ddlZddlmZ ddlmZm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e«      Zdad
ed<    ej,                  «       Zdd„Zdd„Zdd„Zedd„«       Zeddd„«       Zddd„Zddd„Zddd„Zy)u“  
utils/database.py â€” PostgreSQL connection pool + helpers
========================================================
Centralized, thread-safe Postgres access using a psycopg2
ThreadedConnectionPool. All routes / services should go
through `fetch_one`, `fetch_all`, or `execute` â€” never open
their own connections.

Lifecycle:
    init_pool()    â€“ called once at FastAPI startup (fail-fast).
    close_pool()   â€“ called once at FastAPI shutdown.
    get_conn()     â€“ context manager that checks out a connection
                     from the pool and returns it on exit.

Credentials are loaded from `.env` via `config.settings`.
Nothing is hardcoded.
é    )ÚannotationsN)Úcontextmanager)ÚAnyÚIterator)Úpool)ÚRealDictCursor)Úsettings)Ú
get_loggerz%pg_pool.ThreadedConnectionPool | NoneÚ_poolc                 óš  — t         5  t        �t        j                  d«       	 ddd«       yt        j
                  rt        j                  s<d} t        j                  | «       t        j                  rt        | «      ‚	 ddd«       yt        j                  dt        j
                  t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  «       	 t!        j"                  t        j                  t        j                  t        j
                  t        j                  t        j                  t        j                  t        j$                  t        j                  t        j&                  d¬«
      a	 t-        «       5 }|j/                  «       5 }|j1                  d«       |j3                  «        ddd«       ddd«       t        j                  d	«       ddd«       y# t(        j*                  $ r;}t        j                  d|«       t        j                  r‚ daY d}~ddd«       yd}~ww xY w# 1 sw Y   Œ€xY w# 1 sw Y   Œ„xY w# t4        $ r;}t        j                  d
|«       t7        «        t        j                  r‚ Y d}~Œ±d}~ww xY w# 1 sw Y   yxY w)z¿
    Create the connection pool. Call this exactly once at app startup.
    Fail-fast: if DB_FAIL_FAST is true and the pool can't be created,
    we re-raise so the app refuses to start.
    Nu(   DB pool already initialized â€” skippingz<Database is not configured. Check DB_HOST / DB_NAME in .env.uW   Initializing PostgreSQL pool â†’ host=%s port=%s db=%s user=%s min=%d max=%d sslmode=%sÚpeople_hub_candidate)
ÚminconnÚmaxconnÚhostÚportÚdbnameÚuserÚpasswordÚsslmodeÚconnect_timeoutÚapplication_namez$Failed to create PostgreSQL pool: %sz	SELECT 1;u/   PostgreSQL pool ready âœ“ (connection verified)z2PostgreSQL pool created but probe query failed: %s)Ú
_pool_lockr   ÚlogÚdebugr	   ÚDB_HOSTÚDB_NAMEÚerrorÚDB_FAIL_FASTÚRuntimeErrorÚinfoÚDB_PORTÚDB_USERÚDB_POOL_MINÚDB_POOL_MAXÚ
DB_SSLMODEÚpg_poolÚThreadedConnectionPoolÚDB_PASSWORDÚDB_CONNECT_TIMEOUTÚpsycopg2ÚErrorÚget_connÚcursorÚexecuteÚfetchoneÚ	ExceptionÚ
close_pool)ÚmsgÚexcÚconnÚcurs       úi/Users/priyanka/Documents/AI_Agent_Assessment/pepole_hub_candidate/people_hub_candidate/utils/database.pyÚ	init_poolr7   (   sú  € ö 
ÜÐÜ�I‰IÐ@ÔAØ÷ 
ˆô
 ×Ò¤x×'7Ò'7ØPˆCÜ�I‰I�cŒNÜ×$Ò$Ü" 3Ó'Ð'Ø÷ 
ˆô 	�‰ð'ä×Ñœh×.Ñ.´×0@Ñ0@Ä(×BRÑBRÜ× Ñ ¤(×"6Ñ"6¼×8KÑ8Kô		
ð	Ü×2Ñ2Ü ×,Ñ,Ü ×,Ñ,Ü×%Ñ%Ü×%Ñ%Ü×'Ñ'Ü×%Ñ%Ü!×-Ñ-Ü ×+Ñ+Ü (× ;Ñ ;Ø!7ôˆEð*
	Ü”˜tØ—[‘[”] cØ—K‘K Ô,Ø—L‘L”N÷ #÷ ô �H‰HÐFÔG÷] 
ˆøô@ �~‰~ò 	Ü�I‰IÐ<¸cÔBÜ×$Ò$ØØˆEÛ÷K 
ˆûð@	ú÷ #�]ú÷ �ûô
 ò 	Ü�I‰IÐJÈCÔPÜŒLÜ×$Ò$Øô %ûð	ú÷_ 
ˆús‘   ‡K­AKÂ	A>KÄBHÆ&
I:Æ0I.Ç"I"Ç#I.Ç+I:ÈIÈ$)IÉKÉIÉKÉ"I+É'I.É.I7	É3I:É:	J>Ê1J9Ê4KÊ9J>Ê>KËK
c                 ó  — t         5  t        �,	 t        j                  «        t        j	                  d«       daddd«       y# t
        $ r } t        j                  d| «       Y d} ~ Œ/d} ~ ww xY w# daw xY w# 1 sw Y   yxY w)z6Close all connections in the pool. Called at shutdown.NzPostgreSQL pool closedz!Error closing PostgreSQL pool: %s)r   r   Úcloseallr   r    r0   Úwarning)r3   s    r6   r1   r1   e   sm   € ö 
ÜÐðÜ—‘Ô Ü—‘Ð1Ô2ð �÷ 
ˆøô
 ò FÜ—‘Ð?À×EÑEûðFûð ‘ú÷ 
ˆús?   ‡A6�)A¸A6Á	A,ÁA'Á"A/Á'A,Á,A/Á/A3Á3A6Á6A?c                 ó   — t         d uS ©N)r   © ó    r6   Úis_readyr?   s   s   € Ü˜ÐÐr>   c               #  óR  K  — t         €t        d«      ‚t         j                  «       } 	 | –— | j                  s| j	                  «        t         j                  | «       y# t
        $ r" 	 | j                  «        ‚ # t
        $ r Y ‚ w xY ww xY w# t         j                  | «       w xY w­w)z{
    Check out a connection from the pool, return it on exit.
    Auto-commits on success and rolls back on exception.
    Nu7   DB pool not initialized â€” call init_pool() at startup)r   r   ÚgetconnÚclosedÚcommitr0   ÚrollbackÚputconn)r4   s    r6   r,   r,   y   s•   è ø€ ô €}ÜÐTÓUÐUä�=‰=‹?€DðØŠ
Ø�{Š{Ø�K‰KŒMô 	�‰�dÕøô ò ð	Ø�M‰MŒOð 	øô ò 	ØØð	úðûô 	�‰�dÕüsL   ‚&B'© A Á	B'Á	B
Á)A:Á9B
Á:	BÂB
ÂBÂB
Â
B ÂB$Â$B'c              #  ó´   K  — t        «       5 }| rt        nd}|j                  |¬«      5 }|–— ddd«       ddd«       y# 1 sw Y   ŒxY w# 1 sw Y   yxY w­w)zo
    Convenience: get_conn() + cursor() in one go.
    Returns dict-like rows by default (RealDictCursor).
    N)Úcursor_factory)r,   r   r-   )Ú	dict_rowsr4   rG   r5   s       r6   Ú
get_cursorrI   ‘   sG   è ø€ ô 
Œ�tÙ+4�¸$ˆØ�[‰[¨ˆ[Ô7¸3ØŠI÷ 8÷ 
ˆç7Ð7ú÷ 
ˆüs1   ‚A�AªA ¯A·	AÁ A		ÁAÁAÁAc                ó¬   — t        «       5 }|j                  | |xs d«       |j                  «       }|rt        |«      ndcddd«       S # 1 sw Y   yxY w)z7Run SELECT and return the first row as a dict, or None.r=   N)rI   r.   r/   Údict)ÚsqlÚparamsr5   Úrows       r6   Ú	fetch_onerO   Ÿ   s;   € ä	Œ˜Ø�‰�C˜š 2Ô&Ø�l‰l‹nˆÙŒt�CŒy T÷ 
�Šús   ‹5A
Á
Ac                óÊ   — t        «       5 }|j                  | |xs d«       |j                  «       }|D �cg c]  }t        |«      ‘Œ c}cddd«       S c c}w # 1 sw Y   yxY w)z2Run SELECT and return all rows as a list of dicts.r=   N)rI   r.   ÚfetchallrK   )rL   rM   r5   ÚrowsÚrs        r6   Ú	fetch_allrT   §   sP   € ä	Œ˜Ø�‰�C˜š 2Ô&Ø�|‰|‹~ˆÙ!%Ó&¡˜A”�Q• Ñ&÷ 
‰ùò '÷ 
ˆús   ‹+A¶AÁAÁAÁA"c                óŠ   — t        d¬«      5 }|j                  | |xs d«       |j                  cddd«       S # 1 sw Y   yxY w)z5Run INSERT / UPDATE / DELETE and return the rowcount.F)rH   r=   N)rI   r.   Úrowcount)rL   rM   r5   s      r6   r.   r.   ¯   s1   € ä	˜eÕ	$¨Ø�‰�C˜š 2Ô&Ø�|‰|÷ 
%×	$Ò	$ús	   �"9¹A)ÚreturnÚNone)rW   Úbool)rW   z(Iterator[psycopg2.extensions.connection])T)rH   rY   rW   z$Iterator[psycopg2.extensions.cursor]r<   )rL   ÚstrrM   útuple | dict | NonerW   zdict | None)rL   rZ   rM   r[   rW   z
list[dict])rL   rZ   rM   r[   rW   Úint) Ú__doc__Ú
__future__r   Ú	threadingÚ
contextlibr   Útypingr   r   r*   r   r&   Úpsycopg2.extrasr   Úconfigr	   Úutils.loggerr
   Ú__name__r   r   Ú__annotations__ÚLockr   r7   r1   r?   r,   rI   rO   rT   r.   r=   r>   r6   Ú<module>rh      s“   ðòõ" #ã Ý %ß  ã Ý $Ý *å Ý #á�Ó€ð 04€Ð,Ó 3ØˆY�^‰^Ó€
ó
:ózóð òó ðð. óó ðô*ô'õr>   