o
    Qkl[-                     @   s   d dl mZ 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Z
dZdZzeee W n ey<   eZY nw G d	d
 d
eZG dd deZe Zedd Zee_d dlmZmZ dddZee	_dd ZG dd de	ZG dd deZdS )    )absolute_import)unicode_literalsN)	ModelBase)Databasez2.0   pyformatc                   @   s   e Zd ZdZdS )ErrorzException that is the base class of all other error exceptions.
    You can use this to catch all errors with one single except statement.
    N)__name__
__module____qualname____doc__ r   r   X/var/www/Datamplify/venv/lib/python3.10/site-packages/sqlalchemy_clickhouse/connector.pyr      s    r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
ParamEscaperc                    sR   t |tr fdd| D S t |ttfr"t fdd|D S td|)Nc                    s   i | ]
\}}|  |qS r   escape_item).0kvselfr   r   
<dictcomp>#       z,ParamEscaper.escape_args.<locals>.<dictcomp>c                 3   s    | ]}  |V  qd S Nr   )r   xr   r   r   	<genexpr>%   s    z+ParamEscaper.escape_args.<locals>.<genexpr>zUnsupported param format: {})
isinstancedictitemslisttuple	Exceptionformat)r   
parametersr   r   r   escape_args!   s
   
zParamEscaper.escape_argsc                 C   s   |S r   r   r   itemr   r   r   escape_number)      zParamEscaper.escape_numberc                 C   s6   t |tr
|d}d|ddddddS )	Nutf-8z'{}'\z\\'z\'$z$$)r   bytesdecoder"   replacer%   r   r   r   escape_string,   s   

"zParamEscaper.escape_stringc                 C   sF   |d u rdS t |ttfr| |S t |tr| |S td|)NNULLzUnsupported object {})r   intfloatr'   
basestringr0   r!   r"   r%   r   r   r   r   5   s   


zParamEscaper.escape_itemN)r	   r
   r   r$   r'   r0   r   r   r   r   r   r       s
    	r   c                 C   s   dd l m  m} |drd}|dr#| |dd }||S |dr*d}|dr1d}|d	rD| |d
d }||S |d }t||sStd| t	|| S )Nr   EnumStringArray   FixedStringDateTimeNullable	   FieldzNo field class for %s)
infi.clickhouse_orm.fieldsclickhouse_ormfields
startswithcreate_ad_hoc_field
ArrayFieldNullableFieldhasattrNotImplementedErrorgetattr)clsdb_type
orm_fieldsinner_fieldnamer   r   r   rC   B   s"   







