backport stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 27 Jun 2011 15:30:52 +0200
changeset 7562 cdef82ca9eab
parent 7554 fdace9d67d96 (current diff)
parent 7561 45ff0b097be0 (diff)
child 7563 8e129bb6b571
backport stable
.hgtags
__pkginfo__.py
debian/changelog
hooks/syncschema.py
i18n/fr.po
misc/migration/bootstrapmigration_repository.py
server/migractions.py
server/repository.py
server/sources/native.py
web/views/basecontrollers.py
--- a/.hgtags	Thu Jun 23 07:41:25 2011 +0200
+++ b/.hgtags	Mon Jun 27 15:30:52 2011 +0200
@@ -206,3 +206,7 @@
 105767487c7075dbcce36474f1af0485985cbf2c cubicweb-debian-version-3.12.6-1
 b661ef475260ca7d9ea5c36ba2cc86e95e5b17d3 cubicweb-version-3.13.0
 a96137858f571711678954477da6f7f435870cea cubicweb-debian-version-3.13.0-1
+628fe57ce746c1dac87fb1b078b2026057df894e cubicweb-version-3.12.7
+a07517985136bbbfa6610c428a1b42cd04cd530b cubicweb-debian-version-3.12.7-1
+50122a47ce4fb2ecbf3cf20ed2777f4276c93609 cubicweb-version-3.12.8
+cf49ed55685a810d8d73585330ad1a57cc76260d cubicweb-debian-version-3.12.8-1
--- a/debian/changelog	Thu Jun 23 07:41:25 2011 +0200
+++ b/debian/changelog	Mon Jun 27 15:30:52 2011 +0200
@@ -4,6 +4,18 @@
 
  -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Thu, 09 Jun 2011 20:18:41 +0200
 
+cubicweb (3.12.8-1) unstable; urgency=low
+
+  * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Mon, 27 Jun 2011 13:58:58 +0200
+
+cubicweb (3.12.7-1) unstable; urgency=low
+
+  * new upstream release
+
+ -- Sylvain Thénault <sylvain.thenault@logilab.fr>  Tue, 21 Jun 2011 14:47:14 +0200
+
 cubicweb (3.12.6-1) unstable; urgency=low
 
   * new upstream release
--- a/hooks/syncschema.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/hooks/syncschema.py	Mon Jun 27 15:30:52 2011 +0200
@@ -266,7 +266,7 @@
         for rtype in (META_RTYPES - VIRTUAL_RTYPES):
             try:
                 rschema = schema[rtype]
-            except:
+            except KeyError:
                 if rtype == 'cw_source':
                     continue # XXX 3.10 migration
                 raise
--- a/i18n/fr.po	Thu Jun 23 07:41:25 2011 +0200
+++ b/i18n/fr.po	Mon Jun 27 15:30:52 2011 +0200
@@ -4,7 +4,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: cubicweb 2.46.0\n"
-"PO-Revision-Date: 2011-04-29 12:57+0200\n"
+"PO-Revision-Date: 2011-06-23 10:23+0200\n"
 "Last-Translator: Logilab Team <contact@logilab.fr>\n"
 "Language-Team: fr <contact@logilab.fr>\n"
 "Language: \n"
@@ -4104,8 +4104,13 @@
 msgid "tr_count"
 msgstr "n° de transition"
 
+<<<<<<< /home/syt/src/fcubicweb/cubicweb/i18n/fr.po
 msgid "transaction undoed"
 msgstr "transaction annulée"
+=======
+msgid "transaction undone"
+msgstr "transaction annulée"
+>>>>>>> /tmp/fr.po~other.p9Lq3c
 
 #, python-format
 msgid "transition %(tr)s isn't allowed from %(st)s"
--- a/misc/migration/3.10.9_Any.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/misc/migration/3.10.9_Any.py	Mon Jun 27 15:30:52 2011 +0200
@@ -11,7 +11,7 @@
     from logilab.common.shellutils import progress
     from cubicweb.server.session import hooks_control
     rset = rql('Any X, XC WHERE X cwuri XC, X cwuri ~= "%/eid/%"')
