27 |
27 |
28 from logilab.common.decorators import cached |
28 from logilab.common.decorators import cached |
29 from logilab.common.deprecation import deprecated |
29 from logilab.common.deprecation import deprecated |
30 from logilab.common.date import ustrftime, strptime, todate, todatetime |
30 from logilab.common.date import ustrftime, strptime, todate, todatetime |
31 |
31 |
32 from cubicweb import Unauthorized, NoSelectableObject, uilib |
32 from rql.utils import rqlvar_maker |
|
33 |
|
34 from cubicweb import (Unauthorized, NoSelectableObject, NoResultError, |
|
35 MultipleResultsError, uilib) |
33 from cubicweb.rset import ResultSet |
36 from cubicweb.rset import ResultSet |
34 |
37 |
35 ONESECOND = timedelta(0, 1, 0) |
38 ONESECOND = timedelta(0, 1, 0) |
36 CACHE_REGISTRY = {} |
39 CACHE_REGISTRY = {} |
37 |
40 |
167 |
170 |
168 """ |
171 """ |
169 cls = self.vreg['etypes'].etype_class(etype) |
172 cls = self.vreg['etypes'].etype_class(etype) |
170 return cls.cw_instantiate(self.execute, **kwargs) |
173 return cls.cw_instantiate(self.execute, **kwargs) |
171 |
174 |
|
175 @deprecated('[3.18] use find(etype, **kwargs).entities()') |
172 def find_entities(self, etype, **kwargs): |
176 def find_entities(self, etype, **kwargs): |
173 """find entities of the given type and attribute values. |
177 """find entities of the given type and attribute values. |
174 |
178 |
175 >>> users = find_entities('CWGroup', name=u'users') |
179 >>> users = find_entities('CWGroup', name=u'users') |
176 >>> groups = find_entities('CWGroup') |
180 >>> groups = find_entities('CWGroup') |
177 """ |
181 """ |
178 parts = ['Any X WHERE X is %s' % etype] |
182 return self.find(etype, **kwargs).entities() |
179 parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr} for attr in kwargs) |
183 |
180 return self.execute(', '.join(parts), kwargs).entities() |
184 @deprecated('[3.18] use find(etype, **kwargs).one()') |
181 |
|
182 def find_one_entity(self, etype, **kwargs): |
185 def find_one_entity(self, etype, **kwargs): |
183 """find one entity of the given type and attribute values. |
186 """find one entity of the given type and attribute values. |
184 raise :exc:`FindEntityError` if can not return one and only one entity. |
187 raise :exc:`FindEntityError` if can not return one and only one entity. |
185 |
188 |
186 >>> users = find_one_entity('CWGroup', name=u'users') |
189 >>> users = find_one_entity('CWGroup', name=u'users') |
187 >>> groups = find_one_entity('CWGroup') |
190 >>> groups = find_one_entity('CWGroup') |
188 Exception() |
191 Exception() |
189 """ |
192 """ |
|
193 try: |
|
194 return self.find(etype, **kwargs).one() |
|
195 except (NoResultError, MultipleResultsError) as e: |
|
196 raise FindEntityError("%s: (%s, %s)" % (str(e), etype, kwargs)) |
|
197 |
|
198 def find(self, etype, **kwargs): |
|
199 """find entities of the given type and attribute values. |
|
200 |
|
201 :returns: A :class:`ResultSet` |
|
202 |
|
203 >>> users = find('CWGroup', name=u"users").one() |
|
204 >>> groups = find('CWGroup').entities() |
|
205 """ |
190 parts = ['Any X WHERE X is %s' % etype] |
206 parts = ['Any X WHERE X is %s' % etype] |
191 parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr} for attr in kwargs) |
207 varmaker = rqlvar_maker(defined='X') |
|
208 eschema = self.vreg.schema[etype] |
|
209 for attr, value in kwargs.items(): |
|
210 if isinstance(value, list) or isinstance(value, tuple): |
|
211 raise NotImplementedError("List of values are not supported") |
|
212 if hasattr(value, 'eid'): |
|
213 kwargs[attr] = value.eid |
|
214 if attr.startswith('reverse_'): |
|
215 attr = attr[8:] |
|
216 assert attr in eschema.objrels, \ |
|
217 '%s not in %s object relations' % (attr, eschema) |
|
218 parts.append( |
|
219 '%(varname)s %(attr)s X, ' |
|
220 '%(varname)s eid %%(reverse_%(attr)s)s' |
|
221 % {'attr': attr, 'varname': varmaker.next()}) |
|
222 else: |
|
223 assert attr in eschema.subjrels, \ |
|
224 '%s not in %s subject relations' % (attr, eschema) |
|
225 parts.append('X %(attr)s %%(%(attr)s)s' % {'attr': attr}) |
|
226 |
192 rql = ', '.join(parts) |
227 rql = ', '.join(parts) |
193 rset = self.execute(rql, kwargs) |
228 |
194 if len(rset) != 1: |
229 return self.execute(rql, kwargs) |
195 raise FindEntityError('Found %i entitie(s) when 1 was expected (rql=%s ; %s)' |
|
196 % (len(rset), rql, repr(kwargs))) |
|
197 return rset.get_entity(0,0) |
|
198 |
230 |
199 def ensure_ro_rql(self, rql): |
231 def ensure_ro_rql(self, rql): |
200 """raise an exception if the given rql is not a select query""" |
232 """raise an exception if the given rql is not a select query""" |
201 first = rql.split(None, 1)[0].lower() |
233 first = rql.split(None, 1)[0].lower() |
202 if first in ('insert', 'set', 'delete'): |
234 if first in ('insert', 'set', 'delete'): |