rC   )PY3string_typesFc                 C   sN   t rt|tr|d}| |}tj| j|||d}|jdkr%t	|j
|S )Nr)   )paramsdatastream   )rN   r   rO   encode_build_paramsrequestspostdb_urlstatus_coder!   text)r   rQ   settingsrR   rP   rr   r   r   _send`   s   



r]   c                  O   s   t | i |S r   )
Connection)argskwargsr   r   r   connectn   s   ra   c                       sB   e Zd ZdZd fdd	Zdd Zd	d
 Zdd Zdd Z  Z	S )r^   zb
        These objects are small stateless factories for cursors, which do all the real work.
    http://localhost:8123/NFc                    s:   t t| ||||| || _|| _|| _|| _|| _d S r   )superr^   __init__db_namerX   usernamepasswordreadonly)r   re   rX   rf   rg   rh   	__class__r   r   rd   u   s   
zConnection.__init__c                 C      d S r   r   r   r   r   r   close}   r(   zConnection.closec                 C   rk   r   r   r   r   r   r   commit   r(   zConnection.commitc                 C   s   t | S r   )Cursorr   r   r   r   cursor      zConnection.cursorc                 C   s   t d)NzTransactions are not supported)NotSupportedErrorr   r   r   r   rollback   rp   zConnection.rollback)rb   NNF)
r	   r
   r   r   rd   rl   rm   ro   rr   __classcell__r   r   ri   r   r^   q   s    r^   c                   @   s   e Zd ZdZdZdZdZdd Zdd Ze	d	d
 Z
e	dd Zdd Zd,ddZdd Zdd Zd-ddZdd Ze	dd Zejdd Zdd Zd-d d!Zd"d# ZeZd$d% Zd&d' Zd(d) Zd*d+ ZdS ).rn   zThese objects represent a database cursor, which is used to manage the context of a fetch
    operation.

    Cursors are not isolated, i.e., any changes done to the database by a cursor are immediately
    visible by other cursors or connections.
    r      r   c                 C   s   || _ |   d| _d S )Nrt   )_db_reset_state
_arraysize)r   databaser   r   r   rd      s   
zCursor.__init__c                 C   s*   d| _ d| _d| _| j| _d| _d| _dS )zMReset state about the previous query in preparation for running another queryNr   )_uuid_columns
_rownumber_STATE_NONE_state_datar   r   r   r   rv      s   
zCursor._reset_statec                 C      dS )z=By default, return -1 to indicate that this is not supported.r9   r   r   r   r   r   rowcount   s   zCursor.rowcountc                 C   s   | j du rg S dd | j D S )aG  This read-only attribute is a sequence of 7-item sequences.

        Each of these sequences contains information describing one result column:

        - name
        - type_code
        - display_size (None in current implementation)
        - internal_size (None in current implementation)
        - precision (None in current implementation)
        - scale (None in current implementation)
        - null_ok (always True in current implementation)

        The ``type_code`` can be interpreted by comparing it to the Type Objects specified in the
        section below.
        Nc              	   S   s&   g | ]}|d  |d dddddfqS )r   rt   NTr   )r   colr   r   r   
<listcomp>   s    z&Cursor.description.<locals>.<listcomp>)rz   r   r   r   r   description   s
   
zCursor.descriptionc                 C   rk   r   r   r   r   r   r   rl      r(   zCursor.closeNTc                 C   sr   |du s|s	|}n|t | }|   | j| _t | _|r1| jj	|d| jid}| 
| dS | j| dS )z=Prepare and execute a database operation (query or command). Nquery_idr[   )_escaperr$   rv   _STATE_RUNNINGr}   uuiduuid1ry   ru   select_process_responseraw)r   	operationr#   is_responsesqlresponser   r   r   execute   s   
zCursor.executec           
      C   s   g }t dt jt jB }||}|rC|dd }|d }|dd D ]}||t	|  q'd
|d|}	| j|	S |dd D ]
}| j||d	d
 qIdS )a  Prepare a database operation (query or command) and then execute it against all parameter
        sequences or mappings found in the sequence ``seq_of_parameters``.

        Only the final result set is retained.

        Return values are not defined.
        z|\s*((?:INSERT|REPLACE)\s.+\sVALUES?\s*)(\(\s*(?:%s|%\(.+\)s)\s*(?:,\s*(?:%s|%\(.+\)s)\s*)*\))(\s*(?:ON DUPLICATE.*)?);?\s*\Zrt   r   r   Nr9   z{} {};,F)r   )recompile
IGNORECASEDOTALLmatchgrouprstripappendr   r$   r"   joinru   r   r   )
r   r   seq_of_parametersvalues_listRE_INSERT_VALUESmq_prefixq_valuesr#   queryr   r   r   executemany   s    

zCursor.executemanyc                 C   s8   | j | jkr
td| jsdS |  jd7  _| jdS )z{Fetch the next row of a query result set, returning a single sequence, or ``None`` when
        no more data is available. No query yetNrt   r   )r}   r|   r!   r~   r{   popr   r   r   r   fetchone   s   zCursor.fetchonec                 C   sB   |du rd}g }t |D ]}|  }|du r |S || q|S )a2  Fetch the next set of rows of a query result, returning a sequence of sequences (e.g. a
        list of tuples). An empty sequence is returned when no more rows are available.

        The number of rows to fetch per call is specified by the parameter. If it is not given, the
        cursor's arraysize determines the number of rows to be fetched. The method should try to
        fetch as many rows as indicated by the size parameter. If this is not possible due to the
        specified number of rows not being available, fewer rows may be returned.
        Nrt   )ranger   r   )r   sizeresult_oner   r   r   	fetchmany   s   	zCursor.fetchmanyc                 C   s(   g }	 |   }|du r	 |S || q)zFetch all (remaining) rows of a query result, returning them as a sequence of sequences
        (e.g. a list of tuples).
        TN)r   r   )r   r   r   r   r   r   fetchall  s   
zCursor.fetchallc                 C   s   | j S )zThis read/write attribute specifies the number of rows to fetch at a time with
        :py:meth:`fetchmany`. It defaults to 1 meaning to fetch a single row at a time.
        rw   r   r   r   r   	arraysize  s   zCursor.arraysizec                 C   s
   || _ d S r   r   )r   valuer   r   r   r   $  s   
c                 C   r   zDoes nothing by defaultNr   )r   sizesr   r   r   setinputsizes(     zCursor.setinputsizesc                 C   r   r   r   )r   r   columnr   r   r   setoutputsize,  r   zCursor.setoutputsizec                 C   s   |   }|du r
t|S )zReturn the next row from the currently executing SQL statement using the same semantics
        as :py:meth:`fetchone`. A ``StopIteration`` exception is raised when the result set is
        exhausted.
        N)r   StopIteration)r   r   r   r   r   __next__0  s   zCursor.__next__c                 C   s   | S )zAReturn self to make cursors compatible to the iteration protocol.r   r   r   r   r   __iter__=  r   zCursor.__iter__c                 C   sd   | j | jkr
td| jd u r| j | jksJ dd S | jjdd| jid | j| _ d | _d | _d S )Nr   zQuery should be finishedzSELECT 1r   r   )r}   r|   ProgrammingErrorry   _STATE_FINISHEDru   r   r~   r   r   r   r   cancelA  s   

zCursor.cancelc                 C   rk   r   r   r   r   r   r   pollM  r(   zCursor.pollc                    sp   | j | jks
J dd}g }|D ] |s fdd jD }| fdd jD  q|| _|| _| j| _ dS )z; Update the internal state with the data from the response z(Should be running if processing responseNc                    s   g | ]
}| j | jfqS r   )_fieldsrJ   r   fr\   r   r   r   W  r   z,Cursor._process_response.<locals>.<listcomp>c                    s   g | ]}t  |qS r   )rH   r   r   r   r   r   X  s    )r}   r   r   r   r~   rz   r   )r   r   colsrQ   r   r   r   r   P  s   zCursor._process_response)NTr   )r	   r
   r   r   r|   r   r   rd   rv   propertyr   r   rl   r   r   r   r   r   r   setterr   r   r   nextr   r   r   r   r   r   r   r   rn      s:    







rn   )NF) 
__future__r   r   r   r   rV   infi.clickhouse_orm.modelsr   infi.clickhouse_orm.databaser   apilevelthreadsafety
paramstyler   objr4   	NameErrorstrr!   r   objectr   r   classmethodrC   sixrN   rO   r]   ra   r^   rn   r   r   r   r   <module>   s6   

