a
    i                     @   sL  U d Z ddlZddlZddlmZmZmZmZ ddlZddl	m	Z	 e
eZdaeej ed< e Zd!eeejddd	Zdd
ddZejd
ddZd"eee eedddZeee edddZd#eee ee dddZd$eee ee dddZd%eee ee dddZd&eee ee dddZG dd  d Z dS )'zs
Async database layer using aiomysql.

Provides connection pooling, query helpers, and proper resource management.
    N)OptionalAnyTupleList)config_pool
   )	pool_sizemax_overflowreturnc                    s  t 4 I dH  tdur8td tW  d  I dH  S | p@tj} zdtjtjtj	tj
tjtjd| ddtjddI dH atd|  d	tj  tW W  d  I dH  S  ty } ztd
|   W Y d}~n
d}~0 0 W d  I dH  q1 I dH s0    Y  dS )z
    Initialize the async database connection pool.

    Args:
        pool_size: Maximum pool size (default from config.MAX_CONNECTIONS)
        max_overflow: Additional connections beyond pool_size

    Returns:
        The connection pool
    NzPool already initialized   Ti  r   )hostportuserpassworddbZminsizemaxsize
autocommitZpool_recycleZechoconnect_timeoutz Database pool initialized: size=z, host=z$Failed to initialize database pool: )
_pool_lockr   loggerwarningr   MAX_CONNECTIONSaiomysqlZcreate_poolDB_HOSTDB_PORTDB_USERDB_PASSWORDDB_NAMEDEBUGinfo	Exceptionerror)r	   r
   e r$   //var/www/lichun.app/lichun/ws/database_async.pyinitialize_pool   s0    

r&   r   c                	      sh   t 4 I dH B tdur:t  t I dH  datd W d  I dH  qd1 I dH sZ0    Y  dS )z"Close the database connection poolNzDatabase pool closed)r   r   closewait_closedr   r    r$   r$   r$   r%   
close_poolB   s    r*   c                      s   t du rtdt  S )a  
    Get a connection from the pool.

    Usage:
        async with get_connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute("SELECT ...")

    Returns:
        Database connection (context manager)
    Nz<Database pool not initialized. Call initialize_pool() first.)r   RuntimeErroracquirer$   r$   r$   r%   get_connectionN   s    r-   T)queryparamscommitr   c              
      s   t du rtdt  4 I dH ~}| 4 I dH B}|| |I dH  |jW  d  I dH  W  d  I dH  S 1 I dH s0    Y  W d  I dH  q1 I dH s0    Y  dS )z
    Execute a query (INSERT, UPDATE, DELETE).

    Args:
        query: SQL query with %s placeholders
        params: Query parameters
        commit: Whether to commit (default True due to autocommit)

    Returns:
        Number of affected rows
    NDatabase pool not initialized)r   r+   r,   cursorexecuterowcount)r.   r/   r0   connr2   r$   r$   r%   execute_query`   s    r6   )r.   params_listr   c              
      s   t du rtdt  4 I dH ~}| 4 I dH B}|| |I dH  |jW  d  I dH  W  d  I dH  S 1 I dH s0    Y  W d  I dH  q1 I dH s0    Y  dS )z
    Execute a query multiple times with different parameters (batch insert).

    Args:
        query: SQL query with %s placeholders
        params_list: List of parameter tuples

    Returns:
        Total number of affected rows
    Nr1   )r   r+   r,   r2   executemanyr4   )r.   r7   r5   r2   r$   r$   r%   execute_manyy   s    r9   )r.   r/   r   c              
      s   t du rtdt  4 I dH }| 4 I dH J}|| |I dH  | I dH W  d  I dH  W  d  I dH  S 1 I dH s0    Y  W d  I dH  q1 I dH s0    Y  dS )z
    Fetch a single row.

    Args:
        query: SQL query with %s placeholders
        params: Query parameters

    Returns:
        Single row as tuple, or None if not found
    Nr1   )r   r+   r,   r2   r3   fetchoner.   r/   r5   r2   r$   r$   r%   	fetch_one   s    r<   c              
      s   t du rtdt  4 I dH }| 4 I dH J}|| |I dH  | I dH W  d  I dH  W  d  I dH  S 1 I dH s0    Y  W d  I dH  q1 I dH s0    Y  dS )z
    Fetch all rows.

    Args:
        query: SQL query with %s placeholders
        params: Query parameters

    Returns:
        List of rows as tuples
    Nr1   )r   r+   r,   r2   r3   fetchallr;   r$   r$   r%   	fetch_all   s    r>   c              
      s   t du rtdt  4 I dH }|tj4 I dH J}|| |I dH  | I dH W  d  I dH  W  d  I dH  S 1 I dH s0    Y  W d  I dH  q1 I dH s0    Y  dS )z
    Fetch a single row as dictionary.

    Args:
        query: SQL query with %s placeholders
        params: Query parameters

    Returns:
        Single row as dict, or None if not found
    Nr1   )r   r+   r,   r2   r   
DictCursorr3   r:   r;   r$   r$   r%   fetch_dict_one   s    r@   c              
      s   t du rtdt  4 I dH }|tj4 I dH J}|| |I dH  | I dH W  d  I dH  W  d  I dH  S 1 I dH s0    Y  W d  I dH  q1 I dH s0    Y  dS )z
    Fetch all rows as dictionaries.

    Args:
        query: SQL query with %s placeholders
        params: Query parameters

    Returns:
        List of rows as dicts
    Nr1   )r   r+   r,   r2   r   r?   r3   r=   r;   r$   r$   r%   fetch_dict_all   s    rA   c                   @   s0   e Zd ZdZdd ZejdddZdd Zd	S )
Transactiona<  
    Context manager for database transactions.

    Usage:
        async with Transaction() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute("UPDATE ...")
                await cursor.execute("INSERT ...")
            # Auto-commit on success, rollback on exception
    c                 C   s
   d | _ d S )N)r5   selfr$   r$   r%   __init__   s    zTransaction.__init__r'   c                    s6   t d u rtdt  I d H | _| j I d H  | jS )Nr1   )r   r+   r,   r5   beginrC   r$   r$   r%   
__aenter__   s
    zTransaction.__aenter__c                    sX   |d ur,| j  I d H  td|j  n| j  I d H  t| j I d H  d | _ d S )NzTransaction rolled back due to )r5   rollbackr   r   __name__r0   r   release)rD   exc_typeexc_valexc_tbr$   r$   r%   	__aexit__  s    zTransaction.__aexit__N)	rI   
__module____qualname____doc__rE   r   
ConnectionrG   rN   r$   r$   r$   r%   rB      s   rB   )Nr   )NT)N)N)N)N)!rQ   asyncior   typingr   r   r   r   loggingr   	getLoggerrI   r   r   ZPool__annotations__Lockr   intr&   r*   rR   r-   strboolr6   r9   r<   r>   dictr@   rA   rB   r$   r$   r$   r%   <module>   sl   
  .      