
    5Th>H                        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          Zd.d	Z G d
 d          Z G d d          Z G d de          Z G d de          Z G d de          Z G d de          Z G d de          Z eee            eeeddd          Ze                                  eeeddd          Ze                                  eeedd d!          Ze                                  ed"ed#d$d%          Ze                                  ed&ed'd(d)          Ze                                  ed*ed+d,d-          Ze                                 dS )/z1Implementation of the Range type and adaptation

    N)ProgrammingErrorInterfaceError)	ISQLQuoteadaptregister_adapter)new_typenew_array_typeregister_typec                      e Zd ZdZdZddZd Zd Zed	             Z	ed
             Z
ed             Zed             Zed             Zed             Zed             Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )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                     |s-|dvrt          d|          || _        || _        || _        d S d x| _        x| _        | _        d S )N)r   z(]z()z[]zbound flags not valid: )
ValueErrorr   r   r   )selflowerupperboundsemptys        S/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/psycopg2/_range.py__init__zRange.__init__/   s_     	<555 !E6!E!EFFFDKDK!DLLL7;;DK;$+    c                     | j         | j        j         dS d                    | j        j        | j        | j        | j                   S )Nz(empty=True)z{}({!r}, {!r}, {!r}))r   	__class____name__formatr   r   r   s    r   __repr__zRange.__repr__:   sJ    <n-;;;;)001HT[$,8 8 8r   c                     | j         dS | j         d         t          | j                  dt          | j                  | j         d         g}d                    |          S )Nr   r   z,     )r   strr   r   join)r   itemss     r   __str__zRange.__str__A   sY    <7 LOLO
 wwu~~r   c                     | j         S )z:The lower bound of the range. `!None` if empty or unbound.)r   r    s    r   r   zRange.lowerN        {r   c                     | j         S )z:The upper bound of the range. `!None` if empty or unbound.)r   r    s    r   r   zRange.upperS   r*   r   c                     | j         du S )z`!True` if the range is empty.Nr   r    s    r   isemptyzRange.isemptyX   s     |t##r   c                 &    | j         dS | j        du S )z0`!True` if the range doesn't have a lower bound.NFr   r   r    s    r   	lower_infzRange.lower_inf]        <5{d""r   c                 &    | j         dS | j        du S )z1`!True` if the range doesn't have an upper bound.NFr   r   r    s    r   	upper_infzRange.upper_infd   r2   r   c                 D    | j         | j        dS | j         d         dk    S )z4`!True` if the lower bound is included in the range.NFr   [r0   r    s    r   	lower_inczRange.lower_inck   )     <4;#65|A#%%r   c                 D    | j         | j        dS | j         d         dk    S )z4`!True` if the upper bound is included in the range.NFr#   ]r4   r    s    r   	upper_inczRange.upper_incr   r9   r   c                     | j         dS | j        ,| j         d         dk    r|| j        k     rdS n|| j        k    rdS | j        ,| j         d         dk    r|| j        k    rdS n|| j        k    rdS dS )NFr   r7   r#   r;   T)r   r   r   )r   xs     r   __contains__zRange.__contains__y   s    <5;"|A#%%t{?? 5 # ## 5;"|A#%%t{?? 5 # ## 5tr   c                     | j         d uS Nr-   r    s    r   __bool__zRange.__bool__   s    |4''r   c                     t          |t                    sdS | j        |j        k    o| j        |j        k    o| j        |j        k    S )NF)
