[session] add find_entities and find_one_entity to session/request API (closes #1550045) stable
authorNicolas Chauvat <nicolas.chauvat@logilab.fr>
Mon, 28 Mar 2011 15:15:49 +0200
branchstable
changeset 7116 dfd4680a23f0
parent 7115 1f1d8c35cc3e
child 7117 44775b275d45
[session] add find_entities and find_one_entity to session/request API (closes #1550045)
dataimport.py
doc/book/en/devrepo/testing.rst
req.py
server/migractions.py
--- a/dataimport.py	Mon Mar 28 15:16:11 2011 +0200
+++ b/dataimport.py	Mon Mar 28 15:15:49 2011 +0200
@@ -473,6 +473,11 @@
         self.rql('SET X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % rtype,
                  {'x': int(eid_from), 'y': int(eid_to)})
 
+    def find_entities(self, *args, **kwargs):
+        return self.session.find_entities(*args, **kwargs)
+
+    def find_one_entity(self, *args, **kwargs):
+        return self.session.find_one_entity(*args, **kwargs)
 
 # the import controller ########################################################
 
--- a/doc/book/en/devrepo/testing.rst	Mon Mar 28 15:16:11 2011 +0200
+++ b/doc/book/en/devrepo/testing.rst	Mon Mar 28 15:15:49 2011 +0200
@@ -59,10 +59,10 @@
 
         def setup_database(self):
             req = self.request()
-            group_etype = req.execute('Any X WHERE X name "CWGroup"').get_entity(0,0)
+            group_etype = req.find_one_entity('CWEType', name='CWGroup')
             c1 = req.create_entity('Classification', name=u'classif1',
                                    classifies=group_etype)
-            user_etype = req.execute('Any X WHERE X name "CWUser"').get_entity(0,0)
+            user_etype = req.find_one_entity('CWEType', name='CWUser')
             c2 = req.create_entity('Classification', name=u'classif2',
                                    classifies=user_etype)
             self.kw1 = req.create_entity('Keyword', name=u'kwgroup', included_in=c1)
@@ -228,7 +228,7 @@
 
         def test_admin(self):
             req = self.request()
-            rset = req.execute('Any C WHERE C is Conference')
+            rset = req.find_entities('Conference')
             self.assertListEqual(self.pactions(req, rset),
                                   [('workflow', workflow.WorkflowActions),
                                    ('edit', confactions.ModifyAction),
--- a/req.py	Mon Mar 28 15:16:11 2011 +0200
+++ b/req.py	Mon Mar 28 15:15:49 2011 +0200
@@ -35,6 +35,8 @@
 ONESECOND = timedelta(0, 1, 0)
 CACHE_REGISTRY = {}
 
+class FindEntityError(Exception):
+    """raised when find_one_entity() can not return one and only one entity"""
 
 def _check_cw_unsafe(kwargs):
     if kwargs.pop('_cw_unsafe', False):
@@ -140,6 +142,33 @@
         cls = self.vreg['etypes'].etype_class(etype)
         return cls.cw_instantiate(self.execute, **kwargs)
 
+    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()
+
+    def find_one_entity(self, etype, **kwargs):
+        """find one entity of the given type and attribute values.
+        raise FindEntityError if can not return one and only one entity.
+
+        >>> users = find_one_entity('CWGroup', name=u'users')
+        >>> groups = find_one_entity('CWGroup')
+        Exception()
+        """
+        parts = ['Any X WHERE X is %s' % etype]
+        parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr} for attr in kwargs)
+        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)
+
     def ensure_ro_rql(self, rql):
         """raise an exception if the given rql is not a select query"""
         first = rql.split(None, 1)[0].lower()
--- a/server/migractions.py	Mon Mar 28 15:16:11 2011 +0200
+++ b/server/migractions.py	Mon Mar 28 15:15:49 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -1372,6 +1372,18 @@
             self.commit()
         return entity
 
+    def cmd_find_entities(self, etype, **kwargs):
+        """find entities of the given type and attribute values"""
+        return self._cw.find_entities(etype, **kwargs)
+
+    def cmd_find_one_entity(self, etype, **kwargs):
+        """find one entity of the given type and attribute values.
+
+        raise :exc:`cubicweb.req.FindEntityError` if can not return one and only
+        one entity.
+        """
+        return self._cw.find_one_entity(etype, **kwargs)
+
     def cmd_update_etype_fti_weight(self, etype, weight):
         if self.repo.system_source.dbdriver == 'postgres':
             self.sqlexec('UPDATE appears SET weight=%(weight)s '