U
    ÉZj>H  ã                   @   sr  d Z ddlZddlmZmZ ddlmZmZmZ ddlm	Z	m
Z
mZ G dd„ dƒZd/d	d
„ZG dd„ dƒZG dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZeeeƒ eeedddd�Ze ¡  eeedddd�Ze ¡  eeed d!d"d�Ze ¡  ed#ed$d%d&d�Ze ¡  ed'ed(d)d*d�Ze ¡  ed+ed,d-d.d�Ze ¡  dS )0z1Implementation of the Range type and adaptation

é    N)ÚProgrammingErrorÚInterfaceError)Ú	ISQLQuoteÚadaptÚregister_adapter)Únew_typeÚnew_array_typeÚregister_typec                   @   sÚ   e Zd ZdZdZd0dd„Zdd	„ Zd
d„ Zedd„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZe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&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdS )1ÚRangea…  Python representation for a PostgreSQL |range|_ type.

    :param lower: lower bound for the range. `!None` means unbound
    :param upper: upper bound for the range. `!None` means unbound
    :param bounds: one of the literal strings ``()``, ``[)``, ``(]``, ``[]``,
        representing whether the lower or upper bounds are included
    :param empty: if `!True`, the range is empty

    ©Ú_lowerÚ_upperÚ_boundsNú[)Fc                 C   sD   |s.|dkrt d|›�ƒ‚|| _|| _|| _nd  | _ | _| _d S )N)r   z(]z()z[]zbound flags not valid: )Ú
ValueErrorr   r   r   )ÚselfÚlowerÚupperÚboundsÚempty© r   úR/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/psycopg2/_range.pyÚ__init__/   s    zRange.__init__c                 C   s6   | j d kr| jj› d�S d | jj| j| j| j ¡S d S )Nz(empty=True)z{}({!r}, {!r}, {!r}))r   Ú	__class__Ú__name__Úformatr   r   ©r   r   r   r   Ú__repr__:   s    

  ÿzRange.__repr__c                 C   s>   | j d krdS | j d t| jƒdt| jƒ| j d g}d |¡S )Nr   r   z, é   Ú )r   Ústrr   r   Újoin)r   Úitemsr   r   r   Ú__str__A   s    
ûzRange.__str__c                 C   s   | j S )z:The lower bound of the range. `!None` if empty or unbound.)r   r   r   r   r   r   N   s    zRange.lowerc                 C   s   | j S )z:The upper bound of the range. `!None` if empty or unbound.)r   r   r   r   r   r   S   s    zRange.upperc                 C   s
   | j dkS )z`!True` if the range is empty.N©r   r   r   r   r   ÚisemptyX   s    zRange.isemptyc                 C   s   | j dkrdS | jdkS )z0`!True` if the range doesn't have a lower bound.NF©r   r   r   r   r   r   Ú	lower_inf]   s    
zRange.lower_infc                 C   s   | j dkrdS | jdkS )z1`!True` if the range doesn't have an upper bound.NF©r   r   r   r   r   r   Ú	upper_infd   s    
zRange.upper_infc                 C   s&   | j dks| jdkrdS | j d dkS )z4`!True` if the lower bound is included in the range.NFr   ú[r&   r   r   r   r   Ú	lower_inck   s    zRange.lower_incc                 C   s&   | j dks| jdkrdS | j d dkS )z4`!True` if the upper bound is included in the range.NFr   ú]r(   r   r   r   r   Ú	upper_incr   s    zRange.upper_incc                 C   s~   | j d krdS | jd k	rD| j d dkr6|| jk rDdS n|| jkrDdS | jd k	rz| j d dkrl|| jkrzdS n|| jkrzdS dS )NFr   r*   r   r,   T)r   r   r   )r   Úxr   r   r   Ú__contains__y   s    






zRange.__contains__c                 C   s
   | j d k	S ©Nr$   r   r   r   r   Ú__bool__�   s    zRange.__bool__c                 C   s2   t |tƒsdS | j|jko0| j|jko0| j|jkS )NF)Ú
isinstancer
   r   r   r   ©r   Úotherr   r   r   Ú__eq__’   s    

