
    +h>H                     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j-                           eeeddd      Zej-                           eeeddd       Zej-                           ed!ed"d#d$      Zej-                           ed%ed&d'd(      Zej-                           ed)ed*d+d,      Zej-                          y).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y)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_boundsNc                     |s(|dvrt        d|      || _        || _        || _        y d x| _        x| _        | _        y )N)[)z(]z()z[]zbound flags not valid: )
ValueErrorr   r   r   )selflowerupperboundsemptys        B/var/www/html/venv/lib/python3.12/site-packages/psycopg2/_range.py__init__zRange.__init__/   sK    55 #:6*!EFFDKDK!DL7;;DK;$+    c                     | j                   | j                  j                   dS dj                  | 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__:   sV    <<nn--.l;;)001H1HT[[$,,8 8r   c                     | j                   y| j                   d   t        | j                        dt        | j                        | j                   d   g}dj	                  |      S )Nr   r   z,     )r   strr   r   join)r   itemss     r   __str__zRange.__str__A   sY    << LLOLL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                 8    | j                   y| 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]         <<{{d""r   c                 8    | j                   y| 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                 X    | j                   | j                  y| j                   d   dk(  S )z4`!True` if the lower bound is included in the range.Fr   [r0   r    s    r   	lower_inczRange.lower_inck   -     <<4;;#6||A#%%r   c                 X    | j                   | j                  y| j                   d   dk(  S )z4`!True` if the upper bound is included in the range.Fr#   ]r4   r    s    r   	upper_inczRange.upper_incr   r9   r   c                    | j                   y| j                  2| j                   d   dk(  r|| j                  k  ry|| j                  k  ry| j                  3| j                   d   dk(  r|| j                  kD  ryy|| j                  k\  ryy)NFr   r7   r#   r;   T)r   r   r   )r   xs     r   __contains__zRange.__contains__y   s    <<;;"||A#%t{{? # ;;"||A#%t{{? 
  # r   c                     | j                   d uS Nr-   r    s    r   __bool__zRange.__bool__   s    ||4''r   c                     t        |t              sy| j                  |j                  k(  xr4 | j                  |j                  k(  xr | j                  |j                  k(  S )NF)
