U
    d/e)                     @   sV   d dl mZ d dlmZ ddlmZ ddlmZmZm	Z	 eddZ
G d	d
 d
eZdS )    )
namedtuple)islice   )Error   )InterfaceErrorOperationalErrorProgrammingErrorColumnzAname type_code display_size internal_size precision scale null_okc                       s  e Zd ZG dd deZe Z fddZdd Zd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dd Zd?d d!Zed"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd@d1d2Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"  Z#S )ACursorc                   @   s   e Zd Zed\ZZZZdS )zCursor.States   N)__name__
__module____qualname__rangeNONERUNNINGFINISHEDCURSOR_CLOSED r   r   B/tmp/pip-unpacked-wheel-mds_o03w/clickhouse_driver/dbapi/cursor.pyStates   s   r   c                    s2   || _ || _|   d| _d | _tt|   d S )Nr   )_client_connection_reset_state	arraysize_columns_with_typessuperr   __init__)selfclient
connection	__class__r   r   r      s    zCursor.__init__c                 C   s   | j | jjk}dt| |S )Nz(<cursor object at 0x{0:x}; closed: {1:}>)_state_statesr   formatid)r   Z	is_closedr   r   r   __repr__'   s
     zCursor.__repr__c                 c   s    |   }|d krd S |V  q d S N)fetchone)r   Zoner   r   r   __iter__.   s    zCursor.__iter__c                 C   s   | S r)   r   r   r   r   r   	__enter__6   s    zCursor.__enter__c                 C   s   |    d S r)   )close)r   exc_typeexc_valexc_tbr   r   r   __exit__9   s    zCursor.__exit__c                 C   s:   | j | jjkrd S | jpg }| jp$g }dd t||D S )Nc              
   S   s$   g | ]\}}t ||d d d d dqS )NT)r
   ).0nameZ	type_coder   r   r   
<listcomp>D   s   z&Cursor.description.<locals>.<listcomp>)r$   r%   r   _columns_typeszip)r   columnstypesr   r   r   description<   s    

zCursor.descriptionc                 C   s   | j S )zQ
        :return: the number of rows that the last .execute*() produced.
        )	_rowcountr,   r   r   r   rowcountI   s    zCursor.rowcountc                 C   s@   | j   | jj| _z| jj|  W n tk
r:   Y nX dS )z
        Close the cursor now. The cursor will be unusable from this point
        forward; an :data:`~clickhouse_driver.dbapi.Error` (or subclass)
        exception will be raised if any operation is attempted with the
        cursor.
        N)	r   Z
disconnectr%   r   r$   r   Zcursorsremove
ValueErrorr,   r   r   r   r.   P   s    

zCursor.closeNc              
   C   sx   |    |   z&|  \}}||f|dd|}W n* tk
r` } zt|W 5 d}~X Y nX | | |   dS )a  
        Prepare and execute a database operation (query or command).

        :param operation: query or command to execute.
        :param parameters: sequence or mapping that will be bound to
                           variables in the operation.
        :return: None
        T)paramsZwith_column_typesN_check_cursor_closed_begin_query_prepareDriverErrorr   _process_response
_end_query)r   	operation
parametersexecuteexecute_kwargsresponseorigr   r   r   rJ   `   s     	 

zCursor.executec              
   C   sz   |    |   z$|  \}}||fd|i|}W n* tk
r^ } zt|W 5 d}~X Y nX | j|dd |   dS )aE  
        Prepare a database operation (query or command) and then execute it
        against all parameter sequences found in the sequence
        `seq_of_parameters`.

        :param operation: query or command to execute.
        :param seq_of_parameters: sequences or mappings for execution.
        :return: None
        r@   NT)executemanyrA   )r   rH   Zseq_of_parametersrJ   rK   rL   rM   r   r   r   rN   z   s    

zCursor.executemanyc                 C   s4   |    | jrt| jdS | js$dS | jdS dS )z
        Fetch the next row of a query result set, returning a single sequence,
        or None when no more data is available.

        :return: the next row of a query result set or None.
        Nr   )_check_query_started_stream_resultsnext_rowspopr,   r   r   r   r*      s    zCursor.fetchonec                 C   sv   |    |dkr| j}| jr>|dkr.t| jS tt| j|S |dk rT| j}g | _n| jd| }| j|d | _|S )a.  
        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.

        :param size: amount of rows to return.
        :return: list of fetched rows or empty list.
        Nr   )rO   r   rP   listrR   r   )r   sizervr   r   r   	fetchmany   s    	
zCursor.fetchmanyc                 C   s(   |    | jrt| jS | j}g | _|S )z
        Fetch all (remaining) rows of a query result, returning them as a
        sequence of sequences (e.g. a list of tuples).

        :return: list of fetched rows.
        )rO   rP   rU   rR   )r   rW   r   r   r   fetchall   s    
