rset.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 24 Sep 2015 11:26:11 +0200
changeset 10921 977def81780a
parent 10903 da30851f9706
child 10926 f9927717f493
permissions -rw-r--r--
[migration] don't handle data deletion anymore on schema changes In most cases when we want to drop some entity/relation type, we don't care whether hooks are called on their deletion. There is even low chances that some hooks still exists, based on an old version of the schema. Last but not least, this is horribly inefficient. So this should be clearly documented and handled by application's programmer if desired. This patch removes unnecessary deletion (because table or column will be later dropped) and reimplements the case of partial deletion (only one relation definition among several, hence the database structure isn't modified) using sql. Only one test regarding deletion of inlined relation def is added as other cases seem to be covered by existing tests. Closes #7023315
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7395
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5314
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5671
3a2063b752f3 [editform] consistent [do]reledit between attributes and relations: check if rdef is hidden in main section of uicfg.afs for both attributes and relations, and in the reledit view, not in doreledit
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5667
diff changeset
    18
"""The `ResultSet` class which is returned as result of an rql query"""
10691
af266f27c4d5 [py3k] __getslice__ → __getitem__ with slice support
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
    19
from __future__ import print_function
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
10087
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
    22
from warnings import warn
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
    23
10687
d394bfcd8c25 [py3k] unicode → six.text_type
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    24
from six import PY3
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10593
diff changeset
    25
from six.moves import range
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10593
diff changeset
    26
10313
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
    27
from logilab.common import nullobject
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
from logilab.common.decorators import cached, clear_cache, copy_cache
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
    29
from rql import nodes, stmts
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
9347
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
    31
from cubicweb import NotAnEntity, NoResultError, MultipleResultsError
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    32
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
10313
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
    34
_MARKER = nullobject()
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
    35
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
    36
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
class ResultSet(object):
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    38
    """A result set wraps a RQL query result. This object implements
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    39
    partially the list protocol to allow direct use as a list of
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    40
    result rows.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
    :type rowcount: int
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    43
    :param rowcount: number of rows in the result
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    :type rows: list
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    46
    :param rows: list of rows of result
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
    :type description: list
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    49
    :param description:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
      result's description, using the same structure as the result itself
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
    :type rql: str or unicode
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
    53
    :param rql: the original RQL query string
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    """
5740
46207f491a51 [rset] make rsets picklable (again ?) #1056422
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5671
diff changeset
    55
9281
49a7392bb5b5 [rset] make sure rset.description is always a list
Julien Cristau <julien.cristau@logilab.fr>
parents: 8695
diff changeset
    56
    def __init__(self, results, rql, args=None, description=None, rqlst=None):
10087
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
    57
        if rqlst is not None:
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
    58
            warn('[3.20] rqlst parameter is deprecated',
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
    59
                 DeprecationWarning, stacklevel=2)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
        self.rows = results
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        self.rowcount = results and len(results) or 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        # original query and arguments
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        self.rql = rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
        self.args = args
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
        # entity types for each cell (same shape as rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
        # maybe discarded if specified when the query has been executed