isinstancer   r   r   r   r   others     r   __eq__zRange.__eq__   sL    %'' 	5u|+ .u|+.-	/r   c                 .    |                      |           S rA   )rG   rE   s     r   __ne__zRange.__ne__   s    ;;u%%%%r   c                 D    t          | j        | j        | j        f          S rA   )hashr   r   r   r    s    r   __hash__zRange.__hash__   s    T[$+t|<===r   c                     t          |t                    st          S dD ]:}t          | |          }t          ||          }||k    r)| dS | dS ||k     c S dS )Nr   TF)rD   r   NotImplementedgetattr)r   rF   attr
self_valueother_values        r   __lt__zRange.__lt__   s    %'' 	"!!3 
	0 
	0D t,,J!%..K[((#tt$uu!K////ur   c                 <    | |k    rdS |                      |          S NT)rS   rE   s     r   __le__zRange.__le__   "    5==4;;u%%%r   c                 d    t          |t                    r|                    |           S t          S rA   )rD   r   rS   rN   rE   s     r   __gt__zRange.__gt__   s,    eU## 	"<<%%%!!r   c                 <    | |k    rdS |                      |          S rU   )rY   rE   s     r   __ge__zRange.__ge__   rW   r   c                 *      fd j         D             S )Nc                 R    i | ]#}t          |          |t          |          $S  )hasattrrO   ).0slotr   s     r   
<dictcomp>z&Range.__getstate__.<locals>.<dictcomp>   sC     ? ? ?'$*=*=?gdD)) ? ? ?r   )	__slots__r    s   `r   __getstate__zRange.__getstate__   s0    ? ? ? ?? ? ? 	?r   c                 \    |                                 D ]\  }}t          | ||           d S rA   )r'   setattr)r   statera   values       r   __setstate__zRange.__setstate__   s<     ;;== 	' 	'KD%D$&&&&	' 	'r   )NNr   F)r   
__module____qualname____doc__rc   r   r!   r(   propertyr   r   r.   r1   r5   r8   r<   r?   rB   rG   rI   rL   rS   rV   rY   r[   rd   ri   r^   r   r   r   r   #   s         0I	< 	< 	< 	<8 8 8     X   X $ $ X$ # # X# # # X# & & X& & & X&  ,( ( (/ / /& & &> > >   & & &" " "& & &? ? ?' ' ' ' 'r   r   Fc                 r    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casters        r   register_rangerw      s@    4 !!'7LAAF
\2l:d;;;Mr   c                   .    e Zd ZdZdZd Zd Zd Z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                     || _         d S rA   )adapted)r   r{   s     r   r   zRangeAdapter.__init__   s    r   c                 &    | j         t          u r| S d S rA   )_protor   )r   protos     r   __conform__zRangeAdapter.__conform__   s    ;)##K $#r   c                     || _         d S rA   )_conn)r   conns     r   preparezRangeAdapter.prepare   s    


r   c                    | j         t          d          | j        }|j        rd| j                             d          z   S |j        St          |j                  }t          |d          r|                    | j	                   |
                                }nd}|j        St          |j                  }t          |d          r|                    | j	                   |
                                }nd}| j                             d          dz   |z   dz   |z   dz   |j                            d          z   d	z   S )
NzMRangeAdapter must be subclassed overriding its name or the getquoted() methods	   'empty'::utf8r   s   NULL   (s   , s   , 's   '))nameNotImplementedErrorr{   r.   encoder   r   r_   r   r   	getquotedr   r   )r   rar   r   s        r   r   zRangeAdapter.getquoted   sA   9%,- - - L9 	;$)"2"26":":::7agAq)$$ &		$*%%%KKMMEEE7agAq)$$ &		$*%%%KKMMEEEy''$.6>Fy''//0278 	8r   )	r   rj   rk   rl   r   r   r   r   r   r^   r   r   ry   ry      sa         
 D      8 8 8 8 8r   ry   c                       e Zd ZdZd
dZd Zed             Z ej	        dej
                  Z ej	        d          Zd
dZ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                    || _         |                     ||           | j        j        p| j        j        j        }t          |f|| j                  | _        |!t          |f|dz   | j                  | _
        d S d | _
        d S )NARRAY)subtype_oid_create_rangesadapterr   r   r   r   parse
typecasterr	   array_typecaster)r   rr   rs   oidr   	array_oidr   s          r   r   zRangeCaster.__init__$  s    &GW---| CDL$:$C"C64<< $2dWndo%? %?D!!! %)D!!!r   c                 4   d| _         t          |t                    r)t          |t          fi           | _         || j         _        n7	 t          |t                    r|t          ur|| _         n# t          $ r Y nw xY w| j         t          d          d| _        	 t          |t                    rt          |t          fi           | _        t          |t                    r|t          ur|| _        n# t          $ r Y nw xY w| j        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)
r   rD   r%   typery   r   
issubclass	TypeErrorranger   )r   rr   rs   s      r   r   zRangeCaster._create_ranges2  sN    gs## 		,"==DL 'DLg|44 +#<77#*DL    <LN N N 
	'3'' 9!'E8R88
'5)) %gU.B.B$
 	 	 	D	 :CE E E s%   %A- -
