[migration] always rebuild infered relation

This was skipped for some bad reason (see 12ad88615a12 which introduced the change).

Fix for #231956 in Yams is necessary to allow this cset: during a migration, we want to always reinfer relations while allowing explicit redefinition of an infered relation later. Else, we may run the migration with missing parts of the schema (the one that should have been infered).

Closes #3685463.

authorSylvain Thénault <sylvain.thenault@logilab.fr>
changesetfe267b7336f3
branchstable
phasepublic
hiddenno
parent revision#0f0199948f93 Backout "[web/navigation] use add_onload instead of inline javascript href"
child revision#7e4897901c64 [migration] Improve update of in-memory schema during 3.18 CWAttribute.defaultval change
files modified by this revision
__pkginfo__.py
cubicweb.spec
debian/control
hooks/syncschema.py
server/migractions.py
server/test/unittest_migractions.py
# HG changeset patch
# User Sylvain Thénault <sylvain.thenault@logilab.fr>
# Date 1395927141 -3600
# Thu Mar 27 14:32:21 2014 +0100
# Branch stable
# Node ID fe267b7336f308161a812505ce34efad1588d2a7
# Parent 0f0199948f938663c6a0132f116e49cff6a9e22a
[migration] always rebuild infered relation

This was skipped for some bad reason (see 12ad88615a12 which
introduced the change).

Fix for #231956 in Yams is necessary to allow this cset: during a
migration, we want to always reinfer relations while allowing explicit
redefinition of an infered relation later. Else, we may run the
migration with missing parts of the schema (the one that should have
been infered).

Closes #3685463.