9331
c6f54ed6b60a [rset] Fix regression with rset copying (closes #3344410)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9281
diff changeset
    67
        if description is None:
c6f54ed6b60a [rset] Fix regression with rset copying (closes #3344410)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9281
diff changeset
    68
            self.description = []
c6f54ed6b60a [rset] Fix regression with rset copying (closes #3344410)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9281
diff changeset
    69
        else:
c6f54ed6b60a [rset] Fix regression with rset copying (closes #3344410)
Julien Cristau <julien.cristau@logilab.fr>
parents: 9281
diff changeset
    70
            self.description = description
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
        # set to (limit, offset) when a result set is limited using the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        # .limit method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
        self.limited = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        # set by the cursor which returned this resultset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        self.req = None
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    76
        # actions cache
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
    77
        self._rsetactions = None
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
    78
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
    def __str__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        if not self.rows:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
            return '<empty resultset %s>' % self.rql
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        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
    83
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
    def __repr__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
        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
    86
            return '<empty resultset for %r>' % self.rql
616
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    87
        rows = self.rows
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    88
        if len(rows) > 10:
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    89
            rows = rows[:10] + ['...']
5687
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    90
        if len(rows) > 1:
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    91
            # add a line break before first entity if more that one.
7395
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
    92
            pattern = '<resultset %r (%s rows):\n%s>'
5687
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    93
        else:
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    94
            pattern = '<resultset %r (%s rows): %s>'
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    95
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        if not self.description:
5687
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    97
            return pattern % (self.rql, len(self.rows),
616
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
    98
                                                     '\n'.join(str(r) for r in rows))
5687
3ea39709b50e [rset] Add a line break the first result in repr of multiple rows rset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 5679
diff changeset
    99
        return pattern % (self.rql, len(self.rows),
616
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
   100
                                                 '\n'.join('%s (%s)' % (r, d)
545a7e18c47f don't display too much rset rows
sylvain.thenault@logilab.fr
parents: 572
diff changeset
   101
                                                           for r, d in zip(rows, self.description)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   103
    def possible_actions(self, **kwargs):
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   104
        if self._rsetactions is None:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   105
            self._rsetactions = {}
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   106
        if kwargs:
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   107
            key = tuple(sorted(kwargs.items()))
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   108
        else:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   109
            key = None
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   110
        try:
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   111
            return self._rsetactions[key]
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   112
        except KeyError:
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   113
            actions = self.req.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
   114
                self.req, rset=self, **kwargs)
1381
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   115
            self._rsetactions[key] = actions
6042f1b342bb consider kwargs in possible_actions
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   116
            return actions
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   117
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
    def __len__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        """returns the result set's size"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        return self.rowcount
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
    def __getitem__(self, i):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
        """returns the ith element of the result set"""
10691
af266f27c4d5 [py3k] __getslice__ → __getitem__ with slice support
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
   124
        #print('__getitem__', i)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        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
   126
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
    def __iter__(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        """Returns an iterator over rows"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
        return iter(self.rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
    def __add__(self, rset):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
        # XXX buggy implementation (.rql and .args attributes at least much
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        # probably differ)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
        # 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
   135
        # 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
   136
        # method anymore (syt)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
        rset = ResultSet(self.rows+rset.rows, self.rql, self.args,
5072
072ae171aeb0 [cleanup] style fixes, add nodes, 0.2 cents refactorings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4951
diff changeset
   138
                         self.description + rset.description)
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   139
        rset.req = self.req
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   140
        return rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
3764
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   142
    def copy(self, rows=None, descr=None):
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   143
        if rows is None:
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   144
            rows = self.rows[:]
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   145
            descr = self.description[:]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        rset = ResultSet(rows, self.rql, self.args, descr)
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   147
        rset.req = self.req
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   148
        return rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
    def transformed_rset(self, transformcb):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        """ the result set according to a given column types
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
        :type transormcb: callable(row, desc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
        :param transformcb:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
          a callable which should take a row and its type description as
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
          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
   157
0
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
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        :param col: the column index
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
        rows, descr = [], []
3764
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   165
        rset = self.copy(rows, descr)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        for row, desc in zip(self.rows, self.description):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
            nrow, ndesc = transformcb(row, desc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
            if ndesc: # transformcb returns None for ndesc to skip that row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
                rows.append(nrow)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
                descr.append(ndesc)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
    def filtered_rset(self, filtercb, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        """filter the result set according to a given filtercb
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        :type filtercb: callable(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
        :param filtercb:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
          a callable which should take an entity as argument and return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
          False if it should be skipped, else True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
        :param col: the column index
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
        rows, descr = [], []
3764
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   188
        rset = self.copy(rows, descr)
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10593
diff changeset
   189
        for i in range(len(self)):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
            if not filtercb(self.get_entity(i, col)):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
            rows.append(self.rows[i])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
            descr.append(self.description[i])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
        rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
    def sorted_rset(self, keyfunc, reverse=False, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        """sorts the result set according to a given keyfunc
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
        :type keyfunc: callable(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        :param keyfunc:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
          a callable which should take an entity as argument and return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
          the value used to compare and sort
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        :type reverse: bool
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        :param reverse: if the result should be reversed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        :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
   211
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
        :rtype: `ResultSet`
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
        rows, descr = [], []
3764
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   215
        rset = self.copy(rows, descr)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
        if col >= 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
            entities = sorted(enumerate(self.entities(col)),
10593
03ce3d24db87 [py3k] tuple unpacking in function args
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10354
diff changeset
   218
                              key=lambda t: keyfunc(t[1]), reverse=reverse)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
            entities = sorted(enumerate(self),
10593
03ce3d24db87 [py3k] tuple unpacking in function args
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 10354
diff changeset
   221
                              key=lambda t: keyfunc(t[1]), reverse=reverse)
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   222
        for index, _ in entities:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
            rows.append(self.rows[index])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
            descr.append(self.description[index])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
        rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
    def split_rset(self, keyfunc=None, col=0, return_dict=False):
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
   229
        """splits the result set in multiple result sets according to
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
   230
        a given key
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   231
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
        :type keyfunc: callable(entity or FinalType)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
        :param keyfunc:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
          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
   235
          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
   236
          of the specified columns is used.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
        :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
   240
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        :type return_dict: Boolean
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
        :param return_dict: If true, the function return a mapping
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
            (key -> rset) instead of a list of rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   244
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
        :rtype: List of `ResultSet` or mapping of  `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
        result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
        mapping = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        for idx, line in enumerate(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
            if col >= 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
                try:
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 616
diff changeset
   253
                    key = self.get_entity(idx, col)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
                except NotAnEntity:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
                    key = line[col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
                key = line
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
            if keyfunc is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   259
                key = keyfunc(key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
            if key not in mapping:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
                rows, descr = [], []
3764
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   263
                rset = self.copy(rows, descr)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   264
                mapping[key] = rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
                result.append(rset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   266
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
                rset = mapping[key]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
            rset.rows.append(self.rows[idx])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
            rset.description.append(self.description[idx])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        for rset in result:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   271
            rset.rowcount = len(rset.rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   272
        if return_dict:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
            return mapping
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
            return result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
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
   277
    def limited_rql(self):
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
   278
        """returns a printable rql for the result set associated to the object,
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
   279
        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
   280
        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
   281
        """
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
        # 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
   283
        # XXX we should probably not have a ref to this component here (eg in
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3998
diff changeset
   284
        #     cubicweb)
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   285
        nav = self.req.vreg['components'].select_or_none('navigation', self.req,
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   286
                                                         rset=self)
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
   287
        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
   288
            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
   289
            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
   290
        # 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
   291
        # 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
   292
        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
   293
            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
   294
        # 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
   295
        # 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
   296
        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
   297
            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
   298
        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
   299
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
   300
    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
   301
        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
   302
        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
   303
            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
   304
            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
   305
            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
   306
            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
   307
            # 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
   308
            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
   309
        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
   310
            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
   311
            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
   312
            newselect.offset = offset
4939
349af486f5ed fix limited_rql w/ UNION query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   313
            aliases = [nodes.VariableRef(newselect.get_variable(chr(65+i), i))
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10593
diff changeset
   314
                       for i in range(len(rqlst.children[0].selection))]
4939
349af486f5ed fix limited_rql w/ UNION query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   315
            for vref in aliases:
349af486f5ed fix limited_rql w/ UNION query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   316
                newselect.append_selected(nodes.VariableRef(vref.variable))
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
   317
            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
   318
            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
   319
            newunion.append(newselect)
4939
349af486f5ed fix limited_rql w/ UNION query
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   320
            rql = newunion.as_string(kwargs=self.args)
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
   321
            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
   322
        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
   323
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   324
    def limit(self, limit, offset=0, inplace=False):
10903
da30851f9706 spelling: *aly → *ally
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10691
diff changeset
   325
        """limit the result set to the given number of rows optionally starting
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
        from an index different than 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
        :type limit: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
        :param limit: the maximum number of results
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   330
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   331
        :type offset: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   332
        :param offset: the offset index
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   333
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   334
        :type inplace: bool
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
        :param inplace:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
          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
   337
          is returned and the original is left unmodified
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   338
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   339
        :rtype: `ResultSet`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   340
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   341
        stop = limit+offset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
        rows = self.rows[offset:stop]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   343
        descr = self.description[offset:stop]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   344
        if inplace:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   345
            rset = self
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   346
            rset.rows, rset.description = rows, descr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   347
            rset.rowcount = len(rows)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   348
            clear_cache(rset, 'description_struct')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   349
            if offset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   350
                clear_cache(rset, 'get_entity')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   351
            # we also have to fix/remove from the request entity cache entities
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   352
            # which get a wrong rset reference by this limit call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   353
            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
   354
                if entity.cw_rset is self:
4150
2835482b8daf don't try to write .row/.col, use new cw_row/cw_col attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   355
                    if offset <= entity.cw_row < stop:
2835482b8daf don't try to write .row/.col, use new cw_row/cw_col attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4023
diff changeset
   356
                        entity.cw_row = entity.cw_row - offset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
                    else:
8048
10a0f73d834d [rset] replace entity cw_rset on .limit(inplace=True) will avoid pb if the entity is still referenced by some other entity relations cache. Closes #2065643
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7595
diff changeset
   358
                        entity.cw_rset = entity.as_rset()
10a0f73d834d [rset] replace entity cw_rset on .limit(inplace=True) will avoid pb if the entity is still referenced by some other entity relations cache. Closes #2065643
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7595
diff changeset
   359
                        entity.cw_row = entity.cw_col = 0
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
        else:
3764
034aa14b740a drop _prepare_copy method from rset in favor of a more generic copy method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   361
            rset = self.copy(rows, descr)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
            if not offset:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
                # can copy built entity caches
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   364
                copy_cache(rset, 'get_entity', self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
        rset.limited = (limit, offset)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
        return rset
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   367
10313
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
   368
    def printable_rql(self, encoded=_MARKER):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        """return the result set's origin rql as a string, with arguments
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
        substitued
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
        """
10313
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
   372
        if encoded is not _MARKER:
ae9e23cf8790 [rset] Deprecate the 'encoded' argument to ResultSet.printable_rql()
Rémi Cardona <remi.cardona@free.fr>
parents: 10187
diff changeset
   373
            warn('[3.21] the "encoded" argument is deprecated', DeprecationWarning)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
        encoding = self.req.encoding
10314
8f3783dc6358 Don't pass an encoding to rqlst.as_string()
Julien Cristau <julien.cristau@logilab.fr>
parents: 10313
diff changeset
   375
        rqlstr = self.syntax_tree().as_string(kwargs=self.args)
10687
d394bfcd8c25 [py3k] unicode → six.text_type
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
   376
        if PY3:
d394bfcd8c25 [py3k] unicode → six.text_type
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
   377
            return rqlstr
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   378
        # 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
   379
        if not encoded:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
            if isinstance(rqlstr, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   381
                return rqlstr
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   382
            return unicode(rqlstr, encoding)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   383
        else:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
            if isinstance(rqlstr, unicode):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
                return rqlstr.encode(encoding)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
            return rqlstr
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   387
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
    # client helper methods ###################################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   389
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
    def entities(self, col=0):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
        """iter on entities with eid in the `col` column of the result set"""
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10593
diff changeset
   392
        for i in range(len(self)):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
            # 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
   394
            # hacks)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   395
            if self.rows[i][col] is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
                yield self.get_entity(i, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   397
6857
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   398
    def iter_rows_with_entities(self):
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   399
        """ iterates over rows, and for each row
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   400
        eids are converted to plain entities
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   401
        """
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   402
        for i, row in enumerate(self):
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   403
            _row = []
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   404
            for j, col in enumerate(row):
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   405
                try:
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   406
                    _row.append(self.get_entity(i, j) if col is not None else col)
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   407
                except NotAnEntity:
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   408
                    _row.append(col)
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   409
            yield _row
8d2062387134 [rset] add utility method to get entities and attributes from any rset
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6225
diff changeset
   410
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
   411
    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
   412
        """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
   413
        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
   414
        """
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
   415
        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
   416
        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
   417
        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
   418
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
    @cached
4475
37c413a07216 kill most pre 3.2 bw compat code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4427
diff changeset
   420
    def get_entity(self, row, col):
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
   421
        """convenience method for query retrieving a single entity, returns a
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   422
        partially initialized Entity instance.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   423
5314
86e5abbebfaf [doc/book] refresh the autoform section with uicfg content (moved there)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5312
diff changeset
   424
        .. warning::
5312
d2dbba898a96 [doc/book] misc on views, docstrings
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5311
diff changeset
   425
6859
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   426
          Due to the cache wrapping this function, you should NEVER give row as
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   427
          a named parameter (i.e. `rset.get_entity(0, 1)` is OK but
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   428
          `rset.get_entity(row=0, col=1)` isn't)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   430
        :type row,col: int, int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   431
        :param row,col:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
          row and col numbers localizing the entity among the result's table
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   433
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   434
        :return: the partially initialized `Entity` instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   435
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   436
        etype = self.description[row][col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   437
        try:
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   438
            eschema = self.req.vreg.schema.eschema(etype)
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3625
diff changeset
   439
            if eschema.final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   440
                raise NotAnEntity(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   442
            raise NotAnEntity(etype)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
        return self._build_entity(row, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
9347
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   445
    def one(self, col=0):
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   446
        """Retrieve exactly one entity from the query.
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   447
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   448
        If the result set is empty, raises :exc:`NoResultError`.
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   449
        If the result set has more than one row, raises
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   450
        :exc:`MultipleResultsError`.
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   451
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   452
        :type col: int
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   453
        :param col: The column localising the entity in the unique row
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   454
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   455
        :return: the partially initialized `Entity` instance
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   456
        """
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   457
        if len(self) == 1:
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   458
            return self.get_entity(0, col)
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   459
        elif len(self) == 0:
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   460
            raise NoResultError("No row was found for one()")
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   461
        else:
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   462
            raise MultipleResultsError("Multiple rows were found for one()")
bd841d6ae723 [rset] New method: ResultSet.one()
Christophe de Vienne <cdevienne@gmail.com>
parents: 9331
diff changeset
   463
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
   464
    def _build_entity(self, row, col):
6859
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   465
        """internal method to get a single entity, returns a partially
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   466
        initialized Entity instance.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
6859
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   468
        partially means that only attributes selected in the RQL query will be
ace0b991e17b [entity] fix some docstrings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6857
diff changeset
   469
        directly assigned to the entity.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   470
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
        :type row,col: int, int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
        :param row,col:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
          row and col numbers localizing the entity among the result's table
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   474
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
        :return: the partially initialized `Entity` instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   476
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   477
        req = self.req
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
        if req is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
            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
   480
        rowvalues = self.rows[row]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
        eid = rowvalues[col]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
        assert eid is not None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   483
        # return cached entity if exists. This also avoids potential recursion
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
        # XXX should we consider updating a cached entity with possible
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
        #     new attributes found in this resultset ?
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
        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
   487
            entity = req.entity_cache(eid)
10354
635cfac73d28 [repoapi] fold ClientConnection into Connection
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 10314
diff changeset
   488
            entity._cw = req
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   490
            pass
2832
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   491
        else:
3379
9192ba07890d use .cw_rset instead of rset on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3023
diff changeset
   492
            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
   493
                # 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
   494
                # 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
   495
                # info. Add it.
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   496
                entity.cw_rset = self
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   497
                entity.cw_row = row
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   498
                entity.cw_col = col
7fb67c54ffb9 [rset] better explanation, refactor try except
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2813
diff changeset
   499
            return entity
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
        # build entity instance
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   501
        etype = self.description[row][col]
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   502
        entity = self.req.vreg['etypes'].etype_class(etype)(req, rset=self,
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   503
                                                            row=row, col=col)
5557
1a534c596bff [entity] continue cleanup of Entity/AnyEntity namespace
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5532
diff changeset
   504
        entity.eid = eid
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   505
        # cache entity
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
        req.set_entity_cache(entity)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   507
        # try to complete the entity if there are some additional columns
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
        if len(rowvalues) > 1:
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   509
            eschema = entity.e_schema
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   510
            eid_col, attr_cols, rel_cols = self._rset_structure(eschema, col)
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   511
            entity.eid = rowvalues[eid_col]
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   512
            for attr, col_idx in attr_cols.items():
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   513
                entity.cw_attr_cache[attr] = rowvalues[col_idx]
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
   514
            for (rtype, role), col_idx in rel_cols.items():
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   515
                value = rowvalues[col_idx]
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   516
                if value is None:
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   517
                    if role == 'subject':
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   518
                        rql = 'Any Y WHERE X %s Y, X eid %s'
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   519
                    else:
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   520
                        rql = 'Any Y WHERE Y %s X, X eid %s'
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   521
                    rrset = ResultSet([], rql % (rtype, entity.eid))
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   522
                    rrset.req = req
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   523
                else:
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   524
                    rrset = self._build_entity(row, col_idx).as_rset()
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   525
                entity.cw_set_relation_cache(rtype, role, rrset)
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   526
        return entity
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   527
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   528
    @cached
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   529
    def _rset_structure(self, eschema, entity_col):
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   530
        eid_col = col = entity_col
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   531
        rqlst = self.syntax_tree()
10180
ea10572fccfe [rset] fix crash on displaying rset where some symmetric relation is used. Closes #4739253
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9820
diff changeset
   532
        get_rschema = eschema.schema.rschema
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   533
        attr_cols = {}
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   534
        rel_cols = {}
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   535
        if rqlst.TYPE == 'select':
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   536
            # UNION query, find the subquery from which this entity has been
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   537
            # found
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   538
            select, col = rqlst.locate_subquery(entity_col, eschema.type, self.args)
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   539
        else:
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   540
            select = rqlst
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   541
        # take care, due to outer join support, we may find None
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   542
        # values for non final relation
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   543
        for i, attr, role in attr_desc_iterator(select, col, entity_col):
10180
ea10572fccfe [rset] fix crash on displaying rset where some symmetric relation is used. Closes #4739253
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9820
diff changeset
   544
            rschema = get_rschema(attr)
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   545
            if rschema.final:
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   546
                if attr == 'eid':
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   547
                    eid_col = i
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   548
                else:
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   549
                    attr_cols[attr] = i
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   550
            else:
9820
3ad221fe04aa [entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9780
diff changeset
   551
                # XXX takefirst=True to remove warning triggered by ambiguous relations
3ad221fe04aa [entity/rset] replace scary warnings about ambiguous rdefs by XXX in the code
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9780
diff changeset
   552
                rdef = eschema.rdef(attr, role, takefirst=True)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   553
                # only keep value if it can't be multivalued
3877
7ca53fc72a0a reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3766
diff changeset
   554
                if rdef.role_cardinality(role) in '1?':
7285
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   555
                    rel_cols[(attr, role)] = i
39437617f3f0 [optim] cache rset column structures
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 6915
diff changeset
   556
        return eid_col, attr_cols, rel_cols
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   557
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   558
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   559
    def syntax_tree(self):
10087
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
   560
        """return the syntax tree (:class:`rql.stmts.Union`) for the
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
   561
        originating query. You can expect it to have solutions
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
   562
        computed and it will be properly annotated.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   563
        """
10087
ed0b076c119b [rset] kill the rset._rqlst cache
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9820
diff changeset
   564
        return self.req.vreg.parse(self.req, self.rql, self.args)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   565
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   566
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   567
    def column_types(self, col):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   568
        """return the list of different types in the column with the given col
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   569
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   570
        :type col: int
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   571
        :param col: the index of the desired column
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   572
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   573
        :rtype: list
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   574
        :return: the different entities type found in the column
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   575
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   576
        return frozenset(struc[-1][col] for struc in self.description_struct())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   577
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   578
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   579
    def description_struct(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   580
        """return a list describing sequence of results with the same
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   581
        description, e.g. :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   582
        [[0, 4, ('Bug',)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   583
        [[0, 4, ('Bug',), [5, 8, ('Story',)]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   584
        [[0, 3, ('Project', 'Version',)]]
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
        result = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   587
        last = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   588
        for i, row in enumerate(self.description):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   589
            if row != last:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   590
                if last is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   591
                    result[-1][1] = i - 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   592
                result.append( [i, None, row] )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   593
                last = row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   594
        if last is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   595
            result[-1][1] = i
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   596
        return result
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   597
4427
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   598
    def _locate_query_params(self, rqlst, row, col):
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   599
        locate_query_col = col
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   600
        etype = self.description[row][col]
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   601
        # final type, find a better one to locate the correct subquery
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   602
        # (ambiguous if possible)
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4475
diff changeset
   603
        eschema = self.req.vreg.schema.eschema
4427
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   604
        if eschema(etype).final:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   605
            for select in rqlst.children:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   606
                try:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   607
                    myvar = select.selection[col].variable
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   608
                except AttributeError:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   609
                    # not a variable
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   610
                    continue
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10593
diff changeset
   611
                for i in range(len(select.selection)):
4427
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   612
                    if i == col:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   613
                        continue
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   614
                    coletype = self.description[row][i]
6196
12fdccedab5a cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6195
diff changeset
   615
                    # None description possible on column resulting from an
12fdccedab5a cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6195
diff changeset
   616
                    # outer join
4427
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   617
                    if coletype is None or eschema(coletype).final:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   618
                        continue
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   619
                    try:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   620
                        ivar = select.selection[i].variable
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   621
                    except AttributeError:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   622
                        # not a variable
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   623
                        continue
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   624
                    # check variables don't comes from a subquery or are both
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   625
                    # coming from the same subquery
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   626
                    if getattr(ivar, 'query', None) is getattr(myvar, 'query', None):
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   627
                        etype = coletype
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   628
                        locate_query_col = i
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   629
                        if len(self.column_types(i)) > 1:
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   630
                            return etype, locate_query_col
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   631
        return etype, locate_query_col
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   632
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   633
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   634
    def related_entity(self, row, col):
6195
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   635
        """given an cell of the result set, try to return a (entity, relation
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   636
        name) tuple to which this cell is linked.
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   637
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   638
        This is especially useful when the cell is an attribute of an entity,
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   639
        to get the entity to which this attribute belongs to.
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   640
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   641
        rqlst = self.syntax_tree()
6195
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   642
        # UNION query, we've first to find a 'pivot' column to use to get the
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   643
        # actual query from which the row is coming
4427
410c99a917fa fix rset.related_entity with variables coming from subquery while some others not
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   644
        etype, locate_query_col = self._locate_query_params(rqlst, row, col)
6195
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   645
        # now find the query from which this entity has been found. Returned
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   646
        # select node may be a subquery with different column indexes.
3016
5787d1cc8106 [rset] fix #231354 w/ rql 0.22.3 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   647
        select = rqlst.locate_subquery(locate_query_col, etype, self.args)[0]
6195
a0c4441e6ddf [rset] add test for #1251252, actually fixed in rql; fix docstring and add comments in rset.related_entity to make things clearer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5752
diff changeset
   648
        # then get the index of root query's col in the subquery
3016
5787d1cc8106 [rset] fix #231354 w/ rql 0.22.3 api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   649
        col = rqlst.subquery_selection_index(select, col)
3766
9e5dc4b1ada4 work around a pb. with subquery_selection_index
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3764
diff changeset
   650
        if col is None:
9e5dc4b1ada4 work around a pb. with subquery_selection_index
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3764
diff changeset
   651
            # XXX unexpected, should fix subquery_selection_index ?
9e5dc4b1ada4 work around a pb. with subquery_selection_index
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3764
diff changeset
   652
            return None, None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   653
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   654
            myvar = select.selection[col].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   655
        except AttributeError:
572
9849fed789c9 test and fix potential error with None optional relation
sylvain.thenault@logilab.fr
parents: 170
diff changeset
   656
            # not a variable
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   657
            return None, None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   658
        rel = myvar.main_relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   659
        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
   660
            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
   661
            if index is not None and self.rows[row][index]:
5667
04cbd80fd5dc [rset] do not break when rset.related_entity(x,y) is not an entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5532
diff changeset
   662
                try:
04cbd80fd5dc [rset] do not break when rset.related_entity(x,y) is not an entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5532
diff changeset
   663
                    entity = self.get_entity(row, index)
04cbd80fd5dc [rset] do not break when rset.related_entity(x,y) is not an entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5532
diff changeset
   664
                    return entity, rel.r_type
8695
358d8bed9626 [toward-py3k] rewrite to "except AnException as exc:" (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8087
diff changeset
   665
                except NotAnEntity as exc:
5667
04cbd80fd5dc [rset] do not break when rset.related_entity(x,y) is not an entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 5532
diff changeset
   666
                    return None, None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   667
        return None, None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   668
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   669
    @cached
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   670
    def searched_text(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   671
        """returns the searched text in case of full-text search
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   672
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   673
        :return: searched text or `None` if the query is not
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   674
                 a full-text query
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   675
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   676
        rqlst = self.syntax_tree()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   677
        for rel in rqlst.iget_nodes(nodes.Relation):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   678
            if rel.r_type == 'has_text':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   679
                __, rhs = rel.get_variable_parts()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   680
                return rhs.eval(self.args)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   681
        return None
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1477
diff changeset
   682
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   683
def _get_variable(term):
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   684
    # XXX rewritten const
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   685
    # use iget_nodes for (hack) case where we have things like MAX(V)
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   686
    for vref in term.iget_nodes(nodes.VariableRef):
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   687
        return vref.variable
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   688
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   689
def attr_desc_iterator(select, selectidx, rootidx):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   690
    """return an iterator on a list of 2-uple (index, attr_relation)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   691
    localizing attribute relations of the main variable in a result's row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   692
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   693
    :type rqlst: rql.stmts.Select
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   694
    :param rqlst: the RQL syntax tree to describe
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   695
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   696
    :return:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   697
      a generator on (index, relation, target) describing column being
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   698
      attribute of the main variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   699
    """
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   700
    rootselect = select
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   701
    while rootselect.parent.parent is not None:
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   702
        rootselect = rootselect.parent.parent.parent
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   703
    rootmain = rootselect.selection[selectidx]
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   704
    rootmainvar = _get_variable(rootmain)
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   705
    assert rootmainvar
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   706
    root = rootselect.parent
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   707
    selectmain = select.selection[selectidx]
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   708
    for i, term in enumerate(rootselect.selection):
7395
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
   709
        try:
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
   710
            # don't use _get_variable here: if the term isn't a variable
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
   711
            # (function...), we don't want it to be used as an entity attribute
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
   712
            # or relation's value (XXX beside MAX/MIN trick?)
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
   713
            rootvar = term.variable
09ffcc04bd21 [rset] close #1683703: rset.get_entity crash on rql query with subquery and aggregat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6915
diff changeset
   714
        except AttributeError:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   715
            continue
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   716
        if rootvar.name == rootmainvar.name:
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   717
            continue
8085
51929d531aff [rset] fix crash while building entity from rset w/ some subquery. Closes #2089055
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8048
diff changeset
   718
        if select is not rootselect and isinstance(rootvar, nodes.ColumnAlias):
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   719
            term = select.selection[root.subquery_selection_index(select, i)]
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   720
        var = _get_variable(term)
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   721
        if var is None:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   722
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   723
        for ref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   724
            rel = ref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   725
            if rel is None or rel.is_types_restriction():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   726
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   727
            lhs, rhs = rel.get_variable_parts()
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   728
            if selectmain.is_equivalent(lhs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   729
                if rhs.is_equivalent(term):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   730
                    yield (i, rel.r_type, 'subject')
6915
99eb71b311e4 [rset] fix entity building for some result set with UNION and subqueries
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6859
diff changeset
   731
            elif selectmain.is_equivalent(rhs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   732
                if lhs.is_equivalent(term):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   733
                    yield (i, rel.r_type, 'object')