o
    8g>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   sF   |s|dvrt d||| _|| _|| _d S d  | _ | _| _d S )N)r   z(]z()z[]zbound flags not valid: )
ValueErrorr   r   r   )selflowerupperboundsempty r   Q/var/www/html/ecg_monitoring/venv/lib/python3.10/site-packages/psycopg2/_range.py__init__/   s   
zRange.__init__c                 C   s2   | j d u r| jj dS d| jj| j| j| j 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 u 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      | j S )z:The lower bound of the range. `!None` if empty or unbound.)r   r   r   r   r   r   N      zRange.lowerc                 C   r$   )z:The upper bound of the range. `!None` if empty or unbound.)r   r   r   r   r   r   S   r%   zRange.upperc                 C   s
   | j du S )z`!True` if the range is empty.Nr   r   r   r   r   isemptyX   s   
zRange.isemptyc                 C      | j du rdS | jdu S )z0`!True` if the range doesn't have a lower bound.NFr   r   r   r   r   r   	lower_inf]      

zRange.lower_infc                 C   r(   )z1`!True` if the range doesn't have an upper bound.NFr   r   r   r   r   r   	upper_infd   r+   zRange.upper_infc                 C   &   | j du s
| jdu 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      zRange.lower_incc                 C   r.   )z4`!True` if the upper bound is included in the range.NFr   ]r,   r   r   r   r   	upper_incr   r1   zRange.upper_incc                 C   s   | j d u rdS | jd ur"| j d dkr|| jk rdS n|| jkr"dS | jd ur>| j d dkr7|| jkr5dS dS || jkr>dS dS )NFr   r/   r   r2   T)r   r   r   )r   xr   r   r   __contains__y   s"   






zRange.__contains__c                 C   s
   | j d uS Nr&   r   r   r   r   __bool__      
zRange.__bool__c                 C   s2   t |tsdS | j|jko| j|jko| j|jkS )NF)
isinstancer
   r   r   r   r   otherr   r   r   __eq__   s   


