diff -r aff75b69db92 -r 2c48c091b6a2 req.py --- a/req.py Tue Jul 02 17:09:04 2013 +0200 +++ b/req.py Mon Jan 13 13:47:47 2014 +0100 @@ -29,7 +29,10 @@ from logilab.common.deprecation import deprecated from logilab.common.date import ustrftime, strptime, todate, todatetime -from cubicweb import Unauthorized, NoSelectableObject, uilib +from rql.utils import rqlvar_maker + +from cubicweb import (Unauthorized, NoSelectableObject, NoResultError, + MultipleResultsError, uilib) from cubicweb.rset import ResultSet ONESECOND = timedelta(0, 1, 0) @@ -169,16 +172,16 @@ cls = self.vreg['etypes'].etype_class(etype) return cls.cw_instantiate(self.execute, **kwargs) + @deprecated('[3.18] use find(etype, **kwargs).entities()') def find_entities(self, etype, **kwargs): """find entities of the given type and attribute values. >>> users = find_entities('CWGroup', name=u'users') >>> groups = find_entities('CWGroup') """ - parts = ['Any X WHERE X is %s' % etype] - parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr} for attr in kwargs) - return self.execute(', '.join(parts), kwargs).entities() + return self.find(etype, **kwargs).entities() + @deprecated('[3.18] use find(etype, **kwargs).one()') def find_one_entity(self, etype, **kwargs): """find one entity of the given type and attribute values. raise :exc:`FindEntityError` if can not return one and only one entity. @@ -187,14 +190,43 @@ >>> groups = find_one_entity('CWGroup') Exception() """ + try: + return self.find(etype, **kwargs).one() + except (NoResultError, MultipleResultsError) as e: + raise FindEntityError("%s: (%s, %s)" % (str(e), etype, kwargs)) + + def find(self, etype, **kwargs): + """find entities of the given type and attribute values. + + :returns: A :class:`ResultSet` + + >>> users = find('CWGroup', name=u"users").one() + >>> groups = find('CWGroup').entities() + """ parts = ['Any X WHERE X is %s' % etype] - parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr} for attr in kwargs) + varmaker = rqlvar_maker(defined='X') + eschema = self.vreg.schema[etype] + for attr, value in kwargs.items(): + if isinstance(value, list) or isinstance(value, tuple): + raise NotImplementedError("List of values are not supported") + if hasattr(value, 'eid'): + kwargs[attr] = value.eid + if attr.startswith('reverse_'): + attr = attr[8:] + assert attr in eschema.objrels, \ + '%s not in %s object relations' % (attr, eschema) + parts.append( + '%(varname)s %(attr)s X, ' + '%(varname)s eid %%(reverse_%(attr)s)s' + % {'attr': attr, 'varname': varmaker.next()}) + else: + assert attr in eschema.subjrels, \ + '%s not in %s subject relations' % (attr, eschema) + parts.append('X %(attr)s %%(%(attr)s)s' % {'attr': attr}) + rql = ', '.join(parts) - rset = self.execute(rql, kwargs) - if len(rset) != 1: - raise FindEntityError('Found %i entitie(s) when 1 was expected (rql=%s ; %s)' - % (len(rset), rql, repr(kwargs))) - return rset.get_entity(0,0) + + return self.execute(rql, kwargs) def ensure_ro_rql(self, rql): """raise an exception if the given rql is not a select query""" @@ -437,7 +469,7 @@ """return the root url of the instance """ if secure: - return self.vreg.config.get('https-url', self.vreg.config['base-url']) + return self.vreg.config.get('https-url') or self.vreg.config['base-url'] return self.vreg.config['base-url'] # abstract methods to override according to the web front-end #############