o
    i2*                     @   s  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 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eZdd ZG dd deZG dd deZG dd deZ dS )    )config)core)	COMPONENT)
get_logger)ArgumentError)get_argument_value)tracer   )Pin)_SPAN_MEASURED_KEY)	SPAN_KIND)SpanKind)	SpanTypes   )TracedConnection)TracedCursor)ext_service)	iswrappedc                   C   s   dS )N  r   r   r   O/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/contrib/dbapi_async.pyget_version   s   r   c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )TracedAsyncCursorc                    s   | j  I d H  | S N)__wrapped__
__aenter__selfr   r   r   r      s   zTracedAsyncCursor.__aenter__c                 C   s
   | j  S r   )r   	__aiter__r   r   r   r   r   %   s   
zTracedAsyncCursor.__aiter__c                       | j |||I d H S r   r   	__aexit__r   exc_typeexc_valexc_tbr   r   r   r!   (      zTracedAsyncCursor.__aexit__c              
      s6  t | }|r| s||i |I dH S || jk}	tj|t|| j|tj	dh}
|	r2|

td |
|j |
| |
t| jj |
ttj td||| jj|f |rst| jj d| j|
||fj}|rs|j\}
}}z||i |I dH W | |
 W  d   S | |
 w 1 sw   Y  dS )a  
        Internal function to trace the call to the underlying cursor method
        :param method: The callable to be wrapped
        :param name: The name of the resulting span.
        :param resource: The sql query. Sql queries are obfuscated on the agent side.
        :param extra_tags: A dict of tags to store into the span's meta
        :param dbm_propagator: _DBM_Propagator, prepends dbm comments to sql statements
        :param args: The args that will be passed as positional args to the wrapped method
        :param kwargs: The args that will be passed as kwargs to the wrapped method
        :return: The result of the wrapped method invocation
        N)serviceresource	span_typer   db_query_checkz.execute)r
   get_fromenabled_self_datadog_namer   tracer   _self_configr   SQL
set_metricr   set_tagstags_set_tag_strr   integration_namer   r   CLIENTr   dispatchdispatch_with_resultsresultvalue_set_post_execute_tags)r   methodnamer(   
extra_tagsdbm_propagatorargskwargspinmeasuredsr9   r   r   r   _trace_method.   s<   



 zTracedAsyncCursor._trace_methodc                    s<   || _ | j| jj| j|ddi| j|g|R i |I dH S )z#Wraps the cursor.executemany methodzsql.executemanytrueN)_self_last_execute_operationrE   r   executemanyr-   _self_dbm_propagatorr   queryr@   rA   r   r   r   rH   a   s   zTracedAsyncCursor.executemanyc                    s8   || _ | j| jj| j|i | j|g|R i |I dH S )zWraps the cursor.execute methodN)rG   rE   r   executer-   rI   rJ   r   r   r   rL   t   s   zTracedAsyncCursor.executeN)	__name__
__module____qualname__r   r   r!   rE   rH   rL   r   r   r   r   r      s    3r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	FetchTracedAsyncCursorz"FetchTracedAsyncCursor for psycopgc                    <   d | jd}| j| jj|| ji dg|R i |I dH S )z Wraps the cursor.fetchone method{}.{}fetchoneN)formatr-   rE   r   rS   rG   r   r@   rA   	span_namer   r   r   rS         zFetchTracedAsyncCursor.fetchonec                    rQ   )z Wraps the cursor.fetchall methodrR   fetchallN)rT   r-   rE   r   rX   rG   rU   r   r   r   rX      rW   zFetchTracedAsyncCursor.fetchallc                    s   d | jd}d}z|t||ddi}W n ty-   t| jdd}|r)||ini }Y nw | j| jj|| j|dg|R i |I dH S )z!Wraps the cursor.fetchmany methodrR   	fetchmanyzdb.fetch.sizer   size	arraysizeN)	rT   r-   r   r   getattrr   rE   rY   rG   )r   r@   rA   rV   size_tag_keyr>   default_array_sizer   r   r   rY      s    z FetchTracedAsyncCursor.fetchmanyN)rM   rN   rO   __doc__rS   rX   rY   r   r   r   r   rP      s
    rP   c                       sN   e Zd Zdejdf fdd	Zdd Zdd Zdd	 Zd
d Z	dd Z
  ZS )TracedAsyncConnectionNc                    s,   |s	|j rtnt}tt| |||| d S r   )trace_fetch_methodsrP   r   superr`   __init__)r   connrB   cfg
cursor_cls	__class__r   r   rc      s   zTracedAsyncConnection.__init__c                    s~   | j  I dH }t|dr|| j u r| S td |S t|dr8t|r'|S t| }|s0|S | ||| j	S td |S )a  Context management is not defined by the dbapi spec.

        This means unfortunately that the database clients each define their own
        implementations.

        The ones we know about are:

        - mysqlclient<2.0 which returns a cursor instance. >=2.0 returns a
          connection instance.
        - psycopg returns a connection.
        - pyodbc returns a connection.
        - pymysql doesn't implement it.
        - sqlite3 returns the connection.
        Ncursorz{Unexpected object type returned from __wrapped__.__aenter__().Expected a wrapped instance, but received a different object.rL   )
r   r   hasattrlogwarningr   r
   r+   _self_cursor_clsr/   )r   rrB   r   r   r   r      s(   



z TracedAsyncConnection.__aenter__c                    r   r   r    r"   r   r   r   r!      r&   zTracedAsyncConnection.__aexit__c                    s   t | }|r| s||i |I d H S tj|t|| jd,}|t| jj	 |t
tj ||j || ||i |I d H W  d    S 1 sPw   Y  d S )N)r'   )r
   r+   r,   r   r.   r   r/   r4   r   r5   r   r   r6   r2   r3   )r   r<   r=   r>   r@   rA   rB   rD   r   r   r   rE      s   

$z#TracedAsyncConnection._trace_methodc                    6   d | jd}| j| jj|i g|R i |I d H S )NrR   commit)rT   r-   rE   r   rp   rU   r   r   r   rp         &zTracedAsyncConnection.commitc                    ro   )NrR   rollback)rT   r-   rE   r   rr   rU   r   r   r   rr      rq   zTracedAsyncConnection.rollback)rM   rN   rO   r   dbapi2rc   r   r!   rE   rp   rr   __classcell__r   r   rg   r   r`      s    2r`   N)!ddtracer   ddtrace.internalr   ddtrace.internal.constantsr   ddtrace.internal.loggerr   ddtrace.internal.utilsr   r   ddtrace.tracer   
_trace.pinr
   	constantsr   r   extr   r   dbapir   r   internal.trace_utilsr   r   rM   rk   r   r   rP   r`   r   r   r   r   <module>   s*    k#