Merge stable into default (NON-TRIVIAL)
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Tue, 12 Mar 2013 12:04:51 +0100
changeset 8724 1beab80aed23
parent 8721 b399c87df63c (current diff)
parent 8723 d2472948da9c (diff)
child 8725 29e19ca141fc
Merge stable into default (NON-TRIVIAL) - dropping __future__ statement added by d2472948da9c - added migration from 407acc41beb5 to migration file for 3.16.1
cwctl.py
dataimport.py
ext/rest.py
hooks/syncschema.py
hooks/test/unittest_syncschema.py
misc/migration/3.16.1_Any.py
web/application.py
web/views/debug.py
--- a/cwctl.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/cwctl.py	Tue Mar 12 12:04:51 2013 +0100
@@ -830,10 +830,7 @@
     in batch mode.
 
     By default it will connect to a local instance using an in memory
-    connection, unless -P option is specified, in which case you will be
-    connected through pyro. In the later case, you won't have access to
-    repository internals (session, etc...) so most migration commands won't be
-    available.
+    connection, unless an URL to a running instance is specified.
 
     Arguments after bare "--" string will not be processed by the shell command
     You can use it to pass extra arguments to your script and expect for
--- a/doc/book/en/devrepo/devcore/dbapi.rst	Fri Feb 22 11:17:02 2013 +0100
+++ b/doc/book/en/devrepo/devcore/dbapi.rst	Tue Mar 12 12:04:51 2013 +0100
@@ -111,15 +111,18 @@
    :members:
 
 
-The `Cursor` API
-~~~~~~~~~~~~~~~~
+The `Cursor` and `Connection` API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The whole cursor API is developped below.
 
 .. note::
 
-  In practice we use the `.execute` method on the _cw object of
+  In practice you'll usually use the `.execute` method on the _cw object of
   appobjects. Usage of other methods is quite rare.
 
 .. autoclass:: cubicweb.dbapi.Cursor
    :members:
+
+.. autoclass:: cubicweb.dbapi.Connection
+   :members:
--- a/ext/rest.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/ext/rest.py	Tue Mar 12 12:04:51 2013 +0100
@@ -96,7 +96,16 @@
                             **options)], []
 
 def rql_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
-    """:rql:`Any X,Y WHERE X is CWUser, X login Y:table`"""
+    """:rql:`<rql-expr>` or :rql:`<rql-expr>:<vid>`
+
+    Example: :rql:`Any X,Y WHERE X is CWUser, X login Y:table`
+
+    Replace the directive with the output of applying the view to the resultset
+    returned by the query.
+
+    "X eid %(userid)s" can be used in the RQL query for this query will be
+    executed with the argument {'userid': _cw.user.eid}.
+    """
     _cw = inliner.document.settings.context._cw
     text = text.strip()
     if ':' in text:
--- a/hooks/syncschema.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/hooks/syncschema.py	Tue Mar 12 12:04:51 2013 +0100
@@ -244,7 +244,7 @@
     * create the necessary table
     * set creation_date and modification_date by creating the necessary
       CWAttribute entities
