o
    EDiH!                  
   @   s  d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	m
Z
 d dlmZmZmZ d dlmZ ejdkZe  djZdZdd	dd
dZdddddZedkrQded< dd e D Zded< ded< dddddZdedefd d!ZdMd"ed#ed$ed%ee fd&d'Zd(ed$efd)d*Z d(ed$efd+d,Z!d-efd.d/Z"d0ed1efd2d3Z#dNd4ed5ee d1efd6d7Z$d4ed8ed(e%d1efd9d:Z&d;d< Z'd=eeeef  d1efd>d?Z(d=eeeef  fd@dAZ)dOd#edCefdDdEZ*G dFdG dGeZ+G dHdI dIZ,dJee d1ee
egef  fdKdLZ-dS )P    N)SequenceMutableSequenceDictOptionalUnion	GeneratorCallable)ProgrammingErrorStreamClosedError	DataError)Closablebigi   bhq)r            	      &   O   )    @         r   lr   c                 C   s   i | ]\}}||qS  r   ).0kvr   r   Y/var/www/Datamplify/venv/lib/python3.10/site-packages/clickhouse_connect/driver/common.py
<dictcomp>   s    r$   fr   dz[s]z[ms]z[us]z[ns])r         r   sizesignedc                 C   s2   zt |  }W n
 ty   Y dS w |r|S | S )z
    Determines the Python array.array code for the requested byte size
    :param size: byte size
    :param signed: whether int types should be signed or unsigned
    :return: Python array.array code
    N)	array_mapKeyErrorupper)r)   r*   coder   r   r#   
array_type   s   r/   r.   columndestcol_namec              
   C   sx   zt dt| |  }||j| 7 }W dS  ttt jfy; } zd}|r,d| d}td| dd |d}~ww )	a+  
    Write a column of native Python data matching the array.array code
    :param code: Python array.array code matching the column data type
    :param column: Column of native Python values
    :param dest: Destination byte buffer
    :param col_name: Optional column name for error tracking
    < z for source column ``zUnable to create Python arrayz3.  This is usually caused by trying to insert None z4values into a ClickHouse column that is not NullableN)structStructlenpack	TypeErrorOverflowErrorerrorr   )r.   r0   r1   r2   buffexcol_msgr   r   r#   write_array)   s   r@   valuec                 C   s   | | dd dS )z
    Write a single UInt64 value to a binary write buffer
    :param value: UInt64 value to write
    :param dest: Destination byte buffer
    r   littleN)extendto_bytes)rA   r1   r   r   r#   write_uint64<   s   rE   c                 C   s8   	 | d@ }| dL } | dkr| | dS | d|B  q)z
    Write a LEB128 encoded integer to a target binary buffer
    :param value: Integer value (positive only)
    :param dest: Target buffer
    T      r   Nr   )append)rA   r1   r   r   r   r#   write_leb128E   s   
rI   precc                 C   sH   | dk s| dkrt d|  d| dk rdS | dk rdS | d	k r"d
S dS )z
    Determine the bit size of a ClickHouse or Python Decimal needed to store a value of the requested precision
    :param prec: Precision of the Decimal in total number of base 10 digits
    :return: Required bit size
    r   r   zInvalid precision z for ClickHouse Decimal type
   r      r   '   r   r   )ArithmeticError)rJ   r   r   r#   decimal_sizeT   s   rO   xreturnc                 C   s$   |  dr| dr| dd S | S )Nr5   r   )