-    title = "%i entites to fix" % len(rset)
+    title = "%i entities to fix" % len(rset)
     nbops = rset.rowcount
     enabled = interactive_mode
     with progress(title=title, nbops=nbops, size=30, enabled=enabled) as pb:
--- a/misc/migration/bootstrapmigration_repository.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/misc/migration/bootstrapmigration_repository.py	Mon Jun 27 15:30:52 2011 +0200
@@ -100,7 +100,7 @@
             drop_relation_definition('CWRType', '%s_permission' % action, 'RQLExpression')
     sync_schema_props_perms('read_permission', syncperms=False) # fix read_permission cardinality
 
-if applcubicwebversion < (3, 9, 6) and cubicwebversion >= (3, 9, 6):
+if applcubicwebversion < (3, 9, 6) and cubicwebversion >= (3, 9, 6) and not 'CWUniqueTogetherConstraint' in schema:
     add_entity_type('CWUniqueTogetherConstraint')
 
 if not ('CWUniqueTogetherConstraint', 'CWRType') in schema['relations'].rdefs:
--- a/rqlrewrite.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/rqlrewrite.py	Mon Jun 27 15:30:52 2011 +0200
@@ -467,6 +467,7 @@
         original query, return that relation node
         """
         rschema = self.schema.rschema(sniprel.r_type)
+        stmt = self.current_statement()
         for vi in self.varinfos:
             try:
                 if target == 'object':
@@ -482,6 +483,9 @@
             except KeyError:
                 # may be raised by vi['xhs_rels'][sniprel.r_type]
                 return None
+            # don't share if relation's statement is not the current statement
+            if orel.stmt is not stmt:
+                return None
             # can't share neged relation or relations with different outer join
             if (orel.neged(strict=True) or sniprel.neged(strict=True)
                 or (orel.optional and orel.optional != sniprel.optional)):
@@ -498,9 +502,10 @@
     def _use_orig_term(self, snippet_varname, term):
         key = (self.current_expr, self.varmap, snippet_varname)
         if key in self.rewritten:
-            insertedvar = self.select.defined_vars.pop(self.rewritten[key])
+            stmt = self.current_statement()
+            insertedvar = stmt.defined_vars.pop(self.rewritten[key])
             for inserted_vref in insertedvar.references():
-                inserted_vref.parent.replace(inserted_vref, term.copy(self.select))
+                inserted_vref.parent.replace(inserted_vref, term.copy(stmt))
         self.rewritten[key] = term.name
 
     def _get_varname_or_term(self, vname):
--- a/selectors.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/selectors.py	Mon Jun 27 15:30:52 2011 +0200
@@ -1253,7 +1253,7 @@
 def on_fire_transition(etype, tr_name, from_state_name=None):
     """Return 1 when entity of the type `etype` is going through transition of
     the name `tr_name`.
-    
+
     If `from_state_name` is specified, this selector will also check the
     incoming state.
 
@@ -1262,7 +1262,7 @@
     will reference the matching `TrInfo` entity, allowing to get all the
     transition details (including the entity to which is applied the transition
     but also its original state, transition, destination state, user...).
-    
+
     See :class:`cubicweb.entities.wfobjs.TrInfo` for more information.
     """
     def match_etype_and_transition(trinfo):
--- a/server/migractions.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/server/migractions.py	Mon Jun 27 15:30:52 2011 +0200
@@ -739,9 +739,15 @@
 
         `attrname` is a string giving the name of the attribute to drop
         """
-        rschema = self.repo.schema.rschema(attrname)
-        attrtype = rschema.objects(etype)[0]
-        self.cmd_drop_relation_definition(etype, attrname, attrtype, commit=commit)
+        try:
+            rschema = self.repo.schema.rschema(attrname)
+            attrtype = rschema.objects(etype)[0]
+        except KeyError:
+            print 'warning: attribute %s %s is not known, skip deletion' % (
+                etype, attrname)
+        else:
+            self.cmd_drop_relation_definition(etype, attrname, attrtype,
+                                              commit=commit)
 
     def cmd_rename_attribute(self, etype, oldname, newname, commit=True):
         """rename an existing attribute of the given entity type
@@ -774,8 +780,9 @@
         """
         instschema = self.repo.schema
         eschema = self.fs_schema.eschema(etype)
