cubicweb/server/querier.py
changeset 12051 bff3be6eebed
parent 11767 432f87a63057
child 12060 0cdf5fafd234
equal deleted inserted replaced
12050:1c7be7b62823 12051:bff3be6eebed
    28 from rql import RQLSyntaxError, CoercionError
    28 from rql import RQLSyntaxError, CoercionError
    29 from rql.stmts import Union
    29 from rql.stmts import Union
    30 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
    30 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
    31 from yams import BASE_TYPES
    31 from yams import BASE_TYPES
    32 
    32 
    33 from cubicweb import ValidationError, Unauthorized, UnknownEid
    33 from cubicweb import ValidationError, Unauthorized, UnknownEid, QueryError
    34 from cubicweb.rqlrewrite import RQLRelationRewriter
    34 from cubicweb.rqlrewrite import RQLRelationRewriter
    35 from cubicweb import Binary, server
    35 from cubicweb import Binary, server
    36 from cubicweb.rset import ResultSet
    36 from cubicweb.rset import ResultSet
    37 
    37 
    38 from cubicweb.utils import QueryCache, RepeatList
    38 from cubicweb.utils import QueryCache, RepeatList
   544                 eidkeys = self._rql_ck_cache[rql]
   544                 eidkeys = self._rql_ck_cache[rql]
   545                 if eidkeys:
   545                 if eidkeys:
   546                     # if there are some, we need a better cache key, eg (rql +
   546                     # if there are some, we need a better cache key, eg (rql +
   547                     # entity type of each eid)
   547                     # entity type of each eid)
   548                     try:
   548                     try:
   549                         cachekey = self._repo.querier_cache_key(cnx, rql,
   549                         cachekey = _rql_cache_key(cnx, rql, args, eidkeys)
   550                                                                 args, eidkeys)
       
   551                     except UnknownEid:
   550                     except UnknownEid:
   552                         # we want queries such as "Any X WHERE X eid 9999"
   551                         # we want queries such as "Any X WHERE X eid 9999"
   553                         # return an empty result instead of raising UnknownEid
   552                         # return an empty result instead of raising UnknownEid
   554                         return empty_rset(rql, args)
   553                         return empty_rset(rql, args)
   555             rqlst = self._rql_cache[cachekey]
   554             rqlst = self._rql_cache[cachekey]
   570                 # empty result instead of raising UnknownEid
   569                 # empty result instead of raising UnknownEid
   571                 return empty_rset(rql, args)
   570                 return empty_rset(rql, args)
   572             if args and rql not in self._rql_ck_cache:
   571             if args and rql not in self._rql_ck_cache:
   573                 self._rql_ck_cache[rql] = eidkeys
   572                 self._rql_ck_cache[rql] = eidkeys
   574                 if eidkeys:
   573                 if eidkeys:
   575                     cachekey = self._repo.querier_cache_key(cnx, rql, args,
   574                     cachekey = _rql_cache_key(cnx, rql, args, eidkeys)
   576                                                             eidkeys)
       
   577             self._rql_cache[cachekey] = rqlst
   575             self._rql_cache[cachekey] = rqlst
   578         if rqlst.TYPE != 'select':
   576         if rqlst.TYPE != 'select':
   579             if cnx.read_security:
   577             if cnx.read_security:
   580                 check_no_password_selected(rqlst)
   578                 check_no_password_selected(rqlst)
   581             cachekey = None
   579             cachekey = None
   644 
   642 
   645     # these are overridden by set_log_methods below
   643     # these are overridden by set_log_methods below
   646     # only defining here to prevent pylint from complaining
   644     # only defining here to prevent pylint from complaining
   647     info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
   645     info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
   648 
   646 
       
   647 
       
   648 def _rql_cache_key(cnx, rql, args, eidkeys):
       
   649     cachekey = [rql]
       
   650     type_from_eid = cnx.repo.type_from_eid
       
   651     for key in sorted(eidkeys):
       
   652         try:
       
   653             etype = type_from_eid(args[key], cnx)
       
   654         except KeyError:
       
   655             raise QueryError('bad cache key %s (no value)' % key)
       
   656         except TypeError:
       
   657             raise QueryError('bad cache key %s (value: %r)' % (
       
   658                 key, args[key]))
       
   659         cachekey.append(etype)
       
   660         # ensure eid is correctly typed in args
       
   661         args[key] = int(args[key])
       
   662     return tuple(cachekey)
       
   663 
       
   664 
   649 from logging import getLogger
   665 from logging import getLogger
   650 from cubicweb import set_log_methods
   666 from cubicweb import set_log_methods
   651 LOGGER = getLogger('cubicweb.querier')
   667 LOGGER = getLogger('cubicweb.querier')
   652 set_log_methods(QuerierHelper, LOGGER)
   668 set_log_methods(QuerierHelper, LOGGER)
   653 
   669