<s> """<STR_LIT>""" <EOL> from . . orm . query import Query <EOL> from . . orm import strategies , attributes , properties , strategy_options , util as orm_util , interfaces <EOL> from . . import log as sqla_log <EOL> from . . sql import util as sql_util <EOL> from . . orm import exc as orm_exc <EOL> from . . import exc as sa_exc <EOL> from . . import util <EOL> import copy <EOL> import logging <EOL> log = logging . getLogger ( __name__ ) <EOL> class BakedQuery ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' <EOL> def __init__ ( self , bakery , initial_fn , args = ( ) ) : <EOL> self . _cache_key = ( ) <EOL> self . _update_cache_key ( initial_fn , args ) <EOL> self . steps = [ initial_fn ] <EOL> self . _spoiled = False <EOL> self . _bakery = bakery <EOL> @ classmethod <EOL> def bakery ( cls , size = <NUM_LIT:200> ) : <EOL> """<STR_LIT>""" <EOL> _bakery = util . LRUCache ( size ) <EOL> def call ( initial_fn , * args ) : <EOL> return cls ( _bakery , initial_fn , args ) <EOL> return call <EOL> def _clone ( self ) : <EOL> b1 = BakedQuery . __new__ ( BakedQuery ) <EOL> b1 . _cache_key = self . _cache_key <EOL> b1 . steps = list ( self . steps ) <EOL> b1 . _bakery = self . _bakery <EOL> b1 . _spoiled = self . _spoiled <EOL> return b1 <EOL> def _update_cache_key ( self , fn , args = ( ) ) : <EOL> self . _cache_key += ( fn . __code__ , ) + args <EOL> def __iadd__ ( self , other ) : <EOL> if isinstance ( other , tuple ) : <EOL> self . add_criteria ( * other ) <EOL> else : <EOL> self . add_criteria ( other ) <EOL> return self <EOL> def __add__ ( self , other ) : <EOL> if isinstance ( other , tuple ) : <EOL> return self . with_criteria ( * other ) <EOL> else : <EOL> return self . with_criteria ( other ) <EOL> def add_criteria ( self , fn , * args ) : <EOL> """<STR_LIT>""" <EOL> self . _update_cache_key ( fn , args ) <EOL> self . steps . append ( fn ) <EOL> return self <EOL> def with_criteria ( self , fn , * args ) : <EOL> """<STR_LIT>""" <EOL> return self . _clone ( ) . add_criteria ( fn , * args ) <EOL> def for_session ( self , session ) : <EOL> """<STR_LIT>""" <EOL> return Result ( self , session ) <EOL> def __call__ ( self , session ) : <EOL> return self . for_session ( session ) <EOL> def spoil ( self , full = False ) : <EOL> """<STR_LIT>""" <EOL> if not full : <EOL> _spoil_point = self . _clone ( ) <EOL> _spoil_point . _cache_key += ( '<STR_LIT>' , ) <EOL> self . steps = [ _spoil_point . _retrieve_baked_query ] <EOL> self . _spoiled = True <EOL> return self <EOL> def _retrieve_baked_query ( self , session ) : <EOL> query = self . _bakery . get ( self . _cache_key , None ) <EOL> if query is None : <EOL> query = self . _as_query ( session ) <EOL> self . _bakery [ self . _cache_key ] = query . with_session ( None ) <EOL> return query . with_session ( session ) <EOL> def _bake ( self , session ) : <EOL> query = self . _as_query ( session ) <EOL> context = query . _compile_context ( ) <EOL> self . _bake_subquery_loaders ( session , context ) <EOL> context . session = None <EOL> context . query = query = context . query . with_session ( None ) <EOL> query . _execution_options = query . _execution_options . union ( <EOL> { "<STR_LIT>" : self . _bakery } <EOL> ) <EOL> for attr in ( <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' ) : <EOL> query . __dict__ . pop ( attr , None ) <EOL> self . _bakery [ self . _cache_key ] = context <EOL> return context <EOL> def _as_query ( self , session ) : <EOL> query = self . steps [ <NUM_LIT:0> ] ( session ) <EOL> for step in self . steps [ <NUM_LIT:1> : ] : <EOL> query = step ( query ) <EOL> return query <EOL> def _bake_subquery_loaders ( self , session , context ) : <EOL> """<STR_LIT>""" <EOL> context . attributes [ '<STR_LIT>' ] = baked_queries = [ ] <EOL> for k , v in list ( context . attributes . items ( ) ) : <EOL> if isinstance ( v , Query ) : <EOL> if '<STR_LIT>' in k : <EOL> bk = BakedQuery ( self . _bakery , lambda * args : v ) <EOL> bk . _cache_key = self . _cache_key + k <EOL> bk . _bake ( session ) <EOL> baked_queries . append ( ( k , bk . _cache_key , v ) ) <EOL> del context . attributes [ k ] <EOL> def _unbake_subquery_loaders ( self , session , context , params ) : <EOL> """<STR_LIT>""" <EOL> for k , cache_key , query in context . attributes [ "<STR_LIT>" ] : <EOL> bk = BakedQuery ( self . _bakery , lambda sess : query . with_session ( sess ) ) <EOL> bk . _cache_key = cache_key <EOL> context . attributes [ k ] = bk . for_session ( session ) . params ( ** params ) <EOL> class Result ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' <EOL> def __init__ ( self , bq , session ) : <EOL> self . bq = bq <EOL> self . session = session <EOL> self . _params = { } <EOL> def params ( self , * args , ** kw ) : <EOL> """<STR_LIT>""" <EOL> if len ( args ) == <NUM_LIT:1> : <EOL> kw . update ( args [ <NUM_LIT:0> ] ) <EOL> elif len ( args ) > <NUM_LIT:0> : <EOL> raise sa_exc . ArgumentError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> self . _params . update ( kw ) <EOL> return self <EOL> def _as_query ( self ) : <EOL> return self . bq . _as_query ( self . session ) . params ( self . _params ) <EOL> def __str__ ( self ) : <EOL> return str ( self . _as_query ( ) ) <EOL> def __iter__ ( self ) : <EOL> bq = self . bq <EOL> if bq . _spoiled : <EOL> return iter ( self . _as_query ( ) ) <EOL> baked_context = bq . _bakery . get ( bq . _cache_key , None ) <EOL> if baked_context is None : <EOL> baked_context = bq . _bake ( self . session ) <EOL> context = copy . copy ( baked_context ) <EOL> context . session = self . session <EOL> context . attributes = context . attributes . copy ( ) <EOL> bq . _unbake_subquery_loaders ( self . session , context , self . _params ) <EOL> context . statement . use_labels = True <EOL> if context . autoflush and not context . populate_existing : <EOL> self . session . _autoflush ( ) <EOL> return context . query . params ( self . _params ) . with_session ( self . session ) . _execute_and_instances ( context ) <EOL> def first ( self ) : <EOL> """<STR_LIT>""" <EOL> bq = self . bq . with_criteria ( lambda q : q . slice ( <NUM_LIT:0> , <NUM_LIT:1> ) ) <EOL> ret = list ( bq . for_session ( self . session ) . params ( self . _params ) ) <EOL> if len ( ret ) > <NUM_LIT:0> : <EOL> return ret [ <NUM_LIT:0> ] <EOL> else : <EOL> return None <EOL> def one ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> ret = self . one_or_none ( ) <EOL> except orm_exc . MultipleResultsFound : <EOL> raise orm_exc . MultipleResultsFound ( <EOL> "<STR_LIT>" ) <EOL> else : <EOL> if ret is None : <EOL> raise orm_exc . NoResultFound ( "<STR_LIT>" ) <EOL> return ret <EOL> def one_or_none ( self ) : <EOL> """<STR_LIT>""" <EOL> ret = list ( self ) <EOL> l = len ( ret ) <EOL> if l == <NUM_LIT:1> : <EOL> return ret [ <NUM_LIT:0> ] <EOL> elif l == <NUM_LIT:0> : <EOL> return None <EOL> else : <EOL> raise orm_exc . MultipleResultsFound ( <EOL> "<STR_LIT>" ) <EOL> def all ( self ) : <EOL> """<STR_LIT>""" <EOL> return list ( self ) <EOL> def get ( self , ident ) : <EOL> """<STR_LIT>""" <EOL> query = self . bq . steps [ <NUM_LIT:0> ] ( self . session ) <EOL> return query . _get_impl ( ident , self . _load_on_ident ) <EOL> def _load_on_ident ( self , query , key ) : <EOL> """<STR_LIT>""" <EOL> ident = key [ <NUM_LIT:1> ] <EOL> mapper = query . _mapper_zero ( ) <EOL> _get_clause , _get_params = mapper . _get_clause <EOL> def setup ( query ) : <EOL> _lcl_get_clause = _get_clause <EOL> q = query . _clone ( ) <EOL> q . _get_condition ( ) <EOL> q . _order_by = None <EOL> if None in ident : <EOL> nones = set ( [ <EOL> _get_params [ col ] . key for col , value in <EOL> zip ( mapper . primary_key , ident ) if value is None <EOL> ] ) <EOL> _lcl_get_clause = sql_util . adapt_criterion_to_null ( <EOL> _lcl_get_clause , nones ) <EOL> _lcl_get_clause = q . _adapt_clause ( _lcl_get_clause , True , False ) <EOL> q . _criterion = _lcl_get_clause <EOL> return q <EOL> bq = self . bq <EOL> bq = bq . _clone ( ) <EOL> bq . _cache_key += ( _get_clause , ) <EOL> bq = bq . with_criteria ( setup , tuple ( elem is None for elem in ident ) ) <EOL> params = dict ( [ <EOL> ( _get_params [ primary_key ] . key , id_val ) <EOL> for id_val , primary_key in zip ( ident , mapper . primary_key ) <EOL> ] ) <EOL> result = list ( bq . for_session ( self . session ) . params ( ** params ) ) <EOL> l = len ( result ) <EOL> if l > <NUM_LIT:1> : <EOL> raise orm_exc . MultipleResultsFound ( ) <EOL> elif l : <EOL> return result [ <NUM_LIT:0> ] <EOL> else : <EOL> return None <EOL> def bake_lazy_loaders ( ) : <EOL> """<STR_LIT>""" <EOL> BakedLazyLoader . _strategy_keys [ : ] = [ ] <EOL> properties . RelationshipProperty . strategy_for ( <EOL> lazy = "<STR_LIT>" ) ( BakedLazyLoader ) <EOL> properties . RelationshipProperty . strategy_for ( <EOL> lazy = True ) ( BakedLazyLoader ) <EOL> properties . RelationshipProperty . strategy_for ( <EOL> lazy = "<STR_LIT>" ) ( BakedLazyLoader ) <EOL> strategies . LazyLoader . _strategy_keys [ : ] = BakedLazyLoader . _strategy_keys [ : ] <EOL> def unbake_lazy_loaders ( ) : <EOL> """<STR_LIT>""" <EOL> strategies . LazyLoader . _strategy_keys [ : ] = [ ] <EOL> BakedLazyLoader . _strategy_keys [ : ] = [ ] <EOL> properties . RelationshipProperty . strategy_for ( <EOL> lazy = "<STR_LIT>" ) ( strategies . LazyLoader ) <EOL> properties . RelationshipProperty . strategy_for ( <EOL> lazy = True ) ( strategies . LazyLoader ) <EOL> properties . RelationshipProperty . strategy_for ( <EOL> lazy = "<STR_LIT>" ) ( BakedLazyLoader ) <EOL> assert strategies . LazyLoader . _strategy_keys <EOL> @ sqla_log . class_logger <EOL> @ properties . RelationshipProperty . strategy_for ( lazy = "<STR_LIT>" ) <EOL> class BakedLazyLoader ( strategies . LazyLoader ) : <EOL> def _emit_lazyload ( self , session , state , ident_key , passive ) : <EOL> q = BakedQuery ( <EOL> self . mapper . _compiled_cache , <EOL> lambda session : session . query ( self . mapper ) ) <EOL> q . add_criteria ( <EOL> lambda q : q . _adapt_all_clauses ( ) . _with_invoke_all_eagers ( False ) , <EOL> self . parent_property ) <EOL> if not self . parent_property . bake_queries : <EOL> q . spoil ( full = True ) <EOL> if self . parent_property . secondary is not None : <EOL> q . add_criteria ( <EOL> lambda q : <EOL> q . select_from ( self . mapper , self . parent_property . secondary ) ) <EOL> pending = not state . key <EOL> if pending or passive & attributes . NO_AUTOFLUSH : <EOL> q . add_criteria ( lambda q : q . autoflush ( False ) ) <EOL> if state . load_path : <EOL> q . spoil ( ) <EOL> q . add_criteria ( <EOL> lambda q : <EOL> q . _with_current_path ( state . load_path [ self . parent_property ] ) ) <EOL> if state . load_options : <EOL> q . spoil ( ) <EOL> q . add_criteria ( <EOL> lambda q : q . _conditional_options ( * state . load_options ) ) <EOL> if self . use_get : <EOL> return q ( session ) . _load_on_ident ( <EOL> session . query ( self . mapper ) , ident_key ) <EOL> if self . parent_property . order_by : <EOL> q . add_criteria ( <EOL> lambda q : <EOL> q . order_by ( * util . to_list ( self . parent_property . order_by ) ) ) <EOL> for rev in self . parent_property . _reverse_property : <EOL> if rev . direction is interfaces . MANYTOONE and rev . _use_get and not isinstance ( rev . strategy , strategies . LazyLoader ) : <EOL> q . add_criteria ( <EOL> lambda q : <EOL> q . options ( <EOL> strategy_options . Load ( <EOL> rev . parent ) . baked_lazyload ( rev . key ) ) ) <EOL> lazy_clause , params = self . _generate_lazy_clause ( state , passive ) <EOL> if pending : <EOL> if orm_util . _none_set . intersection ( params . values ( ) ) : <EOL> return None <EOL> q . add_criteria ( lambda q : q . filter ( lazy_clause ) ) <EOL> result = q ( session ) . params ( ** params ) . all ( ) <EOL> if self . uselist : <EOL> return result <EOL> else : <EOL> l = len ( result ) <EOL> if l : <EOL> if l > <NUM_LIT:1> : <EOL> util . warn ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % self . parent_property ) <EOL> return result [ <NUM_LIT:0> ] <EOL> else : <EOL> return None <EOL> @ strategy_options . loader_option ( ) <EOL> def baked_lazyload ( loadopt , attr ) : <EOL> """<STR_LIT>""" <EOL> return loadopt . set_relationship_strategy ( attr , { "<STR_LIT>" : "<STR_LIT>" } ) <EOL> @ baked_lazyload . _add_unbound_fn <EOL> def baked_lazyload ( * keys ) : <EOL> return strategy_options . _UnboundLoad . _from_keys ( <EOL> strategy_options . _UnboundLoad . baked_lazyload , keys , False , { } ) <EOL> @ baked_lazyload . _add_unbound_all_fn <EOL> def baked_lazyload_all ( * keys ) : <EOL> return strategy_options . _UnboundLoad . _from_keys ( <EOL> strategy_options . _UnboundLoad . baked_lazyload , keys , True , { } ) <EOL> baked_lazyload = baked_lazyload . _unbound_fn <EOL> baked_lazyload_all = baked_lazyload_all . _unbound_all_fn <EOL> bakery = BakedQuery . bakery </s>
