o
    ޭh                     @  s   d dl m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m	Z	 d dl
mZ d dlmZ er@d dlmZ eee	f ZG d	d
 d
Ze ZdS )    )annotationsN)
ContextVar)copy)TYPE_CHECKINGAny)expand_db_url)ConfigurationError)BaseDBAsyncClientc                   @  s   e Zd ZU ejdi dZded< d=ddZd>ddZe	d?ddZ
d@ddZdAddZd@ddZd=ddZdBddZdCd#d$Zd=d%d&ZdDd(d)ZdDd*d+ZdEd-d.ZdFd0d1ZdGd3d4ZdHd6d7ZdIdJd:d;Zd<S )KConnectionHandler_conn_storage)defaultz(ContextVar[dict[str, BaseDBAsyncClient]]returnNonec                 C  s   d| _ d| _dS )z(Unified connection management interface.NF)
_db_config
_create_dbself r   X/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/tortoise/connection.py__init__   s   
zConnectionHandler.__init__	db_configDBConfigType	create_dbboolc                   s8   | j d u r
|| _ n| j | || _|  I d H  d S N)r   updater   _init_connections)r   r   r   r   r   r   _init   s   
zConnectionHandler._initc                 C  s   | j du r	td| j S )aL  
        Return the DB config.

        This is the same config passed to the
        :meth:`Tortoise.init<tortoise.Tortoise.init>` method while initialization.

        :raises ConfigurationError:
            If this property is accessed before calling the
            :meth:`Tortoise.init<tortoise.Tortoise.init>` method.
        NzDB configuration not initialised. Make sure to call Tortoise.init with a valid configuration before attempting to create connections.)r   r   r   r   r   r   r   %   s
   
zConnectionHandler.db_configdict[str, BaseDBAsyncClient]c                 C  s
   | j  S r   )r   getr   r   r   r   _get_storage9   s   
zConnectionHandler._get_storagenew_storagecontextvars.Tokenc                 C  s   | j |S r   )r   set)r   r!   r   r   r   _set_storage<   s   zConnectionHandler._set_storagec                 C  s   t |  S r   )r   r    r   r   r   r   _copy_storage@   s   zConnectionHandler._copy_storagec                 C  s   |     d S r   )r    clearr   r   r   r   _clear_storageC   s   z ConnectionHandler._clear_storagedb_infodicttype[BaseDBAsyncClient]c                 C  s\   | dd}t|}zt|dr||}W |S |j}W |S  ty-   td| dw )Nengine get_client_classzBackend for engine "z" does not implement db client)r   	importlibimport_modulehasattrr-   client_classAttributeErrorr   )r   r(   
engine_strengine_moduler1   r   r   r   _discover_client_classF   s   


z(ConnectionHandler._discover_client_class
conn_aliasstr
str | dictc                 C  s,   z| j | W S  ty   td| dw )Nz%Unable to get db settings for alias 'zD'. Please check if the config dict contains this alias and try again)r   KeyErrorr   r   r6   r   r   r   _get_db_infoU   s   
zConnectionHandler._get_db_infoc                   s0   | j D ]}| |}| jr| I d H  qd S r   )r   r   r   	db_create)r   alias
connectionr   r   r   r   ^   s   

z#ConnectionHandler._init_connectionsr	   c                 C  sR   |  |}t|trt|}| |}|d  }|d|i |di |}|S )Ncredentialsconnection_namer   )r;   
isinstancer7   r   r5   r   r   )r   r6   r(   r1   	db_paramsr>   r   r   r   _create_connectiond   s   


z$ConnectionHandler._create_connectionc                 C  s<   |   }z|| W S  ty   | |}|||< | Y S w )a  
        Return the connection object for the given alias, creating it if needed.

        Used for accessing the low-level connection object
        (:class:`BaseDBAsyncClient<tortoise.backends.base.client.BaseDBAsyncClient>`) for the
        given alias.

        :param conn_alias: The alias for which the connection has to be fetched

        :raises ConfigurationError: If the connection alias does not exist.
        )r    r9   rC   )r   r6   storager>   r   r   r   r   n   s   

zConnectionHandler.getconn_objc                 C  s   |   }|||< | j|S )a&  
        Sets the given alias to the provided connection object.

        :param conn_alias: The alias to set the connection for.
        :param conn_obj: The connection object that needs to be set for this alias.

        .. note::
            This method copies the storage from the `current context`, updates the
            ``conn_alias`` with the provided ``conn_obj`` and sets the updated storage
            in a `new context` and therefore returns a ``contextvars.Token`` in order to restore
            the original context storage.
        )r%   r   r#   )r   r6   rE   storage_copyr   r   r   r#      s   zConnectionHandler.setBaseDBAsyncClient | Nonec                 C  s   |   |dS )ay  
        Discards the given alias from the storage in the `current context`.

        :param conn_alias: The alias for which the connection object should be discarded.

        .. important::
            Make sure to have called ``conn.close()`` for the provided alias before calling
            this method else there would be a connection leak (dangling connection).
        N)r    popr:   r   r   r   discard   s   
zConnectionHandler.discardtokenc                 C  sB   |   }| j| |   }| D ]\}}||vr|||< qdS )aB  
        Reset the underlying storage to the previous context state.

        Resets the storage state to the `context` associated with the provided token. After
        resetting storage state, any additional `connections` created in the `old context` are
        copied into the `current context`.

        :param token:
            The token corresponding to the `context` to which the storage state has to
            be reset. Typically, this token is obtained by calling the
            :meth:`set<tortoise.connection.ConnectionHandler.set>` method of this class.
        N)r    r   resetitems)r   rJ   current_storageprev_storager=   connr   r   r   rK      s   zConnectionHandler.resetlist[BaseDBAsyncClient]c                   s    fdd j D S )zOReturns a list of connection objects from the storage in the `current context`.c                   s   g | ]}  |qS r   )r   ).0r=   r   r   r   
<listcomp>   s    z)ConnectionHandler.all.<locals>.<listcomp>)r   r   r   r   r   all   s   zConnectionHandler.allTrI   c                   sF   dd |   D }tj| I dH  |r| jD ]	}| | qdS dS )a  
        Closes all connections in the storage in the `current context`.

        All closed connections will be removed from the storage by default.

        :param discard:
            If ``False``, all connection objects are closed but `retained` in the storage.
        c                 S  s   g | ]}|  qS r   )close)rQ   rO   r   r   r   rR      s    z/ConnectionHandler.close_all.<locals>.<listcomp>N)rS   asynciogatherr   rI   )r   rI   tasksr=   r   r   r   	close_all   s   	
zConnectionHandler.close_allN)r   r   )r   r   r   r   r   r   )r   r   )r   r   )r!   r   r   r"   )r(   r)   r   r*   )r6   r7   r   r8   )r6   r7   r   r	   )r6   r7   rE   r	   r   r"   )r6   r7   r   rG   )rJ   r"   r   r   )r   rP   )T)rI   r   r   r   )__name__
__module____qualname__contextvarsr   r   __annotations__r   r   propertyr   r    r$   r%   r'   r5   r;   r   rC   r   r#   rI   rK   rS   rX   r   r   r   r   r
      s,   
 








	






r
   )
__future__r   rU   r\   r.   r   r   typingr   r   'tortoise.backends.base.config_generatorr   tortoise.exceptionsr   tortoise.backends.base.clientr	   r)   r7   r   r
   connectionsr   r   r   r   <module>   s     
9