ÿ
þzRange.__eq__c                 C   s   |   |¡ S r0   )r5   r3   r   r   r   Ú__ne__™   s    zRange.__ne__c                 C   s   t | j| j| jfƒS r0   )Úhashr   r   r   r   r   r   r   Ú__hash__œ   s    zRange.__hash__c                 C   sb   t |tƒstS dD ]J}t| |ƒ}t||ƒ}||kr4q|d krB dS |d krP dS ||k   S qdS )Nr   TF)r2   r
   ÚNotImplementedÚgetattr)r   r4   ÚattrZ
self_valueZother_valuer   r   r   Ú__lt__£   s    


zRange.__lt__c                 C   s   | |krdS |   |¡S d S ©NT)r<   r3   r   r   r   Ú__le__³   s    zRange.__le__c                 C   s   t |tƒr| | ¡S tS d S r0   )r2   r
   r<   r9   r3   r   r   r   Ú__gt__¹   s    

zRange.__gt__c                 C   s   | |krdS |   |¡S d S r=   )r?   r3   r   r   r   Ú__ge__¿   s    zRange.__ge__c                    s   ‡ fdd„ˆ j D ƒS )Nc                    s"   i | ]}t ˆ |ƒr|tˆ |ƒ“qS r   )Úhasattrr:   )Ú.0Úslotr   r   r   Ú
<dictcomp>Æ   s    
ÿ z&Range.__getstate__.<locals>.<dictcomp>)Ú	__slots__r   r   r   r   Ú__getstate__Å   s    
ÿzRange.__getstate__c                 C   s"   |  ¡ D ]\}}t| ||ƒ qd S r0   )r"   Úsetattr)r   ÚstaterC   Úvaluer   r   r   Ú__setstate__É   s    zRange.__setstate__)NNr   F)r   Ú
__module__Ú__qualname__Ú__doc__rE   r   r   r#   Úpropertyr   r   r%   r'   r)   r+   r-   r/   r1   r5   r6   r8   r<   r>   r?   r@   rF   rJ   r   r   r   r   r
   #   s<   	







r
   Fc                 C   s&   t  | ||¡}| | r|pd¡ |S )aé  Create and register an adapter and the typecasters to convert between
    a PostgreSQL |range|_ type and a PostgreSQL `Range` subclass.

    :param pgrange: the name of the PostgreSQL |range| type. Can be
        schema-qualified
    :param pyrange: a `Range` strict subclass, or just a name to give to a new
        class
    :param conn_or_curs: a connection or cursor used to find the oid of the
        range and its subtype; the typecaster is registered in a scope limited
        to this object, unless *globally* is set to `!True`
    :param globally: if `!False` (default) register the typecaster only on
        *conn_or_curs*, otherwise register it globally
    :return: `RangeCaster` instance responsible for the conversion

    If a string is passed to *pyrange*, a new `Range` subclass is created
    with such name and will be available as the `~RangeCaster.range` attribute
    of the returned `RangeCaster` object.

    The function queries the database on *conn_or_curs* to inspect the
    *pgrange* type and raises `~psycopg2.ProgrammingError` if the type is not
    found.  If querying the database is not advisable, use directly the
    `RangeCaster` class and register the adapter and typecasters using the
    provided functions.

    N)ÚRangeCasterÚ_from_dbÚ	_register)ÚpgrangeÚpyrangeÚconn_or_cursZgloballyZcasterr   r   r   Úregister_rangeÎ   s    rU   c                   @   s4   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚRangeAdapterz¢`ISQLQuote` adapter for `Range` subclasses.

    This is an abstract class: concrete classes must set a `name` class
    attribute or override `getquoted()`.
    Nc                 C   s
   || _ d S r0   )Úadapted)r   rW   r   r   r   r   õ   s    zRangeAdapter.__init__c                 C   s   | j tkr| S d S r0   )Z_protor   )r   Úprotor   r   r   Ú__conform__ø   s    
zRangeAdapter.__conform__c                 C   s
   || _ d S r0   )Ú_conn)r   Úconnr   r   r   Úprepareü   s    zRangeAdapter.preparec                 C   sÎ   | j d krtdƒ‚| j}|jr.d| j  d¡ S |jd k	rbt|jƒ}t|dƒrX| | j	¡ | 