isinstancer   r   r   r   r   others     r   __eq__zRange.__eq__   sN    %'u||+ .u||+.-	/r   c                 &    | j                  |       S rA   )rG   rE   s     r   __ne__zRange.__ne__   s    ;;u%%%r   c                 Z    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!| y| y||k  c S  y)Nr   TF)rD   r   NotImplementedgetattr)r   rF   attr
self_valueother_values        r   __lt__zRange.__lt__   sf    %'!!3 
	0D t,J!%.K[(#$!K//
	0 r   c                 0    | |k(  ry| j                  |      S NT)rS   rE   s     r   __le__zRange.__le__       5=;;u%%r   c                 P    t        |t              r|j                  |       S t        S rA   )rD   r   rS   rN   rE   s     r   __gt__zRange.__gt__   s!    eU#<<%%!!r   c                 0    | |k(  ry| j                  |      S rU   )rY   rE   s     r   __ge__zRange.__ge__   rW   r   c                 n    | j                   D ci c]  }t        | |      r|t        | |       c}S c c}w rA   )	__slots__hasattrrO   )r   slots     r   __getstate__zRange.__getstate__   s;    ?'$*= gdD)) ? 	? ?s    2c                 N    |j                         D ]  \  }}t        | ||        y rA   )r'   setattr)r   stater_   values       r   __setstate__zRange.__setstate__   s'     ;;= 	'KD%D$&	'r   )NNr   F)r   
__module____qualname____doc__r]   r   r!   r(   propertyr   r   r.   r1   r5   r8   r<   r?   rB   rG   rI   rL   rS   rV   rY   r[   r`   re    r   r   r   r   #   s     0I	<8     $ $ # # # # & & & &,(/&> &"&?'r   r   c                 h    t         j                  | ||      }|j                  | xr |xs 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_rangert      s7    4 !!'7LAF
\2l:d;Mr   c                   ,    e Zd ZdZdZd Zd Zd Zd Zy)RangeAdapterz`ISQLQuote` adapter for `Range` subclasses.

    This is an abstract class: concrete classes must set a `name` class
    attribute or override `getquoted()`.
    Nc                     || _         y rA   )adapted)r   rx   s     r   r   zRangeAdapter.__init__   s	    r   c                 ,    | j                   t        u r| S y rA   )_protor   )r   protos     r   __conform__zRangeAdapter.__conform__   s    ;;)#K $r   c                     || _         y rA   )_conn)r   conns     r   preparezRangeAdapter.prepare   s	    
r   c                    | j                   t        d      | j                  }|j                  rd| j                   j	                  d      z   S |j
                  Mt        |j
                        }t        |d      r|j                  | j                         |j                         }nd}|j                  Mt        |j                        }t        |d      r|j                  | j                         |j                         }nd}| j                   j	                  d      dz   |z   dz   |z   dz   |j                  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NotImplementedErrorrx   r.   encoder   r   r^   r   r~   	getquotedr   r   )r   rar   r   s        r   r   z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   rf   rg   rh   r   r   r|   r   r   rj   r   r   rv   rv      s"    
 D8r   rv   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y)rl   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                 4   || _         | j                  ||       | j                  j                  xs  | j                  j                  j
                  }t        |f|| j                        | _        |!t        |f|dz   | j                        | _
        y d | _
        y )NARRAY)subtype_oid_create_rangesadapterr   r   r   r   parse
typecasterr	   array_typecaster)r   ro   rp   oidr   	array_oidr   s          r   r   zRangeCaster.__init__$  s    &GW-||  CDLL$:$:$C$C"C64< $2dWndoo%?D! %)D!r   c                    d| _         t        |t              r)t        |t        fi       | _         || j                   _        n 	 t        |t              r|t        ur|| _         | j                   t        d      d| _        	 t        |t              rt        |t        fi       | _        t        |t              r|t        ur|| _        | j                  t        d      y# t        $ r Y w xY w# t        $ r Y 2w xY w)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%   typerv   r   
issubclass	TypeErrorranger   )r   ro   rp   s      r   r   zRangeCaster._create_ranges2  s     gs#,"=DL 'DLLg|4#<7#*DL <<LN N 
	'3'!'E8R8
'5)gU.B$
 ::CE E !    		s%   C  AC- 	C*)C*-	C98C9c                    ddl m} ddlm}  ||      \  }}|j                  j
                  dk  r"t        d|j                  j
                  z        |j                  }d|v r|j                  dd      \  }	}
n|}
d}	|j                  d	|
|	f       |j                         }|sg	 d
}|j                  |k(  r|j                  d       d}|j                  d|f       |j                         }|r	|dd \  }
}		 r|j                  d       	 ||k7  r|j                  s|j                          |st        d| d      |dd \  }}}t        |||||      S # t        $ r Y jw xY w# r|j                  d       w w xY w)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rollbackrl   )r   r   rp   rq   r   r   r   cursconn_statusschematnamerec	savepointr   subtypearrays                   r   rm   zRangeCaster._from_dbU  s    	>4%l3
d99##e+"#L))**$+ , , kk $; JJsA.MFEEF 	  V_	 mmoH!	 ;;"77LL!:; $I  X mmo$'GME6LL!FG //MMO"$TF+68 8  #2Awgu4'U< 	<) $  LL!FG s*   $7E E$ 	E!E$  E!!E$ $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                 v   |y |dk(  r| j                  d      S | j                  j                  |      }|t        d| d      |j	                  d      }|/|j	                  d      }|| j
                  j                  d|      }|j	                  d	      }|/|j	                  d
      }|| j
                  j                  d|      }|8|j                  | j                  |      }|j                  | j                  |      }|j	                  d      |j	                  d      z   }| j                  |||      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  s(   9<::D:))NN  #9 #;A3a!@AA
=GGAJE ))--eU;
=GGAJE ))--eU;?HHT--u5EHHT--u5Eaggaj(zz%//r   c                     t        | j                  |       | j                  t        | j                  |       t        | j                  | j
                         y rA   )r
   r   r   r   r   r   )r   scopes     r   rn   zRangeCaster._register  s>    doou-  ,$//7T\\2r   rA   )r   rf   rg   rh   r   r   classmethodrm   recompileVERBOSEr   r   r   rn   rj   r   r   rl   rl     sf    )!EF J< J<X 

  ZZI 2::l+L0>3r   rl   c                       e Zd ZdZy)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   rf   rg   rh   rj   r   r   r   r     s    
 	r   r   c                       e Zd ZdZy)	DateRangez#Represents :sql:`daterange` values.Nr   rj   r   r   r   r         -r   r   c                       e Zd ZdZy)DateTimeRangez!Represents :sql:`tsrange` values.Nr   rj   r   r   r   r     s    +r   r   c                       e Zd ZdZy)DateTimeTZRangez#Represents :sql:`tstzrange` values.Nr   rj   r   r   r   r     r   r   r   c                       e Zd ZdZd Zy)NumberRangeAdapterz1Adapt a range if the subtype doesn't need quotes.c                    | j                   }|j                  ry|j                  s3t        |j                        j                         j                  d      }nd}|j                  s3t        |j                        j                         j                  d      }nd}d|j                  d    | d| |j                  d    dj                  d      S )Ns   'empty'asciir$   r   r   ,r#   )rx   r.   r1   r   r   r   decoder5   r   r   r   )r   r   r   r   s       r   r   zNumberRangeAdapter.getquoted  s    LL99{{
 !''N,,.55g>EE{{!''N,,.55g>EEAIIaL>%%1a@HHQQr   N)r   rf   rg   rh   r   rj   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)rh   r   psycopg2._psycopgr   r   r   r   r   r   r   r	   r
   r   rt   rv   rl   r   r   r   r   r   int4range_casterrn   int8range_casternumrange_casterdaterange_castertsrange_castertstzrange_casterrj   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   