
    ,hYE                         S r SSKJr  SSKrSSKJr  SSKJr  SSK	Jr
  SSKJr  SSKJr  SSKJr  SS	KJr  SSKJr  \R&                  " \5      r " S
 S5      r " S S5      r " S S5      r\R2                  rg)zBaked query extension.

Provides a creational pattern for the :class:`.query.Query` object which
allows the fully constructed object, Core select statement, and string
compiled result to be fully cached.


    N   )exc)util)Query)Session)func)literal_columnc                   (    \ rS rSrSrSrS rS rSrg)Bakery#   zCallable which returns a :class:`.BakedQuery`.

This object is returned by the class method
:meth:`.BakedQuery.bakery`.  It exists as an object
so that the "cache" can be easily inspected.

.. versionadded:: 1.2


clscachec                     Xl         X l        g Nr   )selfcls_r   s      L/var/www/auris/envauris/lib/python3.13/site-packages/sqlalchemy/ext/baked.py__init__Bakery.__init__1   s    
    c                 :    U R                  U R                  X5      $ r   r   )r   
initial_fnargss      r   __call__Bakery.__call__5   s    xx

J55r   )r   r   N)	__name__
__module____qualname____firstlineno____doc__	__slots__r   r   __static_attributes__ r   r   r   r   #   s    	 I6r   r   c                       \ rS rSrSrSrSS jr\SS j5       rS r	SS jr
S	 rS
 rS rS rS rS rSS jrS rSS jrSS jrS rS rS rS rSrg)
BakedQuery9   z3A builder object for :class:`.query.Query` objects.)steps_bakery
_cache_key_spoiledc                 ^    SU l         U R                  X#5        U/U l        SU l        Xl        g )Nr$   F)r*   _update_cache_keyr(   r+   r)   )r   bakeryr   r   s       r   r   BakedQuery.__init__>   s,    z0 \
r   Nc                 >    [        U [        R                  " XS95      $ )zCConstruct a new bakery.

:return: an instance of :class:`.Bakery`

)
size_alert)r   r   LRUCache)r   size_size_alerts      r   r.   BakedQuery.bakeryE   s     c4==FGGr   c                     [         R                  [         5      nU R                  Ul        [        U R                  5      Ul        U R
                  Ul        U R                  Ul        U$ r   )r&   __new__r*   listr(   r)   r+   )r   b1s     r   _cloneBakedQuery._cloneO   sH    
+

#\\
mm	r   c                 J    U =R                   UR                  4U-   -  sl         g r   )r*   __code__r   fnr   s      r   r-   BakedQuery._update_cache_keyW   s    BKK>D00r   c                 t    [        U[        5      (       a  U R                  " U6   U $ U R                  U5        U $ r   )
isinstancetupleadd_criteriar   others     r   __iadd__BakedQuery.__iadd__Z   s9    eU##u%  e$r   c                 l    [        U[        5      (       a  U R                  " U6 $ U R                  U5      $ r   )rB   rC   with_criteriarE   s     r   __add__BakedQuery.__add__a   s1    eU##%%u--%%e,,r   c                 ^    U R                  X5        U R                  R                  U5        U $ )zAdd a criteria function to this :class:`.BakedQuery`.

This is equivalent to using the ``+=`` operator to
modify a :class:`.BakedQuery` in-place.

)r-   r(   appendr>   s      r   rD   BakedQuery.add_criteriag   s)     	r(

"r   c                 D    U R                  5       R                  " U/UQ76 $ )zAdd a criteria function to a :class:`.BakedQuery` cloned from this
one.

This is equivalent to using the ``+`` operator to
produce a new :class:`.BakedQuery` with modifications.

)r:   rD   r>   s      r   rJ   BakedQuery.with_criteriar   s      {{}))"4t44r   c                     [        X5      $ )zReturn a :class:`_baked.Result` object for this
:class:`.BakedQuery`.