zRange.__eq__c                 C   s   |  | S r6   )r<   r:   r   r   r   __ne__   s   zRange.__ne__c                 C   s   t | j| j| jfS r6   )hashr   r   r   r   r   r   r   __hash__   s   zRange.__hash__c                 C   s`   t |tstS dD ]$}t| |}t||}||krq	|d u r! dS |d u r( dS ||k   S dS )Nr   TF)r9   r
   NotImplementedgetattr)r   r;   attr
self_valueother_valuer   r   r   __lt__   s   


zRange.__lt__c                 C      | |krdS |  |S NT)rE   r:   r   r   r   __le__      
zRange.__le__c                 C   s   t |tr
|| S tS r6   )r9   r
   rE   r@   r:   r   r   r   __gt__   s   

zRange.__gt__c                 C   rF   rG   )rJ   r:   r   r   r   __ge__   rI   zRange.__ge__c                    s    fdd j D S )Nc                    s"   i | ]}t  |r|t |qS r   )hasattrrA   ).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 r6   )r"   setattr)r   staterN   valuer   r   r   __setstate__   s   zRange.__setstate__)NNr   F)r   
__module____qualname____doc__rP   r   r   r#   propertyr   r   r'   r*   r-   r0   r3   r5   r7   r<   r=   r?   rE   rH   rJ   rK   rQ   rU   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_cursgloballycasterr   r   r   register_range   s   rb   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   
   || _ d S r6   )adapted)r   re   r   r   r   r      r8   zRangeAdapter.__init__c                 C   s   | j tu r| S d S r6   )_protor   )r   protor   r   r   __conform__   s   
zRangeAdapter.__conform__c                 C   rd   r6   )_conn)r   connr   r   r   prepare   r8   zRangeAdapter.preparec                 C   s   | j d u r	td| j}|jrd| j d S |jd ur1t|j}t|dr,|| j	 |
 }nd}|jd urMt|j}t|drH|| j	 |
 }nd}| j dd | d | d |jd d	 S )
NzMRangeAdapter must be subclassed overriding its name or the getquoted() methods	   'empty'::utf8rk   s   NULL   (s   , s   , 's   '))nameNotImplementedErrorre   r'   encoder   r   rL   rk   ri   	getquotedr   r   )r   rar   r   r   r   r   rq      s4   









zRangeAdapter.getquoted)	r   rV   rW   rX   rn   r   rh   rk   rq   r   r   r   r   rc      s    rc   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 )rZ   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   sb   || _ | || | jjp| jjj}t|f|| j| _|d ur,t	|f|d | j| _
d S d | _
d S )NARRAY)subtype_oid_create_rangesadapterrn   r   r   r   parse
typecasterr   array_typecaster)r   r]   r^   oidru   	array_oidrn   r   r   r   r   $  s   

zRangeCaster.__init__c                 C   s   d| _ t|trt|tfi | _ || j _nzt|tr"|tur"|| _ W n	 ty,   Y nw | j du r6tdd| _zt|trGt|t	fi | _t|t	rS|t	urS|| _W n	 ty]   Y nw | jdu rgt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)
rw   r9   r    typerc   rn   
issubclass	TypeErrorranger
   )r   r]   r^   r   r   r   rv   2  s>   





zRangeCaster._create_rangesc              	   C   sV  ddl m} ddlm} ||\}}|jjdk r td|jj |j}d|v r0|dd\}	}
n|}
d}	|	d	|
|	f |
 }|sz8zd
}|j|krR|	d d}|	d|f W n	 tyc   Y nw |
 }|rr|dd \}
}	W |rz|	d n	|r|	d w w ||kr|js|  |st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   publiczselect 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;
FzSAVEPOINT register_typeTzSELECT 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#ROLLBACK TO SAVEPOINT register_typezPostgreSQL range 'z' not foundr{   ru   r|   )psycopg2.extensionsr   psycopg2.extrasr   infoserver_versionr   statussplitexecutefetchone
autocommitrollbackrZ   )r   rn   r^   r_   r   r   rj   cursconn_statusschematnamerec	savepointr}   subtypearrayr   r   r   r[   U  s`   



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 u rd S |dkr| j ddS | j|}|d u r"td| d|d}|d u r;|d}|d ur;| jd|}|d	}|d u rT|d
}|d urT| jd|}|d urf|| j|}|| j|}|d|d }|  |||S )Nr   T)r   zfailed to parse range: ''r      z\1      r      )	r   	_re_rangematchr   group_re_undoublesubcastru   )r   scurmr   r   r   r   r   r   rx     s,   



zRangeCaster.parsec                 C   s4   t | j| | jd urt | j| t| j| j d S r6   )r	   ry   rz   r   r   rw   )r   scoper   r   r   r\     s   
zRangeCaster._registerr6   )r   rV   rW   rX   r   rv   classmethodr[   recompileVERBOSEr   r   rx   r\   r   r   r   r   rZ     s    
#
L

rZ   c                   @      e Zd ZdZdS )NumericRangezA `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   rV   rW   rX   r   r   r   r   r     s    r   c                   @   r   )	DateRangez#Represents :sql:`daterange` values.Nr   r   r   r   r   r         r   c                   @   r   )DateTimeRangez!Represents :sql:`tsrange` values.Nr   r   r   r   r   r     r   r   c                   @   r   )DateTimeTZRangez#Represents :sql:`tstzrange` values.Nr   r   r   r   r   r     r   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s&t|j d}nd}d|j	d  | d| |j	d  d
dS )Ns   'empty'asciir   r   r   ,r   )re   r'   r*   r   r   rq   decoder-   r   r   rp   )r   rr   r   r   r   r   r   rq     s   ,zNumberRangeAdapter.getquotedN)r   rV   rW   rX   rq   r   r   r   r   r     s    r   i@     iA  r   iV     iW  iB  i  iC  	daterangeiH  i:  iI  tsrangeiD  iZ  iE  	tstzrangeiF  i  iG  )F)rX   r   psycopg2._psycopgr   r   r   r   r   r   r   r   r	   r
   rb   rc   rZ   r   r   r   r   r   int4range_casterr\   int8range_casternumrange_casterdaterange_castertsrange_castertstzrange_casterr   r   r   r   <module>   sR     
,0 =	