-        assert eschema.final or not etype in instschema, \
-               '%s already defined in the instance schema' % etype
+        if etype in instschema and not (eschema.final and eschema.eid is None):
+            print 'warning: %s already known, skip addition' % etype
+            return
         confirm = self.verbosity >= 2
         groupmap = self.group_mapping()
         cstrtypemap = self.cstrtype_mapping()
@@ -1003,6 +1010,10 @@
 
         """
         reposchema = self.repo.schema
+        if rtype in reposchema:
+            print 'warning: relation type %s is already known, skip addition' % (
+                rtype)
+            return
         rschema = self.fs_schema.rschema(rtype)
         execute = self._cw.execute
         # register the relation into CWRType and insert necessary relation
@@ -1069,6 +1080,10 @@
         rschema = self.fs_schema.rschema(rtype)
         if not rtype in self.repo.schema:
             self.cmd_add_relation_type(rtype, addrdef=False, commit=True)
+        if (subjtype, objtype) in self.repo.schema.rschema(rtype).rdefs:
+            print 'warning: relation %s %s %s is already known, skip addition' % (
+                subjtype, rtype, objtype)
+            return
         execute = self._cw.execute
         rdef = self._get_rdef(rschema, subjtype, objtype)
         ss.execschemarql(execute, rdef,
--- a/server/repository.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/server/repository.py	Mon Jun 27 15:30:52 2011 +0200
@@ -231,6 +231,7 @@
         self.sources_by_eid = {}
         if self.config.quick_start \
                or not 'CWSource' in self.schema: # # 3.10 migration
+            self.system_source.init_creating()
             return
         session = self.internal_session()
         try:
--- a/server/sources/native.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/server/sources/native.py	Mon Jun 27 15:30:52 2011 +0200
@@ -751,7 +751,7 @@
                     session.cnxset.connection(self.uri).rollback()
                     if self.repo.config.mode != 'test':
                         self.critical('transaction has been rollbacked')
-                except:
+                except Exception, ex:
                     pass
             if ex.__class__.__name__ == 'IntegrityError':
                 # need string comparison because of various backends
@@ -1627,7 +1627,7 @@
     * a list of rows (as tuples with one element per column)
 
     Tables are saved in chunks in different files in order to prevent
-    a too high memory consumption. 
+    a too high memory consumption.
     """
     def __init__(self, source):
         """
--- a/test/data/rewrite/schema.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/test/data/rewrite/schema.py	Mon Jun 27 15:30:52 2011 +0200
@@ -27,8 +27,8 @@
         'delete': ('managers', 'owners', ERQLExpression('X concerne S, S owned_by U')),
         }
     ref = String(fulltextindexed=True, indexed=True, maxsize=16)
-    documented_by = SubjectRelation('Card')
-    concerne = SubjectRelation(('Societe', 'Note'))
+    documented_by = SubjectRelation('Card', cardinality='1*')
+    concerne = SubjectRelation(('Societe', 'Note'), cardinality='1*')
 
 
 class Societe(EntityType):
--- a/test/unittest_rqlrewrite.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/test/unittest_rqlrewrite.py	Mon Jun 27 15:30:52 2011 +0200
@@ -33,7 +33,8 @@
     config.bootstrap_cubes()
     schema = config.load_schema()
     from yams.buildobjs import RelationDefinition
-    schema.add_relation_def(RelationDefinition(subject='Card', name='in_state', object='State', cardinality='1*'))
+    schema.add_relation_def(RelationDefinition(subject='Card', name='in_state',
+                                               object='State', cardinality='1*'))
 
     rqlhelper = RQLHelper(schema, special_relations={'eid': 'uid',
                                                      'has_text': 'fti'})
@@ -78,12 +79,21 @@
     return rewriter.rewritten
 
 def test_vrefs(node):
-    vrefmap = {}
+    vrefmaps = {}
+    selects = []
     for vref in node.iget_nodes(nodes.VariableRef):
-        vrefmap.setdefault(vref.name, set()).add(vref)
-    for var in node.defined_vars.itervalues():
-        assert var.stinfo['references']
-        assert not (var.stinfo['references'] ^ vrefmap[var.name]), (node.as_string(), var.stinfo['references'], vrefmap[var.name])
+        stmt = vref.stmt
+        try:
+            vrefmaps[stmt].setdefault(vref.name, set()).add(vref)
+        except KeyError:
+            vrefmaps[stmt] = {vref.name: set( (vref,) )}
+            selects.append(stmt)
+    assert node in selects
+    for stmt in selects:
+        for var in stmt.defined_vars.itervalues():
+            assert var.stinfo['references']
+            vrefmap = vrefmaps[stmt]
+            assert not (var.stinfo['references'] ^ vrefmap[var.name]), (node.as_string(), var, var.stinfo['references'], vrefmap[var.name])
 
 
 class RQLRewriteTC(TestCase):
@@ -140,7 +150,7 @@
                              "EXISTS(2 in_state A, B in_group D, E require_state A, "
                              "E name 'read', E require_group D, A is State, D is CWGroup, E is CWPermission)")
 
-    def test_optional_var_base_1(self):
+    def test_optional_var_1(self):
         constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
         rqlst = parse('Any A,C WHERE A documented_by C?')
@@ -151,7 +161,7 @@
                              "(Any C WHERE EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', "
                              "G require_group F), D eid %(A)s, C is Card)")
 
-    def test_optional_var_base_2(self):
+    def test_optional_var_2(self):
         constraint = ('X in_state S, U in_group G, P require_state S,'
                            'P name "read", P require_group G')
         rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T')
@@ -163,7 +173,7 @@
                              "G require_state B, G name 'read', G require_group F), "
                              "D eid %(A)s, C is Card)")
 
-    def test_optional_var_base_3(self):
+    def test_optional_var_3(self):
         constraint1 = ('X in_state S, U in_group G, P require_state S,'
                        'P name "read", P require_group G')
         constraint2 = 'X in_state S, S name "public"'
@@ -176,6 +186,21 @@
                              "D eid %(A)s, C is Card, "
                              "EXISTS(C in_state E, E name 'public'))")
 
+    def test_optional_var_4(self):
+        constraint1 = 'A created_by U, X documented_by A'
+        constraint2 = 'A created_by U, X concerne A'
+        constraint3 = 'X created_by U'
+        rqlst = parse('Any X,LA,Y WHERE LA? documented_by X, LA concerne Y')
+        rewrite(rqlst, {('LA', 'X'): (constraint1, constraint2),
+                        ('X', 'X'): (constraint3,),
+                        ('Y', 'X'): (constraint3,)}, {})
+        self.failUnlessEqual(rqlst.as_string(),
+                             u'Any X,LA,Y WHERE LA? documented_by X, LA concerne Y, B eid %(C)s, '
+                             'EXISTS(X created_by B), EXISTS(Y created_by B), '
+                             'X is Card, Y is IN(Division, Note, Societe) '
+                             'WITH LA BEING (Any LA WHERE EXISTS(A created_by B, LA documented_by A), '
+                             'B eid %(D)s, LA is Affaire, EXISTS(E created_by B, LA concerne E))')
+
     def test_optional_var_inlined(self):
         c1 = ('X require_permission P')
         c2 = ('X inlined_card O, O require_permission P')
--- a/web/views/basecontrollers.py	Thu Jun 23 07:41:25 2011 +0200
+++ b/web/views/basecontrollers.py	Mon Jun 27 15:30:52 2011 +0200
@@ -603,16 +603,14 @@
         errors = self._cw.cnx.undo_transaction(txuuid)
         if not errors:
             self.redirect()
-        return self._cw._('some errors occurred:') + self._cw.view(
-            'pyvallist', pyvalue=errors)
+        raise ValidationError(None, {None: '\n'.join(errors)})
 
-    def redirect(self):
+    def redirect(self, msg=None):
         req = self._cw
+        msg = msg or req._("transaction undone")
         breadcrumbs = req.session.data.get('breadcrumbs', None)
         if breadcrumbs is not None and len(breadcrumbs) > 1:
-            url = req.rebuild_url(breadcrumbs[-2],
-                                  __message=req._('transaction undoed'))
+            url = req.rebuild_url(breadcrumbs[-2], __message=msg)
         else:
-            url = req.build_url(__message=req._('transaction undoed'))
+            url = req.build_url(__message=msg)
         raise Redirect(url)
-