This is equivalent to calling the :class:`.BakedQuery` as a
Python callable, e.g. ``result = my_baked_query(session)``.

)Resultr   sessions     r   for_sessionBakedQuery.for_session|   s     d$$r   c                 $    U R                  U5      $ r   )rV   rT   s     r   r   BakedQuery.__call__   s    ((r   c                     U(       dH  U R                   (       d7  U R                  5       nU=R                  S-  sl        UR                  /U l        SU l         U $ )a  Cancel any query caching that will occur on this BakedQuery object.

The BakedQuery can continue to be used normally, however additional
creational functions will not be cached; they will be called
on every invocation.

This is to support the case where a particular step in constructing
a baked query disqualifies the query from being cacheable, such
as a variant that relies upon some uncacheable value.

:param full: if False, only functions added to this
 :class:`.BakedQuery` object subsequent to the spoil step will be
 non-cached; the state of the :class:`.BakedQuery` up until
 this point will be pulled from the cache.   If True, then the
 entire :class:`_query.Query` object is built from scratch each
 time, with all creational functions being called on each
 invocation.

)_query_onlyT)r+   r:   r*   _retrieve_baked_queryr(   )r   full_spoil_points      r   spoilBakedQuery.spoil   sF    ( DMM;;=L##'77#&<<=DJr   c                 6    U R                   UR                  4-   $ )as  Return the key that actually goes into the cache dictionary for
this :class:`.BakedQuery`, taking into account the given
:class:`.Session`.

This basically means we also will include the session's query_class,
as the actual :class:`_query.Query` object is part of what's cached
and needs to match the type of :class:`_query.Query` that a later
session will want to use.

)r*   
_query_clsrT   s     r   _effective_keyBakedQuery._effective_key   s     '"4"4!666r   c                 F    U R                  5       nUR                  XUS9  U$ )z)Cloning version of _add_lazyload_options.)
cache_path)r:   _add_lazyload_options)r   optionseffective_pathrf   qs        r   _with_lazyload_options!BakedQuery._with_lazyload_options   s%    KKM	JOr   c                 4  ^^ SnU(       d  TnT Hc  nUR                   (       d  UR                  (       d  M'  UR                  5       nUc  U R                  SS9  MK  US   (       a   S5       eXFS   -  nMe     U R	                  UU4S jUR
                  U5        g)	a  Used by per-state lazy loaders to add options to the
"lazy load" query from a parent query.

Creates a cache key based on given load path and query options;
if a repeatable cache key cannot be generated, the query is
"spoiled" so that it won't use caching.

r$   NT)r]      zloader options with variable bound parameters not supported with baked queries.  Please use new-style select() statements for cached ORM queries.r   c                 @   > U R                  T5      R                  " T6 $ r   )_with_current_pathrh   )rj   ri   rh   s    r   <lambda>2BakedQuery._add_lazyload_options.<locals>.<lambda>   s    a**>:BBGLr   )_is_legacy_option_is_compile_state_generate_cache_keyr_   rD   path)r   rh   ri   rf   keyoptcks    ``    r   rg    BakedQuery._add_lazyload_options   s     'JC$$(=(=(=,,.:JJDJ)!!u '9 a5LC  	LOO	
r   c                     U R                   R                  U R                  U5      S 5      nUc>  U R                  U5      nUR	                  S 5      U R                   U R                  U5      '   UR	                  U5      $ r   )r)   getrc   	_as_querywith_session)r   rU   querys      r   r\    BakedQuery._retrieve_baked_query   sp      !4!4W!=tD=NN7+E9>9K9K:DLL,,W56 !!'**r   c                     U R                  U5      nS Ul        UR                  5       nUR                  R                  (       a   UU4U R
                  U R                  U5      '   X#4$ r   )r}   rU   _statement_20_compile_options_bake_okr)   rc   )r   rU   r   	statements       r   _bakeBakedQuery._bake   sd    w' '')	 %%..:DLL,,W56
 r   c                     [        U[        5      (       a  UnOR[        U[        5      (       a&  UR                  nUc  [        R
                  " S5      eO[        S[        U5      -  5      eU R                  U5      $ )ah  Return the :class:`_query.Query` object for use as a subquery.

This method should be used within the lambda callable being used
to generate a step of an enclosing :class:`.BakedQuery`.   The
parameter should normally be the :class:`_query.Query` object that
is passed to the lambda::

    sub_bq = self.bakery(lambda s: s.query(User.name))
    sub_bq += lambda q: q.filter(User.id == Address.user_id).correlate(Address)

    main_bq = self.bakery(lambda s: s.query(Address))
    main_bq += lambda q: q.filter(sub_bq.to_query(q).exists())

In the case where the subquery is used in the first callable against
a :class:`.Session`, the :class:`.Session` is also accepted::

    sub_bq = self.bakery(lambda s: s.query(User.name))
    sub_bq += lambda q: q.filter(User.id == Address.user_id).correlate(Address)

    main_bq = self.bakery(
        lambda s: s.query(Address.id, sub_bq.to_query(q).scalar_subquery())
    )

:param query_or_session: a :class:`_query.Query` object or a class
 :class:`.Session` object, that is assumed to be within the context
 of an enclosing :class:`.BakedQuery` callable.


 .. versionadded:: 1.3


z1Given Query needs to be associated with a Sessionz)Query or Session object expected, got %r.)	rB   r   r   rU   sa_excArgumentError	TypeErrortyper}   )r   query_or_sessionrU   s      r   to_queryBakedQuery.to_query   s    D &00&G(%00&..G**G  
 ;'()  ~~g&&r   c                 l    U R                   S   " U5      nU R                   SS   H  nU" U5      nM     U$ Nr   rn   )r(   )r   rU   r   steps       r   r}   BakedQuery._as_query-  s8    

1g&JJqrNDKE # r   )r)   r*   r+   r(   )r$   )   N)Fr   )r   r   r   r    r!   r"   r   classmethodr.   r:   r-   rG   rK   rD   rJ   rV   r   r_   rc   rk   rg   r\   r   r   r}   r#   r$   r   r   r&   r&   9   sw    =<I H H1-	5%)67!
F+ 2/'br   r&   c                   |    \ 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S rS rS rS rS rS rS rS rSrg)rS   i6  a  Invokes a :class:`.BakedQuery` against a :class:`.Session`.

The :class:`_baked.Result` object is where the actual :class:`.query.Query`
object gets created, or retrieved from the cache,
against a target :class:`.Session`, and is then invoked for results.

bqrU   _params_post_criteriac                 8    Xl         X l        0 U l        / U l        g r   r   )r   r   rU   s      r   r   Result.__init__A  s     r   c                     [        U5      S:X  a  UR                  US   5        O%[        U5      S:  a  [        R                  " S5      eU R                  R                  U5        U $ )z@Specify parameters to be replaced into the string SQL statement.rn   r   zFparams() takes zero or one positional argument, which is a dictionary.)lenupdater   r   r   )r   r   kws      r   paramsResult.paramsG  s[     t9>IId1gY]&&)  	Br   c                 J    U(       a  U R                   R                  U5        U $ r   )r   extend)r   fnss     r   _using_post_criteriaResult._using_post_criteriaT  s    &&s+r   c                 &    U R                  U/5      $ )a|  Add a criteria function that will be applied post-cache.

This adds a function that will be run against the
:class:`_query.Query` object after it is retrieved from the
cache.    This currently includes **only** the
:meth:`_query.Query.params` and :meth:`_query.Query.execution_options`
methods.

.. warning::  :meth:`_baked.Result.with_post_criteria`
   functions are applied
   to the :class:`_query.Query`
   object **after** the query's SQL statement
   object has been retrieved from the cache.   Only
   :meth:`_query.Query.params` and
   :meth:`_query.Query.execution_options`
   methods should be used.


.. versionadded:: 1.2


)r   )r   r?   s     r   with_post_criteriaResult.with_post_criteriaY  s    . (("..r   c                     U R                   R                  U R                  5      R                  U R                  5      nU R
                   H  nU" U5      nM     U$ r   )r   r}   rU   r   r   r   )r   rj   r?   s      r   r}   Result._as_queryr  sG    GGdll+224<<@%%B1A &r   c                 4    [        U R                  5       5      $ r   )strr}   r   s    r   __str__Result.__str__x  s    4>>#$$r   c                 >    U R                  5       R                  5       $ r   )_iter__iter__r   s    r   r   Result.__iter__{  s    zz|$$&&r   c                 ~   U R                   nU R                  R                  (       a  UR                  (       a  U R	                  5       R                  5       $ UR                  R                  UR                  U R                  5      S5      u  p#Uc  UR                  U R                  5      u  p#U R                  (       a  UR                  U R                  5      nOUnU R                   H  nU" U5      nM     UR                  n[        UR                  5      nUR                  UR                   UR                  S.5        U R                  R#                  X6US9nUR$                  R                  SS5      (       a  UR'                  5       nUR$                  R                  SS5      (       a  UR)                  5       nU$ )N)NN)_sa_orm_load_optionscompiled_cache)execution_optionsis_single_entityFfiltered)r   rU   enable_baked_queriesr+   r}   r   r)   r|   rc   r   r   r   r   dict_execution_optionsr   load_optionsexecute_attributesscalarsunique)	r   r   r   r   rj   r?   r   r   results	            r   r   Result._iter~  s_   WW||00BKK>>#))++::>>dll+\
 =!xx5E<<T\\*AA%%B1A &  !5!56  ()"$**	
 %%1B & 
 !!"4e<<^^%F!!*e44]]_Fr   c                   ^ [         R                  " [        S5      5      mU R                  R	                  U4S j5      nUR                  U R                  5      R                  U R                  5      R                  5       $ )zreturn the 'count'.

Equivalent to :meth:`_query.Query.count`.

Note this uses a subquery to ensure an accurate count regardless
of the structure of the original statement.

*c                 &   > U R                  T5      $ r   )_legacy_from_self)rj   cols    r   rq   Result.count.<locals>.<lambda>  s    Q-@-@-Er   )
r   countr	   r   rJ   rV   rU   r   r   scalar)r   r   r   s     @r   r   Result.count  sX     jj,-WW""#EF~~dll+224<<@GGIIr   c                      U R                  5       n[        U[        R                  5      (       d  U$ US   $ ! [        R
                   a     gf = f)zReturn the first element of the first result or None
if no rows present.  If multiple rows are returned,
raises MultipleResultsFound.

Equivalent to :meth:`_query.Query.scalar`.

r   N)onerB   collections_abcSequenceorm_excNoResultFound)r   rets     r   r   Result.scalar  sK    	((*Cc?#;#;<<
q6M$$ 		s   08 8 AAc                    U R                   R                  S 5      nUR                  U R                  5      R	                  U R
                  5      R                  U R                  5      R                  5       R                  5       $ )zBReturn the first row.

Equivalent to :meth:`_query.Query.first`.

c                 &    U R                  SS5      $ r   )slice)rj   s    r   rq   Result.first.<locals>.<lambda>  s    QWWQ]r   )
r   rJ   rV   rU   r   r   r   r   r   first)r   r   s     r   r   Result.first  s[     WW""#:;NN4<<(VDLL!!!$"5"56UWUW	
r   c                 >    U R                  5       R                  5       $ )z[Return exactly one result or raise an exception.

Equivalent to :meth:`_query.Query.one`.

)r   r   r   s    r   r   
Result.one       zz|!!r   c                 >    U R                  5       R                  5       $ )zwReturn one or zero results, or raise an exception for multiple
rows.

