16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
18 """The `ResultSet` class which is returned as result of an rql query""" |
18 """The `ResultSet` class which is returned as result of an rql query""" |
19 |
19 |
20 |
20 |
21 from warnings import warn |
|
22 |
|
23 from six import PY3, text_type |
21 from six import PY3, text_type |
24 from six.moves import range |
22 from six.moves import range |
25 |
23 |
26 from logilab.common import nullobject |
|
27 from logilab.common.decorators import cached, clear_cache, copy_cache |
24 from logilab.common.decorators import cached, clear_cache, copy_cache |
28 from rql import nodes, stmts |
25 from rql import nodes, stmts |
29 |
26 |
30 from cubicweb import NotAnEntity, NoResultError, MultipleResultsError, UnknownEid |
27 from cubicweb import NotAnEntity, NoResultError, MultipleResultsError, UnknownEid |
31 |
|
32 |
|
33 _MARKER = nullobject() |
|
34 |
28 |
35 |
29 |
36 class ResultSet(object): |
30 class ResultSet(object): |
37 """A result set wraps a RQL query result. This object implements |
31 """A result set wraps a RQL query result. This object implements |
38 partially the list protocol to allow direct use as a list of |
32 partially the list protocol to allow direct use as a list of |
50 |
44 |
51 :type rql: str or unicode |
45 :type rql: str or unicode |
52 :param rql: the original RQL query string |
46 :param rql: the original RQL query string |
53 """ |
47 """ |
54 |
48 |
55 def __init__(self, results, rql, args=None, description=None, rqlst=None): |
49 def __init__(self, results, rql, args=None, description=None): |
56 if rqlst is not None: |
|
57 warn('[3.20] rqlst parameter is deprecated', |
|
58 DeprecationWarning, stacklevel=2) |
|
59 self.rows = results |
50 self.rows = results |
60 self.rowcount = results and len(results) or 0 |
51 self.rowcount = results and len(results) or 0 |
61 # original query and arguments |
52 # original query and arguments |
62 self.rql = rql |
53 self.rql = rql |
63 self.args = args |
54 self.args = args |
361 # can copy built entity caches |
352 # can copy built entity caches |
362 copy_cache(rset, 'get_entity', self) |
353 copy_cache(rset, 'get_entity', self) |
363 rset.limited = (limit, offset) |
354 rset.limited = (limit, offset) |
364 return rset |
355 return rset |
365 |
356 |
366 def printable_rql(self, encoded=_MARKER): |
357 def printable_rql(self): |
367 """return the result set's origin rql as a string, with arguments |
358 """return the result set's origin rql as a string, with arguments |
368 substitued |
359 substitued |
369 """ |
360 """ |
370 if encoded is not _MARKER: |
|
371 warn('[3.21] the "encoded" argument is deprecated', DeprecationWarning) |
|
372 encoding = self.req.encoding |
361 encoding = self.req.encoding |
373 rqlstr = self.syntax_tree().as_string(kwargs=self.args) |
362 rqlstr = self.syntax_tree().as_string(kwargs=self.args) |
374 if PY3: |
363 if PY3: |
375 return rqlstr |
364 return rqlstr |
376 # sounds like we get encoded or unicode string due to a bug in as_string |
365 if isinstance(rqlstr, text_type): |
377 if not encoded: |
|
378 if isinstance(rqlstr, text_type): |
|
379 return rqlstr |
|
380 return text_type(rqlstr, encoding) |
|
381 else: |
|
382 if isinstance(rqlstr, text_type): |
|
383 return rqlstr.encode(encoding) |
|
384 return rqlstr |
366 return rqlstr |
|
367 return text_type(rqlstr, encoding) |
385 |
368 |
386 # client helper methods ################################################### |
369 # client helper methods ################################################### |
387 |
370 |
388 def entities(self, col=0): |
371 def entities(self, col=0): |
389 """iter on entities with eid in the `col` column of the result set""" |
372 """iter on entities with eid in the `col` column of the result set""" |