rset.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 23 Sep 2009 11:22:08 +0200
changeset 3411 c867a096e11c
parent 3405 9d31c9cb8103
child 3589 a5432f99f2d9
permissions -rw-r--r--
access to repo through session
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""The `ResultSet` class which is returned as result of a rql query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1922
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1922
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
from logilab.common.decorators import cached, clear_cache, copy_cache
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    12
from rql import nodes, stmts
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
from cubicweb import NotAnEntity
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    15
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    16
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
class ResultSet(object):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
    """a result set wrap a RQL query result. This object implements a partial
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
    list protocol to allow direct use as a list of result rows.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
    :type rowcount: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
    :ivar rowcount: number of rows in the result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
    :type rows: list
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
    :ivar rows: list of rows of result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
    :type description: list
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
    :ivar description:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
      result's description, using the same structure as the result itself
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    :type rql: str or unicode
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
    :ivar rql: the original RQL query string
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
    def __init__(self, results, rql, args=None, description=(), cachekey=None,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
                 rqlst=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
        self.rows = results
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
        self.rowcount = results and len(results) or 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
        # original query and arguments
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
        self.rql = rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
        self.args = args
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
        self.cachekey = cachekey
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
        # entity types for each cell (same shape as rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
        # maybe discarded if specified when the query has been executed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
        self.description = description
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        # parsed syntax tree
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        if rqlst is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
            rqlst.schema = None # reset schema in case of pyro transfert
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        self._rqlst = rqlst
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        # set to (limit, offset) when a result set is limited using the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        # .limit method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        self.limited = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        # set by the cursor which returned this resultset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
        self.vreg = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
        self.req = None
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    55
        # actions cache
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    56
        self._rsetactions = None
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    57
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        if not self.rows:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
            return '<empty resultset %s>' % self.rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        return '<resultset %s (%s rows)>' % (self.rql, len(self.rows))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    62
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        if not self.rows:
170
455ff18ef28e use repr (instead of str) to print rql in __repr__ method of a result set
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 0
diff changeset
    65
            return '<empty resultset for %r>' % self.rql
616
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    66
        rows = self.rows
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    67
        if len(rows) > 10:
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    68
            rows = rows[:10] + ['...']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
        if not self.description:
616
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    70
            return '<resultset %r (%s rows): %s>' % (self.rql, len(self.rows),
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    71
                                                     '\n'.join(str(r) for r in rows))
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    72
        return '<resultset %r (%s rows): %s>' % (self.rql, len(self.rows),
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    73
                                                 '\n'.join('%s (%s)' % (r, d)
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    74
                                                           for r, d in zip(rows, self.description)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    76
    def possible_actions(self, **kwargs):
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    77
        if self._rsetactions is None:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    78
            self._rsetactions = {}
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    79
        if kwargs:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    80
            key = tuple(sorted(kwargs.iteritems()))
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    81
        else:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    82
            key = None
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    83
        try:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    84
            return self._rsetactions[key]
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    85
        except KeyError:
2813
0cf6c8005bf6 R propagate deprecation of CWRegistry.possible_vobjects
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2792
diff changeset
    86
            actions = self.vreg['actions'].poss_visible_objects(
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2648
diff changeset
    87
                self.req, rset=self, **kwargs)
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    88
            self._rsetactions[key] = actions
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    89
            return actions
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    90
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    def __len__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        """returns the result set's size"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        return self.rowcount
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
    def __nonzero__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        return self.rowcount
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    97
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
    def __getitem__(self, i):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        """returns the ith element of the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
        return self.rows[i] #ResultSetRow(self.rows[i])
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   101
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    def __getslice__(self, i, j):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
        """returns slice [i:j] of the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        return self.rows[i:j]
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   105
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
    def __iter__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
        """Returns an iterator over rows"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
        return iter(self.rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
    def __add__(self, rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        # XXX buggy implementation (.rql and .args attributes at least much
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        # probably differ)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
        # at least rql could be fixed now that we have union and sub-queries
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
        # but I tend to think that since we have that, we should not need this
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
        # method anymore (syt)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        rset = ResultSet(self.rows+rset.rows, self.rql, self.args,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
                         self.description +rset.description)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
        return self.req.decorate_rset(rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
    def _prepare_copy(self, rows, descr):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
        rset = ResultSet(rows, self.rql, self.args, descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
        return self.req.decorate_rset(rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
    def transformed_rset(self, transformcb):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        """ the result set according to a given column types
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        :type transormcb: callable(row, desc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        :param transformcb:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
          a callable which should take a row and its type description as
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
          parameters, and return the transformed row and type description.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   131
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
        :param col: the column index
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
        rows, descr = [], []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        rset = self._prepare_copy(rows, descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        for row, desc in zip(self.rows, self.description):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
            nrow, ndesc = transformcb(row, desc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
            if ndesc: # transformcb returns None for ndesc to skip that row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
                rows.append(nrow)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
                descr.append(ndesc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
        rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
    def filtered_rset(self, filtercb, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        """filter the result set according to a given filtercb
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        :type filtercb: callable(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
        :param filtercb:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
          a callable which should take an entity as argument and return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
          False if it should be skipped, else True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
        :param col: the column index
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
        rows, descr = [], []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        rset = self._prepare_copy(rows, descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        for i in xrange(len(self)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
            if not filtercb(self.get_entity(i, col)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
            rows.append(self.rows[i])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
            descr.append(self.description[i])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
    def sorted_rset(self, keyfunc, reverse=False, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
        """sorts the result set according to a given keyfunc
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        :type keyfunc: callable(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
        :param keyfunc:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
          a callable which should take an entity as argument and return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
          the value used to compare and sort
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
        :type reverse: bool
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        :param reverse: if the result should be reversed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        :param col: the column index. if col = -1, the whole row are used
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
        rows, descr = [], []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        rset = self._prepare_copy(rows, descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
        if col >= 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
            entities = sorted(enumerate(self.entities(col)),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
                              key=lambda (i, e): keyfunc(e), reverse=reverse)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
            entities = sorted(enumerate(self),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
                              key=lambda (i, e): keyfunc(e), reverse=reverse)
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   196
        for index, _ in entities:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
            rows.append(self.rows[index])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
            descr.append(self.description[index])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
    def split_rset(self, keyfunc=None, col=0, return_dict=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        """Splits the result set in multiple result set according to a given key
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   204
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
        :type keyfunc: callable(entity or FinalType)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        :param keyfunc:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
          a callable which should take a value of the rset in argument and
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
          return the value used to group the value. If not define, raw value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
          of the specified columns is used.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        :param col: the column index. if col = -1, the whole row are used
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
        :type return_dict: Boolean
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
        :param return_dict: If true, the function return a mapping
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
            (key -> rset) instead of a list of rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
        :rtype: List of `ResultSet` or mapping of  `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
        mapping = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        for idx, line in enumerate(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
            if col >= 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
                try:
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   226
                    key = self.get_entity(idx, col)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
                except NotAnEntity:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
                    key = line[col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
                key = line
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
            if keyfunc is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
                key = keyfunc(key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
            if key not in mapping:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
                rows, descr = [], []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
                rset = self._prepare_copy(rows, descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
                mapping[key] = rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
                result.append(rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
                rset = mapping[key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
            rset.rows.append(self.rows[idx])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
            rset.description.append(self.description[idx])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        for rset in result:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
            rset.rowcount = len(rset.rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
        if return_dict:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
            return mapping
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
            return result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   250
    def limited_rql(self):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   251
        """return a printable rql for the result set associated to the object,
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   252
        with limit/offset correctly set according to maximum page size and
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   253
        currently displayed page when necessary
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   254
        """
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   255
        # try to get page boundaries from the navigation component
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   256
        # XXX we should probably not have a ref to this component here (eg in
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   257
        #     cubicweb.common)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   258
        nav = self.vreg['components'].select_or_none('navigation', self.req,
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   259
                                                     rset=self)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   260
        if nav:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   261
            start, stop = nav.page_boundaries()
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   262
            rql = self._limit_offset_rql(stop - start, start)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   263
        # result set may have be limited manually in which case navigation won't
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   264
        # apply
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   265
        elif self.limited:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   266
            rql = self._limit_offset_rql(*self.limited)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   267
        # navigation component doesn't apply and rset has not been limited, no
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   268
        # need to limit query
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   269
        else:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   270
            rql = self.printable_rql()
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   271
        return rql
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   272
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   273
    def _limit_offset_rql(self, limit, offset):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   274
        rqlst = self.syntax_tree()
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   275
        if len(rqlst.children) == 1:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   276
            select = rqlst.children[0]
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   277
            olimit, ooffset = select.limit, select.offset
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   278
            select.limit, select.offset = limit, offset
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   279
            rql = rqlst.as_string(kwargs=self.args)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   280
            # restore original limit/offset
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   281
            select.limit, select.offset = olimit, ooffset
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   282
        else:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   283
            newselect = stmts.Select()
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   284
            newselect.limit = limit
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   285
            newselect.offset = offset
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   286
            aliases = [nodes.VariableRef(newselect.get_variable(vref.name, i))
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   287
                       for i, vref in enumerate(rqlst.selection)]
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   288
            newselect.set_with([nodes.SubQuery(aliases, rqlst)], check=False)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   289
            newunion = stmts.Union()
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   290
            newunion.append(newselect)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   291
            rql = rqlst.as_string(kwargs=self.args)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   292
            rqlst.parent = None
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   293
        return rql
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   294
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
    def limit(self, limit, offset=0, inplace=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   296
        """limit the result set to the given number of rows optionaly starting
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
        from an index different than 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
        :type limit: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
        :param limit: the maximum number of results
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
        :type offset: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
        :param offset: the offset index
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   304
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   305
        :type inplace: bool
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
        :param inplace:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   307
          if true, the result set is modified in place, else a new result set
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
          is returned and the original is left unmodified
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   310
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   311
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
        stop = limit+offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
        rows = self.rows[offset:stop]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
        descr = self.description[offset:stop]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   315
        if inplace:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
            rset = self
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
            rset.rows, rset.description = rows, descr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
            rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   319
            clear_cache(rset, 'description_struct')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
            if offset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
                clear_cache(rset, 'get_entity')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
            # we also have to fix/remove from the request entity cache entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
            # which get a wrong rset reference by this limit call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
            for entity in self.req.cached_entities():
3379
9192ba07890d use .cw_rset instead of rset on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3023
diff changeset
   325
                if entity.cw_rset is self:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
                    if offset <= entity.row < stop:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
                        entity.row = entity.row - offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
                        self.req.drop_entity_cache(entity.eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
            rset = self._prepare_copy(rows, descr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
            if not offset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   333
                # can copy built entity caches
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
                copy_cache(rset, 'get_entity', self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
        rset.limited = (limit, offset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
        return rset
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   337
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
    def printable_rql(self, encoded=False):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
        """return the result set's origin rql as a string, with arguments
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
        substitued
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
        encoding = self.req.encoding
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
        rqlstr = self.syntax_tree().as_string(encoding, self.args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
        # sounds like we get encoded or unicode string due to a bug in as_string
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
        if not encoded:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
            if isinstance(rqlstr, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
                return rqlstr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
            return unicode(rqlstr, encoding)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   349
        else:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   350
            if isinstance(rqlstr, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   351
                return rqlstr.encode(encoding)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
            return rqlstr
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   353
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   354
    # client helper methods ###################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   355
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
    def entities(self, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
        """iter on entities with eid in the `col` column of the result set"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
        for i in xrange(len(self)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
            # may have None values in case of outer join (or aggregat on eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
            # hacks)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   361
            if self.rows[i][col] is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
                yield self.get_entity(i, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   364
    def complete_entity(self, row, col=0, skip_bytes=True):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   365
        """short cut to get an completed entity instance for a particular
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   366
        row (all instance's attributes have been fetched)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   367
        """
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   368
        entity = self.get_entity(row, col)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   369
        entity.complete(skip_bytes=skip_bytes)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   370
        return entity
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   371
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   372
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
    def get_entity(self, row, col=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
        """special method for query retreiving a single entity, returns a
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
        partially initialized Entity instance.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   376
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
        WARNING: due to the cache wrapping this function, you should NEVER
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
                 give row as a named parameter (i.e. rset.get_entity(req, 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   379
                 is OK but rset.get_entity(row=0, req=req) isn't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
        :type row,col: int, int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
        :param row,col:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   383
          row and col numbers localizing the entity among the result's table
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
        :return: the partially initialized `Entity` instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
        if col is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
            from warnings import warn
3405
9d31c9cb8103 nicer deprecation warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3379
diff changeset
   389
            msg = '[3.2] col parameter will become mandatory in future version'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
            warn(msg, DeprecationWarning, stacklevel=3)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
            col = 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   392
        etype = self.description[row][col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   394
            eschema = self.vreg.schema.eschema(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
            if eschema.is_final():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
                raise NotAnEntity(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
            raise NotAnEntity(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
        return self._build_entity(row, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   401
    def _build_entity(self, row, col):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
        """internal method to get a single entity, returns a
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
        partially initialized Entity instance.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
        partially means that only attributes selected in the RQL
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
        query will be directly assigned to the entity.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   407
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
        :type row,col: int, int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
        :param row,col:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
          row and col numbers localizing the entity among the result's table
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   411
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   412
        :return: the partially initialized `Entity` instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   414
        req = self.req
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   415
        if req is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   416
            raise AssertionError('dont call get_entity with no req on the result set')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
        rowvalues = self.rows[row]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
        eid = rowvalues[col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
        assert eid is not None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
        # return cached entity if exists. This also avoids potential recursion
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   421
        # XXX should we consider updating a cached entity with possible
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
        #     new attributes found in this resultset ?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   423
        try:
2648
4ae7d02ce063 F [rset repo cache] set entity.rset when no set on entities retreived from the cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2647
diff changeset
   424
            entity = req.entity_cache(eid)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   425
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   426
            pass
2832
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   427
        else:
3379
9192ba07890d use .cw_rset instead of rset on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3023
diff changeset
   428
            if entity.cw_rset is None:
2832
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   429
                # entity has no rset set, this means entity has been created by
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   430
                # the querier (req is a repository session) and so jas no rset
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   431
                # info. Add it.
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   432
                entity.cw_rset = self
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   433
                entity.cw_row = row
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   434
                entity.cw_col = col
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   435
            return entity
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        # build entity instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        etype = self.description[row][col]
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2648
diff changeset
   438
        entity = self.vreg['etypes'].etype_class(etype)(req, rset=self,
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2648
diff changeset
   439
                                                        row=row, col=col)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
        entity.set_eid(eid)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
        # cache entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
        req.set_entity_cache(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
        eschema = entity.e_schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
        # try to complete the entity if there are some additional columns
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   445
        if len(rowvalues) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   446
            rqlst = self.syntax_tree()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   447
            if rqlst.TYPE == 'select':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   448
                # UNION query, find the subquery from which this entity has been
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   449
                # found
3016
5787d1cc8106 [rset] fix #231354 w/ rql 0.22.3 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   450
                rqlst, col = rqlst.locate_subquery(col, etype, self.args)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   451
            # take care, due to outer join support, we may find None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   452
            # values for non final relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   453
            for i, attr, x in attr_desc_iterator(rqlst, col):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   454
                if x == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   455
                    rschema = eschema.subject_relation(attr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   456
                    if rschema.is_final():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   457
                        entity[attr] = rowvalues[i]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   458
                        continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   459
                    tetype = rschema.objects(etype)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   460
                    card = rschema.rproperty(etype, tetype, 'cardinality')[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   461
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   462
                    rschema = eschema.object_relation(attr)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   463
                    tetype = rschema.subjects(etype)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   464
                    card = rschema.rproperty(tetype, etype, 'cardinality')[1]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   465
                # only keep value if it can't be multivalued
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
                if card in '1?':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
                    if rowvalues[i] is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   468
                        if x == 'subject':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
                            rql = 'Any Y WHERE X %s Y, X eid %s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
                        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
                            rql = 'Any Y WHERE Y %s X, X eid %s'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
                        rrset = ResultSet([], rql % (attr, entity.eid))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
                        req.decorate_rset(rrset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
                    else:
2647
b0a2e779845c enable server side entity caching, 25% speedup on codenaf insertion. ALL CW TESTS OK
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2381
diff changeset
   475
                        rrset = self._build_entity(row, i).as_rset()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
                    entity.set_related_cache(attr, x, rrset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
        return entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
    def syntax_tree(self):
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   481
        """get the syntax tree for the source query.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
        :rtype: rql.stmts.Statement
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
        :return: the RQL syntax tree of the originating query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
        if self._rqlst:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   487
            rqlst = self._rqlst.copy()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   488
            # to avoid transport overhead when pyro is used, the schema has been
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
            # unset from the syntax tree
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   490
            rqlst.schema = self.vreg.schema
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   491
            self.vreg.rqlhelper.annotate(rqlst)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
            rqlst = self.vreg.parse(self.req, self.rql, self.args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
        return rqlst
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   495
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   496
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   497
    def column_types(self, col):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   498
        """return the list of different types in the column with the given col
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   499
        index default to 0 (ie the first column)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   500
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   502
        :param col: the index of the desired column
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   503
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   504
        :rtype: list
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   505
        :return: the different entities type found in the column
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   507
        return frozenset(struc[-1][col] for struc in self.description_struct())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   509
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   510
    def description_struct(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   511
        """return a list describing sequence of results with the same
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   512
        description, e.g. :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   513
        [[0, 4, ('Bug',)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   514
        [[0, 4, ('Bug',), [5, 8, ('Story',)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
        [[0, 3, ('Project', 'Version',)]]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   516
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   517
        result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
        last = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
        for i, row in enumerate(self.description):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   520
            if row != last:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
                if last is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
                    result[-1][1] = i - 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
                result.append( [i, None, row] )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
                last = row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
        if last is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
            result[-1][1] = i
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   527
        return result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   528
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   529
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   530
    def related_entity(self, row, col):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   531
        """try to get the related entity to extract format information if any"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   532
        locate_query_col = col
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   533
        rqlst = self.syntax_tree()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   534
        etype = self.description[row][col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   535
        if self.vreg.schema.eschema(etype).is_final():
572
9849fed789c9 test and fix potential error with None optional relation
sylvain.thenault@logilab.fr
parents: 170
diff changeset
   536
            # final type, find a better one to locate the correct subquery
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   537
            # (ambiguous if possible)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   538
            for i in xrange(len(rqlst.children[0].selection)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   539
                if i == col:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   540
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   541
                coletype = self.description[row][i]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   542
                if coletype is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   543
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   544
                if not self.vreg.schema.eschema(coletype).is_final():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   545
                    etype = coletype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   546
                    locate_query_col = i
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   547
                    if len(self.column_types(i)) > 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   548
                        break
572
9849fed789c9 test and fix potential error with None optional relation
sylvain.thenault@logilab.fr
parents: 170
diff changeset
   549
        # UNION query, find the subquery from which this entity has been found
3016
5787d1cc8106 [rset] fix #231354 w/ rql 0.22.3 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   550
        select = rqlst.locate_subquery(locate_query_col, etype, self.args)[0]
5787d1cc8106 [rset] fix #231354 w/ rql 0.22.3 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   551
        col = rqlst.subquery_selection_index(select, col)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   552
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
            myvar = select.selection[col].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   554
        except AttributeError:
572
9849fed789c9 test and fix potential error with None optional relation
sylvain.thenault@logilab.fr
parents: 170
diff changeset
   555
            # not a variable
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   556
            return None, None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
        rel = myvar.main_relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
        if rel is not None:
3016
5787d1cc8106 [rset] fix #231354 w/ rql 0.22.3 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   559
            index = rel.children[0].root_selection_index()
572
9849fed789c9 test and fix potential error with None optional relation
sylvain.thenault@logilab.fr
parents: 170
diff changeset
   560
            if index is not None and self.rows[row][index]:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   561
                return self.get_entity(row, index), rel.r_type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   562
        return None, None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   564
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   565
    def searched_text(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
        """returns the searched text in case of full-text search
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
        :return: searched text or `None` if the query is not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   569
                 a full-text query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
        rqlst = self.syntax_tree()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   572
        for rel in rqlst.iget_nodes(nodes.Relation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
            if rel.r_type == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   574
                __, rhs = rel.get_variable_parts()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   575
                return rhs.eval(self.args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   576
        return None
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   577
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
def attr_desc_iterator(rqlst, index=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
    """return an iterator on a list of 2-uple (index, attr_relation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   581
    localizing attribute relations of the main variable in a result's row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
    :type rqlst: rql.stmts.Select
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
    :param rqlst: the RQL syntax tree to describe
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   585
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   586
    :return:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   587
      a generator on (index, relation, target) describing column being
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   588
      attribute of the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   589
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   590
    main = rqlst.selection[index]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   591
    for i, term in enumerate(rqlst.selection):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
        if i == index:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   593
            continue
2352
734eb79680e9 handle attribute selection on variable selected using MAX()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   594
        # XXX rewritten const
734eb79680e9 handle attribute selection on variable selected using MAX()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   595
        # use iget_nodes for (hack) case where we have things like MAX(V)
734eb79680e9 handle attribute selection on variable selected using MAX()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   596
        for vref in term.iget_nodes(nodes.VariableRef):
734eb79680e9 handle attribute selection on variable selected using MAX()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   597
            var = vref.variable
734eb79680e9 handle attribute selection on variable selected using MAX()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   598
            break
734eb79680e9 handle attribute selection on variable selected using MAX()
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   599
        else:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   600
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   601
        #varname = var.name
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   602
        for ref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   603
            rel = ref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   604
            if rel is None or rel.is_types_restriction():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   605
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   606
            lhs, rhs = rel.get_variable_parts()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   607
            if main.is_equivalent(lhs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   608
                if rhs.is_equivalent(term):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   609
                    yield (i, rel.r_type, 'subject')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   610
            elif main.is_equivalent(rhs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   611
                if lhs.is_equivalent(term):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   612
                    yield (i, rel.r_type, 'object')