startswithendswith)rP   r   r   r#   unescape_identifiere   s   rU   sourceupdatec                 C   s"   | r|   ni }|r|| |S N)copyrW   )rV   rW   rY   r   r   r#   	dict_copyk   s   
rZ   keyc                 C   s   |d ur|| |< | S rX   r   )rV   r[   rA   r   r   r#   dict_addr   s   r\   c                   c   s    dE d H  d S )Nr   r   r   r   r   r#   	empty_genx   s   r]   valc                 C   s   | sdS t | S )Nr   )intr^   r   r   r#   
coerce_int|   s   ra   c                 C   s&   | sdS | du pt | to|  dv S )NFT)true1yyes)
isinstancestrlowerr`   r   r   r#   coerce_bool   s   ri   Tnullablec                 C   s,   |rt dd | D d S t| r| d S d S )Nc                 s   s    | ]	}|d ur|V  qd S rX   r   )r    rP   r   r   r#   	<genexpr>   s    zfirst_value.<locals>.<genexpr>r   )nextr8   )r0   rj   r   r   r#   first_value   s
   rm   c                   @   sT   e Zd ZdZdZddedee fddZdd	 Z	d
d Z
dd Zdd Zdd ZdS )	SliceViewa  
    Provides a view into a sequence rather than copying.  Borrows liberally from
    https://gist.github.com/mathieucaroff/0cf094325fb5294fb54c6a577f05a2c1
    Also see the discussion on SO: https://stackoverflow.com/questions/3485475/can-i-create-a-view-on-a-python-list
    )_source_rangeNrV   source_slicec                 C   sX   t |tr|j| _|j| | _d S || _|d u r!tt|| _d S tt|| | _d S rX   )rf   rn   ro   rp   ranger8   )selfrV   rq   r   r   r#   __init__   s   
zSliceView.__init__c                 C   s
   t | jS rX   )r8   rp   rs   r   r   r#   __len__   s   
zSliceView.__len__c                 C   s&   t |trt| j|S | j| j|  S rX   )rf   slicern   ro   rp   )rs   r   r   r   r#   __getitem__   s   
zSliceView.__getitem__c                 C   s"   | j }t| jt|j|j|j S rX   )rp   rg   ro   rw   startstopsteprs   rr   r   r#   __str__   s   zSliceView.__str__c                 C   s&   | j }d| jt|j|j|j  dS )Nz
SliceView())rp   ro   rw   ry   rz   r{   r|   r   r   r#   __repr__   s    zSliceView.__repr__c                 C   sF   | |u rdS t | t |krdS t| |D ]\}}||kr  dS qdS )NTF)r8   zip)rs   otherr"   wr   r   r#   __eq__   s   zSliceView.__eq__rX   )__name__
__module____qualname____doc__slotsr   r   rw   rt   rv   rx   r~   r   r   r   r   r   r#   rn      s    rn   c                   @   sF   e Zd ZdZdZdedefddZdd Zd	d
 Z	dd Z
dd ZdS )StreamContextz
    Wraps a generator and its "source" in a Context.  This ensures that the source will be "closed" even if the
    generator is not fully consumed or there is an exception during consumption
    rV   gen_in_contextrV   r   c                 C   s   || _ || _d| _d S NFr   )rs   rV   r   r   r   r#   rt      s   
zStreamContext.__init__c                 C   s   | S rX   r   ru   r   r   r#   __iter__   s   zStreamContext.__iter__c                 C   s   | j stdt| jS )Nz&Stream should be used within a context)r   r	   rl   r   ru   r   r   r#   __next__   s   
zStreamContext.__next__c                 C   s   | j std| _| S )NT)r   r
   r   ru   r   r   r#   	__enter__   s   zStreamContext.__enter__c                 C   s   d| _ | j  d | _d S r   )r   rV   closer   )rs   exc_typeexc_valexc_tbr   r   r#   __exit__   s   

zStreamContext.__exit__N)r   r   r   r   	__slots__r   r   rt   r   r   r   r   r   r   r   r#   r      s    r   methodc                    s   dt dt fdddt dt fdddt dt fdd | sd S |   }|d	kr+d S |d
kr1 S |dkr7S |dkrB fddS |dkrHS |dkrS fddS g d}td| d| )NsrQ   c                 S   s^   | sdS g d}}| D ]}|  s|dkrd}q|r$||  d}q|| qd|S )Nr4   F_T)isspacerH   r-   join)r   outupchr   r   r#   	_to_camel   s   

z$get_rename_method.<locals>._to_camelc                 S   s   | sdS g d}}| D ]B}|  r|dkr|d d}q| rF|dkr2|d ||  n|dkr>||  n|| d}q|| d}q|r_|d dkr_d|dd  S d|S )Nr4   r   r   r   r   )r   rH   isupperrh   r   )r   r   prevr   r   r   r#   _to_underscore   s&   




,z)get_rename_method.<locals>._to_underscorec                 S   s&   |  d}|dkr| |d d  S | S )N.r   r   )rfind)r   r   r   r   r#   _remove_prefix  s   
z)get_rename_method.<locals>._remove_prefixNONEREMOVE_PREFIXTO_CAMELCASETO_CAMELCASE_WITHOUT_PREFIXc                        | S rX   r   r   )r   r   r   r#   <lambda>      z#get_rename_method.<locals>.<lambda>TO_UNDERSCORETO_UNDERSCORE_WITHOUT_PREFIXc                    r   rX   r   r   )r   r   r   r#   r     r   )noneremove_prefixto_camelcaseto_camelcase_without_prefixto_underscoreto_underscore_without_prefixzInvalid option 'z'. Expected one of )rg   stripr-   
ValueError)r   namevalid_optionsr   )r   r   r   r#   get_rename_method   s(   r   rX   )NN)T).arrayr6   systypingr   r   r   r   r   r   r   $clickhouse_connect.driver.exceptionsr	   r
   r   clickhouse_connect.driver.typesr   	byteorder	must_swapitemsizeint_sizelow_card_versionr+   decimal_precitemsarray_sizesnp_date_typesr_   boolr/   rg   r@   rE   rI   rO   rU   rZ   anyr\   r]   ra   ri   rm   rn   r   r   r   r   r   r#   <module>   s@    $
 	.( 