zCursor.fetchallc                 C   s   d S r)   r   )r   Zsizesr   r   r   setinputsizes   s    zCursor.setinputsizesc                 C   s   d S r)   r   )r   rV   columnr   r   r   setoutputsize   s    zCursor.setoutputsizec                 C   s   | j S )z
        :return: list of column names with corresponding types of the last
                 .execute*(). E.g. [('x', 'UInt64')].
        )r   r,   r   r   r   columns_with_types   s    zCursor.columns_with_typesc                 C   s   || _ || _dS )am  
        Toggles results streaming from server. Driver will consume
        block-by-block of `max_row_buffer` size and yield row-by-row from each
        block.

        :param stream_results: enable or disable results streaming.
        :param max_row_buffer: specifies the maximum number of rows to buffer
               at a time.
        :return: None
        N)rP   _max_row_buffer)r   Zstream_resultsZmax_row_bufferr   r   r   set_stream_results   s    zCursor.set_stream_resultsc                 C   s
   || _ dS )z}
        Specifies settings for cursor.

        :param settings: dictionary of query settings
        :return: None
        N)	_settings)r   settingsr   r   r   set_settings   s    zCursor.set_settingsc                 C   s
   || _ dS )z
        Toggles type checking for sequence of INSERT parameters.
        Disabled by default.

        :param types_check: new types check value.
        :return: None
        N)_types_check)r   types_checkr   r   r   set_types_check   s    zCursor.set_types_checkc                 C   s   ||f| j |< dS )a  
        Adds external table to cursor context.

        If the same table is specified more than once the last one is used.

        :param name: name of external table
        :param structure: list of tuples (name, type) that defines table
                          structure. Example [(x, 'Int32')].
        :param data: sequence of rows of tuples or dicts for transmission.
        :return: None
        N)_external_tables)r   r4   	structuredatar   r   r   set_external_table  s    zCursor.set_external_tablec                 C   s
   || _ dS )z
        Specifies the query identifier for cursor.

        :param query_id: the query identifier.
        :return: None
        N)	_query_id)r   query_idr   r   r   set_query_id  s    zCursor.set_query_idc                 C   sb   dd | j  D pd }| jj}| jrF| jj}| jp6i | _| j| jd< | j|| j| j	d}||fS )Nc                 S   s    g | ]\}\}}|||d qS ))r4   rg   rh   r   )r3   r4   rg   rh   r   r   r   r5     s   
z#Cursor._prepare.<locals>.<listcomp>Zmax_block_size)ra   external_tablesrd   rk   )
rf   itemsr   rJ   rP   Zexecute_iterr`   r^   rc   rj   )r   rm   rJ   rK   r   r   r   rD     s     zCursor._prepareFc                 C   s   |r|| _ d }|rt|trBg  | _ | _| _t|tr>|| _ d S | jrVt|}|}n|\}}|| _|rt	| \| _| _| jst
|| _ ng  | _| _|| _d S r)   )r<   
isinstanceintr6   r7   rR   rP   rQ   r   r8   len)r   rL   rN   r]   Zrowsr   r   r   rF   4  s&    
zCursor._process_responsec                 C   sJ   | j j| _d| _d| _d| _d| _d| _d| _d| _	d| _
i | _d| _dS )zE
        Resets query state and get ready for another query.
        NrT   Fr   )r%   r   r$   r6   r7   rR   r<   rP   r^   r`   rj   rf   rc   r,   r   r   r   r   T  s    
zCursor._reset_statec                 C   s   | j j| _d S r)   )r%   r   r$   r,   r   r   r   rC   f  s    zCursor._begin_queryc                 C   s   | j j| _d S r)   )r%   r   r$   r,   r   r   r   rG   i  s    zCursor._end_queryc                 C   s   | j | jjkrtdd S )Nzcursor already closed)r$   r%   r   r   r,   r   r   r   rB   l  s    zCursor._check_cursor_closedc                 C   s   | j | jjkrtdd S )Nzno results to fetch)r$   r%   r   r	   r,   r   r   r   rO   p  s    zCursor._check_query_started)N)N)N)F)$r   r   r   objectr   r%   r   r(   r+   r-   r2   propertyr;   r=   r.   rJ   rN   r*   rX   rY   rZ   r\   r]   r_   rb   re   ri   rl   rD   rF   r   rC   rG   rB   rO   __classcell__r   r   r"   r   r      sB   





	

 r   N)collectionsr   	itertoolsr   errorsr   rE   r   r   r	   r
   rr   r   r   r   r   r   <module>   s   