Equivalent to :meth:`_query.Query.one_or_none`.

)r   one_or_noner   s    r   r   Result.one_or_none  s     zz|''))r   c                 >    U R                  5       R                  5       $ )z;Return all rows.

Equivalent to :meth:`_query.Query.all`.

)r   allr   s    r   r   
Result.all  r   r   c                     U R                   R                  S   " U R                  5      nUR                  XR                  5      $ )zPRetrieve an object based on identity.

Equivalent to :meth:`_query.Query.get`.

r   )r   r(   rU   	_get_impl_load_on_pk_identity)r   identr   s      r   r|   
Result.get  s4     a .u&?&?@@r   c                 h  ^ ^^^^ UR                   S   R                  S   mTR                  u  mmUUUUU 4S jnT R                  nUR	                  5       nU=R
                  T4-  sl        UR                  U[        S T 5       5      5      n[        TTR                  5       VVs0 s H  u  pxTU   R                  U_M     n	nn[        UR                  T R                  5      R                  " S0 U	D65      n
[        U
5      nUS:  a  [         R"                  " 5       eU(       a  U
S   $ gs  snnf )z6Load the given primary key identity from the database.r   parententityc                   > TnU R                  5       nUR                  5         S Ul        S T
;   aR  [        T	R                  T
5       VVs1 s H  u  p4Ub  M
  TU   R
                  iM     nnn[        R                  " X5      n[        R                  " USS05      4Ul	        TR                   H  nU" U5      nM     U$ s  snnf )N
_orm_adaptT)r:   _get_condition	_order_byzipprimary_keyrw   sql_utiladapt_criterion_to_null_deep_annotate_where_criteriar   )r   _lcl_get_clauserj   r   valuenonesr?   _get_clause_get_paramsmapperprimary_key_identityr   s          r   setup*Result._load_on_pk_identity.<locals>.setup  s    )OAAK ++ '***,@''
 	 )K$(('   #+"B"B## '',9MN!A ))qE *H%s   
	B?B?c              3   (   #    U  H  oS L v   M
     g 7fr   r$   ).0elems     r   	<genexpr>.Result._load_on_pk_identity.<locals>.<genexpr>&  s     G2F$2Fs   rn   Nr$   )_raw_columns_annotationsr   r   r:   r*   rJ   rC   r   r   rw   r8   rV   rU   r   r   r   MultipleResultsFound)r   rU   r   r   r   r   r   id_valr   r   r   lr   r   r   s   `  `        @@@r   r   Result._load_on_pk_identity  s(    ##A&33NC#)#5#5 [	 	@ WW
 YY[
+'5G2FGG
 (+$f&8&8(
(# $((&0( 	 
 bnnT\\299CFCDKq5..00!9
s   (D.)r   r   r   rU   N)r   r   r   r    r!   r"   r   r   r   r   r}   r   r   r   r   r   r   r   r   r   r|   r   r#   r$   r   r   rS   rS   6  sb     =I!
/2%'%NJ 
 "*"AAr   rS   )r!   collections.abcabcr   logging r   r   r   ormr   	orm.queryr   orm.sessionr   sqlr   r	   r   	getLoggerr   logr   r&   rS   r.   r$   r   r   <module>r     sm    *       !    " !6 6,z zzA AH 
		r   