A:9A:AC2 2
C?>C?c                 6   ddl m} ddlm}  ||          \  }}|j        j        dk     rt          d|j        j        z            |j        }d|v r|                    dd          \  }	}
n|}
d}	|	                    d	|
|	f           |
                                }|s	 d
}|j        |k    r|	                    d           d}|	                    d|f           |
                                }|r|dd         \  }
}	n# t          $ r Y nw xY w|r|	                    d           n# |r|	                    d           w w xY w||k    r|j        s|                                 |st          d| d          |dd         \  }}}t          |||||          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   r   r   )psycopg2.extensionsr   psycopg2.extrasr   infoserver_versionr   statussplitexecutefetchone
autocommitrollbackro   )r   r   rs   rt   r   r   r   cursconn_statusschematnamerec	savepointr   subtypearrays                   r   rp   zRangeCaster._from_dbU  sO    	>=====444444%%l33
d9#e++"#L)*$+ , , , k $;; JJsA..MFEEEF 	  V_	 	 	 mmoo 	HH!	 ;"777LL!:;;; $I  X   mmoo ,$'GME6 $     HLL!FGGG  HLL!FGGGGH ////MMOOO 	8"6T6668 8 8  #2A2wgu4'U< < < 	<s*   ;C> $D& >
DD& 
DD& &E a]  
        ( \(|\[ )                   # 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                    |d S |dk    r|                      d          S | j                            |          }|t          d| d          |                    d          }|2|                    d          }|| j                            d|          }|                    d	          }|2|                    d
          }|| j                            d|          }|6|                    | j        |          }|                    | j        |          }|                    d          |                    d          z   }|                      |||          S )Nr   T)r   zfailed to parse range: ''r      z\1      r#      )	r   	_re_rangematchr   group_re_undoublesubcastr   )r   scurmr   r   r   s          r   r   zRangeCaster.parse  sD   94<<::D:)))N  ##9 !@A!@!@!@AAA

=GGAJJE )--eU;;

=GGAJJE )--eU;;?HHT-u55EHHT-u55Eaggajj(zz%///r   c                     t          | j        |           | j        t          | j        |           t          | j        | j                   d S rA   )r
   r   r   r   r   r   )r   scopes     r   rq   zRangeCaster._register  sJ    dou--- ,$/777T\22222r   rA   )r   rj   rk   rl   r   r   classmethodrp   recompileVERBOSEr   r   r   rq   r^   r   r   ro   ro     s         ) ) ) )!E !E !EF J< J< [J<X 
  Z I 2:l++L0 0 0 0>3 3 3 3 3 3r   ro   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   rj   rk   rl   r^   r   r   r   r     s         
 	Dr   r   c                       e Zd ZdZdS )	DateRangez#Represents :sql:`daterange` values.Nr   r^   r   r   r   r             --Dr   r   c                       e Zd ZdZdS )DateTimeRangez!Represents :sql:`tsrange` values.Nr   r^   r   r   r   r     s        ++Dr   r   c                       e Zd ZdZdS )DateTimeTZRangez#Represents :sql:`tstzrange` values.Nr   r^   r   r   r   r     r   r   r   c                       e Zd ZdZd ZdS )NumberRangeAdapterz1Adapt a range if the subtype doesn't need quotes.c                    | 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#   )r{   r.   r1   r   r   r   decoder5   r   r   r   )r   r   r   r   s       r   r   zNumberRangeAdapter.getquoted  s    L9 	:{ 	
 !'NN,,..55g>>EEE{ 	!'NN,,..55g>>EEE@AIaL@%@@%@1@@@HHQQQr   N)r   rj   rk   rl   r   r^   r   r   r   r     s.        ;;R R R R Rr   r   i@     iA  r   iV     iW  iB  i  iC  	daterangeiH  i:  iI  tsrangeiD  iZ  iE  	tstzrangeiF  i  iG  )F)rl   r   psycopg2._psycopgr   r   r   r   r   r   r   r	   r
   r   rw   ry   ro   r   r   r   r   r   int4range_casterrq   int8range_casternumrange_casterdaterange_castertsrange_castertstzrange_casterr^   r   r   <module>r      s>   6 
			 > > > > > > > > B B B B B B B B B B G G G G G G G G G Gh' h' h' h' h' h' h' h'V   >-8 -8 -8 -8 -8 -8 -8 -8`y3 y3 y3 y3 y3 y3 y3 y3x	 	 	 	 	5 	 	 		 	 	 	 	 	 	 	
	 	 	 	 	E 	 	 	
	 	 	 	 	e 	 	 	R R R R R R R R2  1 2 2 2
 ;1<". . .       ;1<". . .       +0,$$0 0 0      ;{I$$0 0 0       Y$$0 0 0      ;{O$$0 0 0         r   