¡ }nd}|jd k	ršt|jƒ}t|dƒr�| | j	¡ | 
¡ }nd}| j  d¡d | d | d |j d¡ d	 S )
NzMRangeAdapter must be subclassed overriding its name or the getquoted() methods	   'empty'::Úutf8r\   s   NULLó   (s   , s   , 's   '))ÚnameÚNotImplementedErrorrW   r%   Úencoder   r   rA   r\   rZ   Ú	getquotedr   r   )r   ÚrÚar   r   r   r   r   rb   ÿ   s4    
ÿ







ÿ
ÿÿzRangeAdapter.getquoted)	r   rK   rL   rM   r_   r   rY   r\   rb   r   r   r   r   rV   í   s   rV   c                   @   sZ   e Zd ZdZddd„Zdd„ Zedd„ ƒZe 	d	ej
¡Ze 	d
¡Zddd„Zddd„ZdS )rO   a	  Helper class to convert between `Range` and PostgreSQL range types.

    Objects of this class are usually created by `register_range()`. Manual
    creation could be useful if querying the database is not advisable: in
    this case the oids must be provided.
    Nc                 C   s`   || _ |  ||¡ | jjp"| jjj}t|f|| jƒ| _|d k	rVt	|f|d | jƒ| _
nd | _
d S )NZARRAY)Úsubtype_oidÚ_create_rangesÚadapterr_   r   r   r   ÚparseÚ
typecasterr   Úarray_typecaster)r   rR   rS   Úoidre   Ú	array_oidr_   r   r   r   r   $  s      ÿzRangeCaster.__init__c                 C   sÖ   d| _ t|tƒr*t|tfi ƒ| _ || j _n2zt|tƒrD|tk	rD|| _ W n tk
rZ   Y nX | j dkrntdƒ‚d| _z6t|tƒr�t|t	fi ƒ| _t|t	ƒr¨|t	k	r¨|| _W n tk
r¾   Y nX | jdkrÒtdƒ‚dS )z0Create Range and RangeAdapter classes if needed.Nz:pgrange must be a string or a RangeAdapter strict subclassz1pyrange must be a type or a Range strict subclass)
rg   r2   r    ÚtyperV   r_   Ú
issubclassÚ	TypeErrorÚranger
   )r   rR   rS   r   r   r   rf   2  s6    


ÿ

ÿ


ÿzRangeCaster._create_rangesc              	   C   sN  ddl m} ddlm} ||ƒ\}}|jjdk r@td|jj ƒ‚|j}d|kr`| dd¡\}	}
n|}
d}	| 	d	|
|	f¡ | 
¡ }|súzdz.d}|j|kr¤| 	d¡ d}| 	d|f¡ W n tk
rÈ   Y nX | 
¡ }|ræ|dd… \}
}	W 5 |rø| 	d
¡ X ||k�r|j�s| ¡  |�s*td|› d�ƒ‚|dd… \}}}t|||||d�S )z|Return a `RangeCaster` instance for the type *pgrange*.

        Raise `ProgrammingError` if the type is not found.
        r   )ÚSTATUS_IN_TRANSACTION)Ú_solve_conn_cursiX` z'range types not available in version %sÚ.r   Úpublicz¯select rngtypid, rngsubtype, typarray
from pg_range r
join pg_type t on t.oid = rngtypid
join pg_namespace ns on ns.oid = typnamespace
where typname = %s and ns.nspname = %s;
z#ROLLBACK TO SAVEPOINT register_typeFzSAVEPOINT register_typeTz³SELECT rngtypid, rngsubtype, typarray, typname, nspname
from pg_range r
join pg_type t on t.oid = rngtypid
join pg_namespace ns on ns.oid = typnamespace
WHERE t.oid = %s::regtype
é   NzPostgreSQL range 'z' not found©rk   re   rl   )Úpsycopg2.extensionsrq   Zpsycopg2.extrasrr   ÚinfoZserver_versionr   ÚstatusÚsplitÚexecuteZfetchoneZ
autocommitÚrollbackrO   )r   r_   rS   rT   rq   rr   r[   ZcursZconn_statusZschemaZtnameZrecZ	savepointrm   ÚsubtypeÚarrayr   r   r   rP   U  sX    ÿú

ú
ÿ  ÿzRangeCaster._from_dba]  
        ( \(|\[ )                   # lower bound flag
        (?:                         # lower bound:
          " ( (?: [^"] | "")* ) "   #   - a quoted string
          | ( [^",]+ )              #   - or an unquoted string
        )?                          #   - or empty (not catched)
        ,
        (?:                         # upper bound:
          " ( (?: [^"] | "")* ) "   #   - a quoted string
          | ( [^"\)\]]+ )           #   - or an unquoted string
        )?                          #   - or empty (not catched)
        ( \)|\] )                   # upper bound flag
        z	(["\\])\1c                 C   sî   |d krd S |dkr | j dd�S | j |¡}|d krDtd|› d�ƒ‚| d¡}|d krv| d¡}|d k	rv| j d|¡}| d	¡}|d kr¨| d
¡}|d k	r¨| j d|¡}|d k	rÌ| | j|¡}| | j|¡}| d¡| d¡ }|   |||¡S )Nr   T)r   zfailed to parse range: 'ú'ru   é   z\1é   é   r   é   )	rp   Ú	_re_rangeÚmatchr   ÚgroupÚ_re_undoubleÚsubÚcastre   )r   ÚsÚcurÚmr   r   r   r   r   r   rh   ²  s,    



zRangeCaster.parsec                 C   s4   t | j|ƒ | jd k	r"t | j|ƒ t| j| jƒ d S r0   )r	   ri   rj   r   rp   rg   )r   Úscoper   r   r   rQ   Ñ  s    
zRangeCaster._register)N)N)N)r   rK   rL   rM   r   rf   ÚclassmethodrP   ÚreÚcompileÚVERBOSEr„   r‡   rh   rQ   r   r   r   r   rO     s   
#
Lô

rO   c                   @   s   e Zd ZdZdS )ÚNumericRangezÄA `Range` suitable to pass Python numeric types to a PostgreSQL range.

    PostgreSQL types :sql:`int4range`, :sql:`int8range`, :sql:`numrange` are
    casted into `!NumericRange` instances.
    N©r   rK   rL   rM   r   r   r   r   r’   Ù  s   r’   c                   @   s   e Zd ZdZdS )Ú	DateRangez#Represents :sql:`daterange` values.Nr“   r   r   r   r   r”   â  s   r”   c                   @   s   e Zd ZdZdS )ÚDateTimeRangez!Represents :sql:`tsrange` values.Nr“   r   r   r   r   r•   ç  s   r•   c                   @   s   e Zd ZdZdS )ÚDateTimeTZRangez#Represents :sql:`tstzrange` values.Nr“   r   r   r   r   r–   ì  s   r–   c                   @   s   e Zd ZdZdd„ ZdS )ÚNumberRangeAdapterz1Adapt a range if the subtype doesn't need quotes.c                 C   s|   | j }|jrdS |js,t|jƒ ¡  d¡}nd}|jsLt|jƒ ¡  d¡}nd}d|j	d › |› d|› |j	d › d� 
d¡S )Ns   'empty'Úasciir   r   r   ú,r   )rW   r%   r'   r   r   rb   Údecoder)   r   r   ra   )r   rc   r   r   r   r   r   rb   ø  s    zNumberRangeAdapter.getquotedN)r   rK   rL   rM   rb   r   r   r   r   r—   ö  s   r—   i@  é   iA  rv   iV  é   iW  iB  i¤  iC  Z	daterangeiH  i:  iI  ZtsrangeiD  iZ  iE  Z	tstzrangeiF  i   iG  )F)rM   r�   Zpsycopg2._psycopgr   r   rw   r   r   r   r   r   r	   r
   rU   rV   rO   r’   r”   r•   r–   r—   Zint4range_casterrQ   Zint8range_casterZnumrange_casterZdaterange_casterZtsrange_casterZtstzrange_casterr   r   r   r   Ú<module>   sh    ,
0 =	

  ÿ  ÿ  ÿ  ÿ  ÿ  ÿ