server/session.py
branchstable
changeset 5701 41119f034735
parent 5426 0d4853a6e5ee
child 5707 3586d36d2a45
child 5791 274a5a6080a7
equal deleted inserted replaced
5695:85bafafc1f22 5701:41119f034735
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    13 # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
    14 # details.
    14 # details.
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """Repository users' and internal' sessions.
    18 """Repository users' and internal' sessions."""
    19 
    19 
    20 """
       
    21 from __future__ import with_statement
    20 from __future__ import with_statement
    22 
    21 
    23 __docformat__ = "restructuredtext en"
    22 __docformat__ = "restructuredtext en"
    24 
    23 
    25 import sys
    24 import sys
    27 from time import time
    26 from time import time
    28 from uuid import uuid4
    27 from uuid import uuid4
    29 from warnings import warn
    28 from warnings import warn
    30 
    29 
    31 from logilab.common.deprecation import deprecated
    30 from logilab.common.deprecation import deprecated
    32 from rql.nodes import VariableRef, Function, ETYPE_PYOBJ_MAP, etype_from_pyobj
    31 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj
    33 from yams import BASE_TYPES
    32 from yams import BASE_TYPES
    34 
    33 
    35 from cubicweb import Binary, UnknownEid, schema
    34 from cubicweb import Binary, UnknownEid, schema
    36 from cubicweb.req import RequestSessionBase
    35 from cubicweb.req import RequestSessionBase
    37 from cubicweb.dbapi import ConnectionProperties
    36 from cubicweb.dbapi import ConnectionProperties
    46 # dataimport.NoHookRQLObjectStore, and we don't want to record them
    45 # dataimport.NoHookRQLObjectStore, and we don't want to record them
    47 # anyway in the later case
    46 # anyway in the later case
    48 NO_UNDO_TYPES.add('is')
    47 NO_UNDO_TYPES.add('is')
    49 NO_UNDO_TYPES.add('is_instance_of')
    48 NO_UNDO_TYPES.add('is_instance_of')
    50 # XXX rememberme,forgotpwd,apycot,vcsfile
    49 # XXX rememberme,forgotpwd,apycot,vcsfile
    51 
       
    52 def is_final(rqlst, variable, args):
       
    53     # try to find if this is a final var or not
       
    54     for select in rqlst.children:
       
    55         for sol in select.solutions:
       
    56             etype = variable.get_type(sol, args)
       
    57             if etype is None:
       
    58                 continue
       
    59             if etype in BASE_TYPES:
       
    60                 return True
       
    61             return False
       
    62 
    50 
    63 def _make_description(selected, args, solution):
    51 def _make_description(selected, args, solution):
    64     """return a description for a result set"""
    52     """return a description for a result set"""
    65     description = []
    53     description = []
    66     for term in selected:
    54     for term in selected:
   868 
   856 
   869         XXX could probably be done more efficiently during execution of query
   857         XXX could probably be done more efficiently during execution of query
   870         """
   858         """
   871         # not so easy, looks for variable which changes from one solution
   859         # not so easy, looks for variable which changes from one solution
   872         # to another
   860         # to another
   873         unstables = rqlst.get_variable_variables()
   861         unstables = rqlst.get_variable_indices()
   874         basedescription = []
   862         basedescr = []
   875         todetermine = []
   863         todetermine = []
   876         selected = rqlst.children[0].selection # sample selection
   864         sampleselect = rqlst.children[0]
   877         for i, term in enumerate(selected):
   865         samplesols = sampleselect.solutions[0]
   878             if isinstance(term, Function) and term.descr().rtype is not None:
   866         for i, term in enumerate(sampleselect.selection):
   879                 basedescription.append(term.get_type(term.descr().rtype, args))
   867             try:
   880                 continue
   868                 ttype = term.get_type(samplesols, args)
   881             for vref in term.get_nodes(VariableRef):
   869             except CoercionError:
   882                 if vref.name in unstables:
   870                 ttype = None
   883                     basedescription.append(None)
   871                 isfinal = True
   884                     todetermine.append( (i, is_final(rqlst, vref.variable, args)) )
       
   885                     break
       
   886             else:
   872             else:
   887                 # sample etype
   873                 if ttype is None or ttype == 'Any':
   888                 etype = rqlst.children[0].solutions[0]
   874                     ttype = None
   889                 basedescription.append(term.get_type(etype, args))
   875                     isfinal = True
       
   876                 else:
       
   877                     isfinal = ttype in BASE_TYPES
       
   878             if ttype is None or i in unstables:
       
   879                 basedescr.append(None)
       
   880                 todetermine.append( (i, isfinal) )
       
   881             else:
       
   882                 basedescr.append(ttype)
   890         if not todetermine:
   883         if not todetermine:
   891             return RepeatList(len(result), tuple(basedescription))
   884             return RepeatList(len(result), tuple(basedescr))
   892         return self._build_descr(result, basedescription, todetermine)
   885         return self._build_descr(result, basedescr, todetermine)
   893 
   886 
   894     def _build_descr(self, result, basedescription, todetermine):
   887     def _build_descr(self, result, basedescription, todetermine):
   895         description = []
   888         description = []
   896         etype_from_eid = self.describe
   889         etype_from_eid = self.describe
   897         for row in result:
   890         for row in result:
   898             row_descr = basedescription
   891             row_descr = basedescription[:]
   899             for index, isfinal in todetermine:
   892             for index, isfinal in todetermine:
   900                 value = row[index]
   893                 value = row[index]
   901                 if value is None:
   894                 if value is None:
   902                     # None value inserted by an outer join, no type
   895                     # None value inserted by an outer join, no type
   903                     row_descr[index] = None
   896                     row_descr[index] = None
   906                     row_descr[index] = etype_from_pyobj(value)
   899                     row_descr[index] = etype_from_pyobj(value)
   907                 else:
   900                 else:
   908                     try:
   901                     try:
   909                         row_descr[index] = etype_from_eid(value)[0]
   902                         row_descr[index] = etype_from_eid(value)[0]
   910                     except UnknownEid:
   903                     except UnknownEid:
   911                         self.critical('wrong eid %s in repository, should check database' % value)
   904                         self.critical('wrong eid %s in repository, you should '
       
   905                                       'db-check the database' % value)
   912                         row_descr[index] = row[index] = None
   906                         row_descr[index] = row[index] = None
   913             description.append(tuple(row_descr))
   907             description.append(tuple(row_descr))
   914         return description
   908         return description
   915 
   909 
   916     # deprecated ###############################################################
   910     # deprecated ###############################################################