diff --git a/__pkginfo__.py b/__pkginfo__.py
@@ -40,11 +40,11 @@
1 
2  __depends__ = {
3      'logilab-common': '>= 0.60.0',
4      'logilab-mtconverter': '>= 0.8.0',
5      'rql': '>= 0.31.2',
6 -    'yams': '>= 0.39.0',
7 +    'yams': '>= 0.39.1',
8      #gettext                    # for xgettext, msgcat, etc...
9      # web dependancies
10      'simplejson': '>= 2.0.9',
11      'lxml': '',
12      'Twisted': '',
diff --git a/cubicweb.spec b/cubicweb.spec
@@ -21,11 +21,11 @@
13 
14  Requires:       %{python}
15  Requires:       %{python}-logilab-common >= 0.60.0
16  Requires:       %{python}-logilab-mtconverter >= 0.8.0
17  Requires:       %{python}-rql >= 0.31.2
18 -Requires:       %{python}-yams >= 0.39.0
19 +Requires:       %{python}-yams >= 0.39.1
20  Requires:       %{python}-logilab-database >= 1.11.0
21  Requires:       %{python}-passlib
22  Requires:       %{python}-lxml
23  Requires:       %{python}-twisted-web
24  # the schema view uses `dot'; at least on el5, png output requires graphviz-gd
diff --git a/debian/control b/debian/control
@@ -13,11 +13,11 @@
25   python-sphinx,
26   python-logilab-common,
27   python-unittest2 | python (>= 2.7),
28   python-logilab-mtconverter,
29   python-rql,
30 - python-yams (>= 0.39),
31 + python-yams (>= 0.39.1),
32   python-lxml,
33  Standards-Version: 3.9.1
34  Homepage: http://www.cubicweb.org
35  XS-Python-Version: >= 2.6
36 
@@ -151,11 +151,11 @@
37   ${python:Depends},
38   graphviz,
39   gettext,
40   python-logilab-mtconverter (>= 0.8.0),
41   python-logilab-common (>= 0.60.0),
42 - python-yams (>= 0.39.0),
43 + python-yams (>= 0.39.1),
44   python-rql (>= 0.31.2),
45   python-lxml
46  Recommends:
47   python-simpletal (>= 4.0),
48   python-crypto
diff --git a/hooks/syncschema.py b/hooks/syncschema.py
@@ -1,6 +1,6 @@
49 -# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
50 +# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
51  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
52  #
53  # This file is part of CubicWeb.
54  #
55  # CubicWeb is free software: you can redistribute it and/or modify it under the
@@ -194,17 +194,15 @@
56          for eschema in self.session.repo.schema.entities():
57              if not eschema.final:
58                  clear_cache(eschema, 'ordered_relations')
59 
60      def postcommit_event(self):
61 -        rebuildinfered = self.session.data.get('rebuild-infered', True)
62          repo = self.session.repo
63          # commit event should not raise error, while set_schema has chances to
64          # do so because it triggers full vreg reloading
65          try:
66 -            if rebuildinfered:
67 -                repo.schema.rebuild_infered_relations()
68 +            repo.schema.rebuild_infered_relations()
69              # trigger vreg reload
70              repo.set_schema(repo.schema)
71              # CWUser class might have changed, update current session users
72              cwuser_cls = self.session.vreg['etypes'].etype_class('CWUser')
73              for session in repo._sessions.itervalues():
diff --git a/server/migractions.py b/server/migractions.py
@@ -1,6 +1,6 @@
74 -# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
75 +# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
76  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
77  #
78  # This file is part of CubicWeb.
79  #
80  # CubicWeb is free software: you can redistribute it and/or modify it under the
@@ -100,11 +100,10 @@
81          elif connect:
82              self.repo_connect()
83          # no config on shell to a remote instance
84          if config is not None and (cnx or connect):
85              repo = self.repo
86 -            self.session.data['rebuild-infered'] = False
87              # register a hook to clear our group_mapping cache and the
88              # self._synchronized set when some group is added or updated
89              ClearGroupMap.mih = self
90              ClearGroupMap.mih_register(repo)
91              CW_EVENT_MANAGER.bind('after-registry-reload',
@@ -290,11 +289,10 @@
92                      login, pwd = manager_userpasswd()
93                  except (KeyboardInterrupt, EOFError):
94                      print 'aborting...'
95                      sys.exit(0)
96              self.session.keep_cnxset_mode('transaction')
97 -            self.session.data['rebuild-infered'] = False
98              return self._cnx
99 
100      @property
101      def session(self):
102          if self.config is not None:
diff --git a/server/test/unittest_migractions.py b/server/test/unittest_migractions.py
@@ -1,6 +1,6 @@
103 -# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
104 +# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
105  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
106  #
107  # This file is part of CubicWeb.
108  #
109  # CubicWeb is free software: you can redistribute it and/or modify it under the
@@ -223,11 +223,10 @@
110          self.assertTrue('Folder2' in self.schema)
111          self.assertTrue('Old' in self.schema)
112          self.assertTrue(self.session.execute('CWEType X WHERE X name "Folder2"'))
113          self.assertTrue('filed_under2' in self.schema)
114          self.assertTrue(self.session.execute('CWRType X WHERE X name "filed_under2"'))
115 -        self.schema.rebuild_infered_relations()
116          self.assertEqual(sorted(str(rs) for rs in self.schema['Folder2'].subject_relations()),
117                            ['created_by', 'creation_date', 'cw_source', 'cwuri',
118                             'description', 'description_format',
119                             'eid',
120                             'filed_under2', 'has_text',
@@ -269,11 +268,10 @@
121          self.mh.cmd_rename_attribute('New', 'name', 'new_name')
122 
123      def test_add_drop_relation_type(self):
124          self.mh.cmd_add_entity_type('Folder2', auto=False)
125          self.mh.cmd_add_relation_type('filed_under2')
126 -        self.schema.rebuild_infered_relations()
127          self.assertTrue('filed_under2' in self.schema)
128          # Old will be missing as it has been renamed into 'New' in the migrated
129          # schema while New hasn't been added here.
130          self.assertEqual(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
131                           sorted(str(e) for e in self.schema.entities()
@@ -326,21 +324,15 @@
132                            ['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
133          self.mh.cmd_drop_relation_definition('Affaire', 'concerne', 'Societe')
134          self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
135                            ['Affaire', 'Personne'])
136          self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
137 -                          ['Affaire', 'Division', 'Note', 'SubDivision'])
138 -        self.schema.rebuild_infered_relations() # need to be explicitly called once everything is in place
139 -        self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
140                            ['Affaire', 'Note'])
141          self.mh.cmd_add_relation_definition('Affaire', 'concerne', 'Societe')
142          self.assertEqual(sorted(str(e) for e in self.schema['concerne'].subjects()),
143                            ['Affaire', 'Personne'])
144          self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
145 -                          ['Affaire', 'Note', 'Societe'])
146 -        self.schema.rebuild_infered_relations() # need to be explicitly called once everything is in place
147 -        self.assertEqual(sorted(str(e) for e in self.schema['concerne'].objects()),
148                            ['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
149          # trick: overwrite self.maxeid to avoid deletion of just reintroduced types
150          self.maxeid = self.session.execute('Any MAX(X)')[0][0]
151 
152      def test_rename_relation(self):
@@ -597,16 +589,14 @@
153          self.assertEqual(str(cm.exception), "can't remove cube file, used as a dependency")
154 
155      @tag('longrun')
156      def test_introduce_base_class(self):
157          self.mh.cmd_add_entity_type('Para')
158 -        self.mh.repo.schema.rebuild_infered_relations()
159          self.assertEqual(sorted(et.type for et in self.schema['Para'].specialized_by()),
160                            ['Note'])
161          self.assertEqual(self.schema['Note'].specializes().type, 'Para')
162          self.mh.cmd_add_entity_type('Text')
163 -        self.mh.repo.schema.rebuild_infered_relations()
164          self.assertEqual(sorted(et.type for et in self.schema['Para'].specialized_by()),
165                            ['Note', 'Text'])
166          self.assertEqual(self.schema['Text'].specializes().type, 'Para')
167          # test columns have been actually added
168          text = self.session.execute('INSERT Text X: X para "hip", X summary "hop", X newattr "momo"').get_entity(0, 0)
@@ -626,16 +616,12 @@
169          # after_delete_entity(CWEType) hook, since in that case the MemSchemaSpecializesDel
170          # operation would be removed before, but I'm not sure this is a desired behaviour.
171          #
172          # also we need more tests about introducing/removing base classes or
173          # specialization relationship...
174 -        self.session.data['rebuild-infered'] = True
175 -        try:
176 -            self.session.execute('DELETE X specializes Y WHERE Y name "Para"')
177 -            self.session.commit(free_cnxset=False)
178 -        finally:
179 -            self.session.data['rebuild-infered'] = False
180 +        self.session.execute('DELETE X specializes Y WHERE Y name "Para"')
181 +        self.session.commit(free_cnxset=False)
182          self.assertEqual(sorted(et.type for et in self.schema['Para'].specialized_by()),
183                            [])
184          self.assertEqual(self.schema['Note'].specializes(), None)
185          self.assertEqual(self.schema['Text'].specializes(), None)
186