-    * add owned_by relation by creating the necessary CWRelation entity
+    * add <meta rtype> relation by creating the necessary CWRelation entity
     """
     entity = None # make pylint happy
 
@@ -270,9 +270,16 @@
             except KeyError:
                 self.critical('rtype %s was not handled at cwetype creation time', rtype)
                 continue
+            if not rschema.rdefs:
+                self.warning('rtype %s has no relation definition yet', rtype)
+                continue
             sampletype = rschema.subjects()[0]
             desttype = rschema.objects()[0]
-            rdef = copy(rschema.rdef(sampletype, desttype))
+            try:
+                rdef = copy(rschema.rdef(sampletype, desttype))
+            except KeyError:
+                # this combo does not exist because this is not a universal META_RTYPE
+                continue
             rdef.subject = _MockEntity(eid=entity.eid)
             mock = _MockEntity(eid=None)
             ss.execschemarql(session.execute, mock, ss.rdef2rql(rdef, cmap, gmap))
--- a/hooks/test/unittest_syncschema.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/hooks/test/unittest_syncschema.py	Tue Mar 12 12:04:51 2013 +0100
@@ -20,10 +20,12 @@
 from logilab.common.testlib import TestCase, unittest_main
 
 from cubicweb import ValidationError
+from cubicweb.schema import META_RTYPES
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.server.sqlutils import SQL_PREFIX
 from cubicweb.devtools.repotest import schema_eids_idx, restore_schema_eids_idx
 
+
 def tearDownModule(*args):
     del SchemaModificationHooksTC.schema_eids
 
@@ -116,6 +118,33 @@
         self.assertFalse(schema.has_entity('concerne2'))
         self.assertFalse('concerne2' in schema['CWUser'].subject_relations())
 
+    def test_metartype_with_nordefs(self):
+        META_RTYPES.add('custom_meta')
+        self.execute('INSERT CWRType X: X name "custom_meta", X description "", '
+                     'X final FALSE, X symmetric FALSE')
+        self.commit()
+        eeid = self.execute('INSERT CWEType X: X name "NEWEtype", '
+                            'X description "", X final FALSE')[0][0]
+        self._set_perms(eeid)
+        self.commit()
+        META_RTYPES.remove('custom_meta')
+
+    def test_metartype_with_somerdefs(self):
+        META_RTYPES.add('custom_meta')
+        self.execute('INSERT CWRType X: X name "custom_meta", X description "", '
+                     'X final FALSE, X symmetric FALSE')
+        self.commit()
+        rdefeid = self.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, '
+                               '   X from_entity E, X to_entity E '
+                               'WHERE RT name "custom_meta", E name "CWUser"')[0][0]
+        self._set_perms(rdefeid)
+        self.commit()
+        eeid = self.execute('INSERT CWEType X: X name "NEWEtype", '
+                            'X description "", X final FALSE')[0][0]
+        self._set_perms(eeid)
+        self.commit()
+        META_RTYPES.remove('custom_meta')
+
     def test_is_instance_of_insertions(self):
         seid = self.execute('INSERT Transition T: T name "subdiv"')[0][0]
         is_etypes = [etype for etype, in self.execute('Any ETN WHERE X eid %s, X is ET, ET name ETN' % seid)]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.15.9_Any.py	Tue Mar 12 12:04:51 2013 +0100
@@ -0,0 +1,2 @@
+sync_schema_props_perms(('State', 'state_of', 'Workflow'), commit=False)
+sync_schema_props_perms(('State', 'name', 'String'))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.16.1_Any.py	Tue Mar 12 12:04:51 2013 +0100
@@ -0,0 +1,2 @@
+sync_schema_props_perms(('State', 'state_of', 'Workflow'), commit=False)
+sync_schema_props_perms(('State', 'name', 'String'))
--- a/schemas/workflow.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/schemas/workflow.py	Tue Mar 12 12:04:51 2013 +0100
@@ -79,7 +79,7 @@
     state_of = SubjectRelation('Workflow', cardinality='1*', composite='object',
                                description=_('workflow to which this state belongs'),
                                constraints=[RQLUniqueConstraint('S name N, Y state_of O, Y name N', 'Y',
-                                                                _('workflow already have a state of that name'))])
+                                                                _('workflow already has a state of that name'))])
 
 
 class BaseTransition(EntityType):
--- a/web/application.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/web/application.py	Tue Mar 12 12:04:51 2013 +0100
@@ -541,7 +541,7 @@
         req.reset_message()
         req.reset_headers()
         if req.ajax_request:
-            return ajax_error_handler(req, ex)
+            return self.ajax_error_handler(req, ex)
         try:
             req.data['ex'] = ex
             if tb:
--- a/web/views/debug.py	Fri Feb 22 11:17:02 2013 +0100
+++ b/web/views/debug.py	Tue Mar 12 12:04:51 2013 +0100
@@ -131,10 +131,13 @@
             sessions = SESSION_MANAGER.current_sessions()
             w(u'<h3>%s</h3>' % _('opened web sessions'))
             if sessions:
+                n_no_cnx_sessions = 0
                 w(u'<ul>')
                 for session in sessions:
                     if not session.cnx:
-                        w(u'<li>%s (NO CNX)</li>' % session.sessionid)
+                        # We do not want to list all sessions without cnx
+                        # Their session ID are useless, hence we just count them
+                        n_no_cnx_sessions += 1
                         continue
                     try:
                         last_usage_time = session.cnx.check()
@@ -148,6 +151,9 @@
                     dict_to_html(w, session.data)
                     w(u'</li>')
                 w(u'</ul>')
+                if n_no_cnx_sessions > 0:
+                    w(u'<h3>%s %s</h3>' % (n_no_cnx_sessions,
+                                           _('web sessions without CNX')))
             else:
                 w(u'<p>%s</p>' % _('no web sessions found'))