
    9h>H                     F   S r SSKrSSKJrJr  SSKJrJrJr  SSKJ	r	J
r
Jr   " S S5      rS-S jr " S	 S
5      r " S S5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r\" \\5        \" \\SSSS9r\R-                  5         \" \\SSSS9r\R-                  5         \" \\SSS S9r\R-                  5         \" S!\S"S#S$S9r\R-                  5         \" S%\S&S'S(S9r\R-                  5         \" S)\S*S+S,S9r\R-                  5         g).z1Implementation of the Range type and adaptation

    N)ProgrammingErrorInterfaceError)	ISQLQuoteadaptregister_adapter)new_typenew_array_typeregister_typec                       \ rS rSrSrSrSS jrS rS r\	S 5       r
\	S	 5       r\	S
 5       r\	S 5       r\	S 5       r\	S 5       r\	S 5       rS rS rS rS rS rS rS rS rS rS rS rSrg)Range#   am  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_boundsNc                     U(       d(  US;  a  [        SU< 35      eXl        X l        X0l        g S =U l        =U l        U l        g )N)[)z(]z()z[]zbound flags not valid: )
ValueErrorr   r   r   )selflowerupperboundsemptys        A/var/www/html/env/lib/python3.13/site-packages/psycopg2/_range.py__init__Range.__init__/   sE    55 #:6*!EFFKK!L7;;DK;$+    c                     U R                   c  U R                  R                   S3$ SR                  U R                  R                  U R                  U R
                  U R                   5      $ )Nz(empty=True)z{}({!r}, {!r}, {!r}))r   	__class____name__formatr   r   r   s    r   __repr__Range.__repr__:   sV    <<nn--.l;;)001H1HT[[$,,8 8r   c                     U R                   c  gU R                   S   [        U R                  5      S[        U R                  5      U R                   S   /nSR	                  U5      $ )Nr   r   z,     )r   strr   r   join)r   itemss     r   __str__Range.__str__A   sY    << LLOLLO
 wwu~r   c                     U R                   $ )z:The lower bound of the range. `!None` if empty or unbound.)r   r"   s    r   r   Range.lowerN        {{r   c                     U R                   $ )z:The upper bound of the range. `!None` if empty or unbound.)r   r"   s    r   r   Range.upperS   r/   r   c                     U R                   SL $ )z`!True` if the range is empty.Nr   r"   s    r   isemptyRange.isemptyX   s     ||t##r   c                 :    U R                   c  gU R                  SL $ )z0`!True` if the range doesn't have a lower bound.NFr   r   r"   s    r   	lower_infRange.lower_inf]         <<{{d""r   c                 :    U R                   c  gU R                  SL $ )z1`!True` if the range doesn't have an upper bound.NFr   r   r"   s    r   	upper_infRange.upper_infd   r:   r   c                 \    U R                   b  U R                  c  gU R                   S   S:H  $ )z4`!True` if the lower bound is included in the range.Fr   [r7   r"   s    r   	lower_incRange.lower_inck   -     <<4;;#6||A#%%r   c                 \    U R                   b  U R                  c  gU R                   S   S:H  $ )z4`!True` if the upper bound is included in the range.Fr&   ]r<   r"   s    r   	upper_incRange.upper_incr   rC   r   c                 &   U R                   c  gU R                  b4  U R                   S   S:X  a  XR                  :  a  gOXR                  ::  a  gU R                  b5  U R                   S   S:X  a  XR                  :  a  g gXR                  :  a  gg)NFr   r@   r&   rE   Tr   r   r   )r   xs     r   __contains__Range.__contains__y   s    <<;;"||A#%{{?  # # ;;"||A#%{{?  #  # r   c                     U R                   S L$ Nr3   r"   s    r   __bool__Range.__bool__   s    ||4''r   c                     [        U[        5      (       d  gU R                  UR                  :H  =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ )NF)
isinstancer   r   r   r   r   others     r   __eq__Range.__eq__   sQ    %''u||+ .u||+.-	/r   c                 .    U R                  U5      (       + $ rN   )rU   rS   s     r   __ne__Range.__ne__   s    ;;u%%%r   c                 Z    [        U R                  U R                  U R                  45      $ rN   )hashr   r   r   r"   s    r   __hash__Range.__hash__   s     T[[$++t||<==r   c                     [        U[        5      (       d  [        $ S H.  n[        X5      n[        X5      nX4:X  a  M   Uc    gUc    gX4:  s  $    g)Nr   TF)rR   r   NotImplementedgetattr)r   rT   attr
self_valueother_values        r   __lt__Range.__lt__   s\    %''!!3D ,J!%.K(#$!// 4 r   c                 0    X:X  a  gU R                  U5      $ NT)rd   rS   s     r   __le__Range.__le__       =;;u%%r   c                 Z    [        U[        5      (       a  UR                  U 5      $ [        $ rN   )rR   r   rd   r_   rS   s     r   __gt__Range.__gt__   s$    eU##<<%%!!r   c                 0    X:X  a  gU R                  U5      $ rg   )rl   rS   s     r   __ge__Range.__ge__   rj   r   c                 ~    U R                    Vs0 s H!  n[        X5      (       d  M  U[        X5      _M#     sn$ s  snf rN   )	__slots__hasattrr`   )r   slots     r   __getstate__Range.__getstate__   s>    ?&'$*= *gd))&? 	? ?s   ::c                 N    UR                  5        H  u  p#[        XU5        M     g rN   )r*   setattr)r   statert   values       r   __setstate__Range.__setstate__   s     ;;=KDD& )r   rI   )NNr   F)r    
__module____qualname____firstlineno____doc__rr   r   r#   r+   propertyr   r   r4   r8   r=   rA   rF   rK   rO   rU   rX   r\   rd   rh   rl   ro   ru   r{   __static_attributes__ r   r   r   r   #   s     0I	<8     $ $ # # # # & & & &,(/&> &"&?'r   r   c                     [         R                  XU5      nUR                  U(       + =(       a    U=(       d    S5        U$ )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_ranger      s5    4 !!'LAF
\2l:d;Mr   c                   4    \ rS rSrSrSrS rS rS rS r	Sr
g)	RangeAdapter   z`ISQLQuote` adapter for `Range` subclasses.

This is an abstract class: concrete classes must set a `name` class
attribute or override `getquoted()`.
Nc                     Xl         g rN   )adapted)r   r   s     r   r   RangeAdapter.__init__   s    r   c                 .    U R                   [        L a  U $ g rN   )_protor   )r   protos     r   __conform__RangeAdapter.__conform__   s    ;;)#K $r   c                     Xl         g rN   )_conn)r   conns     r   prepareRangeAdapter.prepare   s    
r   c                    U R                   c  [        S5      eU R                  nUR                  (       a  SU R                   R	                  S5      -   $ UR
                  bR  [        UR
                  5      n[        US5      (       a  UR                  U R                  5        UR                  5       nOSnUR                  bR  [        UR                  5      n[        US5      (       a  UR                  U R                  5        UR                  5       nOSnU R                   R	                  S5      S-   U-   S-   U-   S-   UR                  R	                  S5      -   S	-   $ )
NzMRangeAdapter must be subclassed overriding its name or the getquoted() methods	   'empty'::utf8r   s   NULL   (s   , s   , 's   '))nameNotImplementedErrorr   r4   encoder   r   rs   r   r   	getquotedr   r   )r   rar   r   s        r   r   RangeAdapter.getquoted   s$   99%,- - LL99$))"2"26":::77aggAq)$$		$**%KKMEE77aggAq)$$		$**%KKMEEyy'$.6>Fyy''/0278 	8r   )r   r   )r    r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r      s"    
 D8r   r   c                       \ rS rSrSrSS jrS r\S 5       r\	R                  " S\	R                  5      r\	R                  " S5      rSS	 jrSS
 jrSrg)r   i  zHelper 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                 :   X@l         U R                  X5        U R                  R                  =(       d     U R                  R                  R
                  n[        U4X`R                  5      U l        Ub!  [        U4US-   U R                  5      U l
        g S U l
        g )NARRAY)subtype_oid_create_rangesadapterr   r   r    r   parse
typecasterr	   array_typecaster)r   r   r   oidr   	array_oidr   s          r   r   RangeCaster.__init__$  s|    &G-||  CDLL$:$:$C$C"C64< $2dWndoo%?D! %)D!r   c                 &   SU l         [        U[        5      (       a(  [        U[        40 5      U l         XR                   l        O% [        U[        5      (       a  U[        La  Xl         U R                   c  [        S5      eSU l         [        U[        5      (       a  [        U[        40 5      U l        [        U[        5      (       a  U[        La  X l        U R                  c  [        S5      eg! [         a     Nf = f! [         a     N5f = f)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   rR   r(   typer   r   
issubclass	TypeErrorranger   )r   r   r   s      r   r   RangeCaster._create_ranges2  s    gs##,"=DL 'LLg|44#<7#*L <<LN N 
	'3''!'E8R8
'5))gU.B$
 ::CE E !    		s%   $C3 
AD 3
D ?D 
DDc                 (   SSK Jn  SSKJn  U" U5      u  pgUR                  R
                  S:  a"  [        SUR                  R
                  -  5      eUR                  nSU;   a  UR                  SS5      u  pOUn
Sn	UR                  S	X45        UR                  5       nU(       do   S
nUR                  U:X  a  UR                  S5        SnUR                  SU45        UR                  5       nU(       a  USS u  pW(       a  UR                  S5        X:w  a!  UR                  (       d  UR                  5         U(       d  [        SU S35      eUSS u  pn[        XXUS9$ ! [         a     Nsf = f! W(       a  UR                  S5        f f = f)zlReturn 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rollbackr   )r   r   r   r   r   r   r   cursconn_statusschematnamerec	savepointr   subtypearrays                   r   r   RangeCaster._from_dbU  s    	>4%l3
99##e+"#L))**$+ , , kk $; JJsA.MFEEF 	  _	 mmoH!	 ;;"77LL!:; $I  X mmo$'GMELL!FG /MMO"$TF+68 8  #2Awu4U< 	<) $  LL!FG s*   )8E& !E6 &
E30E6 2E33E6 6F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                 ~   Uc  g US:X  a  U R                  SS9$ U R                  R                  U5      nUc  [        SU S35      eUR	                  S5      nUc0  UR	                  S5      nUb  U R
                  R                  SU5      nUR	                  S	5      nUc0  UR	                  S
5      nUb  U R
                  R                  SU5      nUb8  UR                  U R                  U5      nUR                  U R                  U5      nUR	                  S5      UR	                  S5      -   nU R                  XEU5      $ )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   RangeCaster.parse  s&   9<::D:))NN  #9 #;A3a!@AA
=GGAJE ))--eU;
=GGAJE ))--eU;?HHT--u5EHHT--u5Eaggaj(zz%//r   c                     [        U R                  U5        U R                  b  [        U R                  U5        [        U R                  U R
                  5        g rN   )r
   r   r   r   r   r   )r   scopes     r   r   RangeCaster._register  s>    doou-  ,$//7T\\2r   )r   r   r   r   r   rN   )r    r}   r~   r   r   r   r   classmethodr   recompileVERBOSEr   r   r   r   r   r   r   r   r   r     sb    )!EF J< J<X 

  ZZI ::l+L0>3r   r   c                       \ rS rSrSrSrg)NumericRangei  zA `Range` suitable to pass Python numeric types to a PostgreSQL range.

PostgreSQL types :sql:`int4range`, :sql:`int8range`, :sql:`numrange` are
casted into `!NumericRange` instances.
r   Nr    r}   r~   r   r   r   r   r   r   r   r     s    
 	r   r   c                       \ rS rSrSrSrg)	DateRangei  z#Represents :sql:`daterange` values.r   Nr   r   r   r   r   r         -r   r   c                       \ rS rSrSrSrg)DateTimeRangei  z!Represents :sql:`tsrange` values.r   Nr   r   r   r   r   r     s    +r   r   c                       \ rS rSrSrSrg)DateTimeTZRangei  z#Represents :sql:`tstzrange` values.r   Nr   r   r   r   r   r     r   r   r   c                       \ rS rSrSrS rSrg)NumberRangeAdapteri  z1Adapt a range if the subtype doesn't need quotes.c                    U R                   nUR                  (       a  gUR                  (       d3  [        UR                  5      R                  5       R                  S5      nOSnUR                  (       d3  [        UR                  5      R                  5       R                  S5      nOSnSUR                  S    U SU UR                  S    S3R                  S5      $ )Ns   'empty'asciir'   r   r   ,r&   )r   r4   r8   r   r   r   decoder=   r   r   r   )r   r   r   r   s       r   r   NumberRangeAdapter.getquoted  s    LL99{{
 !''N,,.55g>EE{{!''N,,.55g>EEAIIaL>%%1a@HHQQr   r   N)r    r}   r~   r   r   r   r   r   r   r   r   r     s    ;Rr   r   i@     iA  r   iV     iW  iB  i  iC  	daterangeiH  i:  iI  tsrangeiD  iZ  iE  	tstzrangeiF  i  iG  )F)r   r   psycopg2._psycopgr   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   int4range_casterr   int8range_casternumrange_casterdaterange_castertsrange_castertstzrange_casterr   r   r   <module>r     sb  6 
 > B B G Gh' h'V>-8 -8`y3 y3x	5 		 	
	E 	
	e 	R R2 1 2
 1<".     1<".     0,$$0    {I$$0     Y$$0    {O$$0     r   