47 cursor.execute(dbh.sql_drop_sequence('entities_id_seq')) |
47 cursor.execute(dbh.sql_drop_sequence('entities_id_seq')) |
48 cursor.execute(dbh.sql_create_numrange('entities_id_seq')) |
48 cursor.execute(dbh.sql_create_numrange('entities_id_seq')) |
49 cursor.execute(dbh.sql_restart_numrange('entities_id_seq', initial_value=lasteid)) |
49 cursor.execute(dbh.sql_restart_numrange('entities_id_seq', initial_value=lasteid)) |
50 session.commit() |
50 session.commit() |
51 |
51 |
|
52 if applcubicwebversion <= (3, 13, 0) and cubicwebversion >= (3, 13, 1): |
|
53 sql('ALTER TABLE entities ADD asource VARCHAR(64)') |
|
54 sql('UPDATE entities SET asource=cw_name ' |
|
55 'FROM cw_CWSource, cw_source_relation ' |
|
56 'WHERE entities.eid=cw_source_relation.eid_from AND cw_source_relation.eid_to=cw_CWSource.cw_eid') |
|
57 commit() |
|
58 |
|
59 if applcubicwebversion <= (3, 14, 4) and cubicwebversion >= (3, 14, 4): |
|
60 from cubicweb.server import schema2sql as y2sql |
|
61 dbhelper = repo.system_source.dbhelper |
|
62 rdefdef = schema['CWSource'].rdef('name') |
|
63 attrtype = y2sql.type_from_constraints(dbhelper, rdefdef.object, rdefdef.constraints).split()[0] |
|
64 cursor = session.cnxset.cu |
|
65 sql('UPDATE entities SET asource = source WHERE asource is NULL') |
|
66 dbhelper.change_col_type(cursor, 'entities', 'asource', attrtype, False) |
|
67 dbhelper.change_col_type(cursor, 'entities', 'source', attrtype, False) |
|
68 |
|
69 # we now have a functional asource column, start using the normal eid_type_source method |
|
70 if repo.system_source.eid_type_source == repo.system_source.eid_type_source_pre_131: |
|
71 del repo.system_source.eid_type_source |
|
72 |
52 if applcubicwebversion < (3, 19, 0) and cubicwebversion >= (3, 19, 0): |
73 if applcubicwebversion < (3, 19, 0) and cubicwebversion >= (3, 19, 0): |
53 try: |
74 try: |
54 # need explicit drop of the indexes on some database systems (sqlserver) |
75 # need explicit drop of the indexes on some database systems (sqlserver) |
55 sql(repo.system_source.dbhelper.sql_drop_index('entities', 'mtime')) |
76 sql(repo.system_source.dbhelper.sql_drop_index('entities', 'mtime')) |
56 sql('ALTER TABLE "entities" DROP COLUMN "mtime"') |
77 sql('ALTER TABLE "entities" DROP COLUMN "mtime"') |
67 ss._IGNORED_PROPS.append('formula') |
88 ss._IGNORED_PROPS.append('formula') |
68 add_attribute('CWAttribute', 'formula', commit=False) |
89 add_attribute('CWAttribute', 'formula', commit=False) |
69 ss._IGNORED_PROPS.remove('formula') |
90 ss._IGNORED_PROPS.remove('formula') |
70 commit() |
91 commit() |
71 add_entity_type('CWComputedRType') |
92 add_entity_type('CWComputedRType') |
|
93 commit() |
|
94 |
|
95 if schema['TZDatetime'].eid is None: |
|
96 add_entity_type('TZDatetime', auto=False) |
|
97 if schema['TZTime'].eid is None: |
|
98 add_entity_type('TZTime', auto=False) |
|
99 |
|
100 if applcubicwebversion < (3, 18, 0) and cubicwebversion >= (3, 18, 0): |
|
101 driver = config.system_source_config['db-driver'] |
|
102 if not (driver == 'postgres' or driver.startswith('sqlserver')): |
|
103 import sys |
|
104 print >>sys.stderr, 'This migration is not supported for backends other than sqlserver or postgres (yet).' |
|
105 sys.exit(1) |
|
106 |
|
107 add_relation_definition('CWAttribute', 'add_permission', 'CWGroup') |
|
108 add_relation_definition('CWAttribute', 'add_permission', 'RQLExpression') |
|
109 |
|
110 # a bad defaultval in 3.13.8 schema was fixed in 3.13.9, but the migration was missed |
|
111 rql('SET ATTR defaultval NULL WHERE ATTR from_entity E, E name "CWSource", ATTR relation_type T, T name "in_synchronization"') |
|
112 |
|
113 # the migration gets confused when we change rdefs out from under it. So |
|
114 # explicitly remove this size constraint so it doesn't stick around and break |
|
115 # things later. |
|
116 rdefeid = schema['defaultval'].rdefs.values()[0].eid |
|
117 rql('DELETE CWConstraint C WHERE C cstrtype T, T name "SizeConstraint", R constrained_by C, R eid %(eid)s', {'eid': rdefeid}) |
|
118 |
|
119 sync_schema_props_perms('defaultval') |
|
120 |
|
121 def convert_defaultval(cwattr, default): |
|
122 from decimal import Decimal |
|
123 import yams |
|
124 from cubicweb import Binary |
|
125 if default is None: |
|
126 return |
|
127 if isinstance(default, Binary): |
|
128 # partially migrated instance, try to be idempotent |
|
129 return default |
|
130 atype = cwattr.to_entity[0].name |
|
131 if atype == 'Boolean': |
|
132 # boolean attributes with default=False were stored as '' |
|
133 assert default in ('True', 'False', ''), repr(default) |
|
134 default = default == 'True' |
|
135 elif atype in ('Int', 'BigInt'): |
|
136 default = int(default) |
|
137 elif atype == 'Float': |
|
138 default = float(default) |
|
139 elif atype == 'Decimal': |
|
140 default = Decimal(default) |
|
141 elif atype in ('Date', 'Datetime', 'TZDatetime', 'Time'): |
|
142 try: |
|
143 # handle NOW and TODAY, keep them stored as strings |
|
144 yams.KEYWORD_MAP[atype][default.upper()] |
|
145 default = default.upper() |
|
146 except KeyError: |
|
147 # otherwise get an actual date or datetime |
|
148 default = yams.DATE_FACTORY_MAP[atype](default) |
|
149 else: |
|
150 assert atype == 'String', atype |
|
151 default = unicode(default) |
|
152 return Binary.zpickle(default) |
|
153 |
|
154 dbh = repo.system_source.dbhelper |
|
155 |
|
156 |
|
157 sql('ALTER TABLE cw_cwattribute ADD new_defaultval %s' % dbh.TYPE_MAPPING['Bytes']) |
|
158 |
|
159 for cwattr in rql('CWAttribute X').entities(): |
|
160 olddefault = cwattr.defaultval |
|
161 if olddefault is not None: |
|
162 req = "UPDATE cw_cwattribute SET new_defaultval = %(val)s WHERE cw_eid = %(eid)s" |
|
163 args = {'val': dbh.binary_value(convert_defaultval(cwattr, olddefault).getvalue()), 'eid': cwattr.eid} |
|
164 sql(req, args, ask_confirm=False) |
|
165 |
|
166 sql('ALTER TABLE cw_cwattribute DROP COLUMN cw_defaultval') |
|
167 if driver == 'postgres': |
|
168 sql('ALTER TABLE cw_cwattribute RENAME COLUMN new_defaultval TO cw_defaultval') |
|
169 else: # sqlserver |
|
170 sql("sp_rename 'cw_cwattribute.new_defaultval', 'cw_defaultval', 'COLUMN'") |
|
171 |
|
172 |
|
173 # Set object type to "Bytes" for CWAttribute's "defaultval" attribute |
|
174 rql('SET X to_entity B WHERE X is CWAttribute, X from_entity Y, Y name "CWAttribute", ' |
|
175 'X relation_type Z, Z name "defaultval", B name "Bytes", NOT X to_entity B') |
|
176 |
|
177 oldrdef = schema['CWAttribute'].rdef('defaultval') |
|
178 import yams.buildobjs as ybo |
|
179 newrdef = ybo.RelationDefinition('CWAttribute', 'defaultval', 'Bytes') |
|
180 newrdef.eid = oldrdef.eid |
|
181 schema.add_relation_def(newrdef) |
|
182 schema.del_relation_def('CWAttribute', 'defaultval', 'String') |
|
183 |
|
184 commit() |
|
185 |
|
186 sync_schema_props_perms('defaultval') |
|
187 |
|
188 for rschema in schema.relations(): |
|
189 if rschema.symmetric: |
|
190 subjects = set(repr(e.type) for e in rschema.subjects()) |
|
191 objects = set(repr(e.type) for e in rschema.objects()) |
|
192 assert subjects == objects |
|
193 martians = set(str(eid) for eid, in sql('SELECT eid_to FROM %s_relation, entities WHERE eid_to = eid AND type NOT IN (%s)' % |
|
194 (rschema.type, ','.join(subjects)))) |
|
195 martians |= set(str(eid) for eid, in sql('SELECT eid_from FROM %s_relation, entities WHERE eid_from = eid AND type NOT IN (%s)' % |
|
196 (rschema.type, ','.join(subjects)))) |
|
197 if martians: |
|
198 martians = ','.join(martians) |
|
199 print 'deleting broken relations %s for eids %s' % (rschema.type, martians) |
|
200 sql('DELETE FROM %s_relation WHERE eid_from IN (%s) OR eid_to IN (%s)' % (rschema.type, martians, martians)) |
|
201 with session.deny_all_hooks_but(): |
|
202 rql('SET X %(r)s Y WHERE Y %(r)s X, NOT X %(r)s Y' % {'r': rschema.type}) |
|
203 commit() |
|
204 |
|
205 |
|
206 # multi columns unique constraints regeneration |
|
207 from cubicweb.server import schemaserial |
|
208 |
|
209 # syncschema hooks would try to remove indices but |
|
210 # 1) we already do that below |
|
211 # 2) the hook expects the CWUniqueTogetherConstraint.name attribute that hasn't |
|
212 # yet been added |
|
213 with session.allow_all_hooks_but('syncschema'): |
|
214 rql('DELETE CWUniqueTogetherConstraint C') |
|
215 commit() |
|
216 add_attribute('CWUniqueTogetherConstraint', 'name') |
|
217 |
|
218 # low-level wipe code for postgres & sqlserver, plain sql ... |
|
219 if driver == 'postgres': |
|
220 for indexname, in sql('select indexname from pg_indexes'): |
|
221 if indexname.startswith('unique_'): |
|
222 print 'dropping index', indexname |
|
223 sql('DROP INDEX %s' % indexname) |
|
224 commit() |
|
225 elif driver.startswith('sqlserver'): |
|
226 for viewname, in sql('select name from sys.views'): |
|
227 if viewname.startswith('utv_'): |
|
228 print 'dropping view (index should be cascade-deleted)', viewname |
|
229 sql('DROP VIEW %s' % viewname) |
|
230 commit() |
|
231 |
|
232 # recreate the constraints, hook will lead to low-level recreation |
|
233 for eschema in sorted(schema.entities()): |
|
234 if eschema._unique_together: |
|
235 print 'recreate unique indexes for', eschema |
|
236 rql_args = schemaserial.uniquetogether2rqls(eschema) |
|
237 for rql, args in rql_args: |
|
238 args['x'] = eschema.eid |
|
239 session.execute(rql, args) |
|
240 commit() |
|
241 |
|
242 # all attributes perms have to be refreshed ... |
|
243 for rschema in sorted(schema.relations()): |
|
244 if rschema.final: |
|
245 if rschema.type in fsschema: |
|
246 print 'sync perms for', rschema.type |
|
247 sync_schema_props_perms(rschema.type, syncprops=False, ask_confirm=False, commit=False) |
|
248 else: |
|
249 print 'WARNING: attribute %s missing from fs schema' % rschema.type |
72 commit() |
250 commit() |
73 |
251 |
74 if applcubicwebversion < (3, 17, 0) and cubicwebversion >= (3, 17, 0): |
252 if applcubicwebversion < (3, 17, 0) and cubicwebversion >= (3, 17, 0): |
75 try: |
253 try: |
76 add_cube('sioc', update_database=False) |
254 add_cube('sioc', update_database=False) |
89 except ConfigurationError: |
267 except ConfigurationError: |
90 if not confirm('In cubicweb 3.17 geocoding views have been moved to the geocoding ' |
268 if not confirm('In cubicweb 3.17 geocoding views have been moved to the geocoding ' |
91 'cube, which is not installed. Continue anyway?'): |
269 'cube, which is not installed. Continue anyway?'): |
92 raise |
270 raise |
93 |
271 |
94 if applcubicwebversion <= (3, 13, 0) and cubicwebversion >= (3, 13, 1): |
|
95 sql('ALTER TABLE entities ADD asource VARCHAR(64)') |
|
96 sql('UPDATE entities SET asource=cw_name ' |
|
97 'FROM cw_CWSource, cw_source_relation ' |
|
98 'WHERE entities.eid=cw_source_relation.eid_from AND cw_source_relation.eid_to=cw_CWSource.cw_eid') |
|
99 commit() |
|
100 |
|
101 if schema['TZDatetime'].eid is None: |
|
102 add_entity_type('TZDatetime', auto=False) |
|
103 if schema['TZTime'].eid is None: |
|
104 add_entity_type('TZTime', auto=False) |
|
105 |
|
106 |
272 |
107 if applcubicwebversion <= (3, 14, 0) and cubicwebversion >= (3, 14, 0): |
273 if applcubicwebversion <= (3, 14, 0) and cubicwebversion >= (3, 14, 0): |
108 if 'require_permission' in schema and not 'localperms'in repo.config.cubes(): |
274 if 'require_permission' in schema and not 'localperms'in repo.config.cubes(): |
109 from cubicweb import ExecutionError |
275 from cubicweb import ExecutionError |
110 try: |
276 try: |
111 add_cube('localperms', update_database=False) |
277 add_cube('localperms', update_database=False) |
112 except ConfigurationError: |
278 except ConfigurationError: |
113 raise ExecutionError('In cubicweb 3.14, CWPermission and related stuff ' |
279 raise ExecutionError('In cubicweb 3.14, CWPermission and related stuff ' |
114 'has been moved to cube localperms. Install it first.') |
280 'has been moved to cube localperms. Install it first.') |
115 |
281 |
|
282 |
116 if applcubicwebversion == (3, 6, 0) and cubicwebversion >= (3, 6, 0): |
283 if applcubicwebversion == (3, 6, 0) and cubicwebversion >= (3, 6, 0): |
117 CSTRMAP = dict(rql('Any T, X WHERE X is CWConstraintType, X name T', |
284 CSTRMAP = dict(rql('Any T, X WHERE X is CWConstraintType, X name T', |
118 ask_confirm=False)) |
285 ask_confirm=False)) |
119 _add_relation_definition_no_perms('CWAttribute', 'update_permission', 'CWGroup') |
286 _add_relation_definition_no_perms('CWAttribute', 'update_permission', 'CWGroup') |
120 _add_relation_definition_no_perms('CWAttribute', 'update_permission', 'RQLExpression') |
287 _add_relation_definition_no_perms('CWAttribute', 'update_permission', 'RQLExpression') |
121 rql('SET X update_permission Y WHERE X is CWAttribute, X add_permission Y') |
288 rql('SET X update_permission Y WHERE X is CWAttribute, X add_permission Y') |
122 drop_relation_definition('CWAttribute', 'add_permission', 'CWGroup') |
|
123 drop_relation_definition('CWAttribute', 'add_permission', 'RQLExpression') |
|
124 drop_relation_definition('CWAttribute', 'delete_permission', 'CWGroup') |
289 drop_relation_definition('CWAttribute', 'delete_permission', 'CWGroup') |
125 drop_relation_definition('CWAttribute', 'delete_permission', 'RQLExpression') |
290 drop_relation_definition('CWAttribute', 'delete_permission', 'RQLExpression') |
126 |
291 |
127 elif applcubicwebversion < (3, 6, 0) and cubicwebversion >= (3, 6, 0): |
292 elif applcubicwebversion < (3, 6, 0) and cubicwebversion >= (3, 6, 0): |
128 CSTRMAP = dict(rql('Any T, X WHERE X is CWConstraintType, X name T', |
293 CSTRMAP = dict(rql('Any T, X WHERE X is CWConstraintType, X name T', |