29 assert atype == 'String', atype |
35 assert atype == 'String', atype |
30 default = unicode(default) |
36 default = unicode(default) |
31 return Binary.zpickle(default) |
37 return Binary.zpickle(default) |
32 |
38 |
33 dbh = repo.system_source.dbhelper |
39 dbh = repo.system_source.dbhelper |
34 driver = config.sources()['system']['db-driver'] |
|
35 |
40 |
36 if driver == 'postgres' or driver.startswith('sqlserver'): |
|
37 |
41 |
38 sql('ALTER TABLE cw_cwattribute ADD new_defaultval %s' % dbh.TYPE_MAPPING['Bytes']) |
42 sql('ALTER TABLE cw_cwattribute ADD new_defaultval %s' % dbh.TYPE_MAPPING['Bytes']) |
39 |
43 |
40 for cwattr in rql('CWAttribute X').entities(): |
44 for cwattr in rql('CWAttribute X').entities(): |
41 olddefault = cwattr.defaultval |
45 olddefault = cwattr.defaultval |
42 if olddefault is not None: |
46 if olddefault is not None: |
43 req = "UPDATE cw_cwattribute SET new_defaultval = %(val)s WHERE cw_eid = %(eid)s" |
47 req = "UPDATE cw_cwattribute SET new_defaultval = %(val)s WHERE cw_eid = %(eid)s" |
44 args = {'val': dbh.binary_value(convert_defaultval(cwattr, olddefault).getvalue()), 'eid': cwattr.eid} |
48 args = {'val': dbh.binary_value(convert_defaultval(cwattr, olddefault).getvalue()), 'eid': cwattr.eid} |
45 sql(req, args, ask_confirm=False) |
|
46 |
|
47 sql('ALTER TABLE cw_cwattribute DROP COLUMN cw_defaultval') |
|
48 if config.sources()['system']['db-driver'] == 'postgres': |
|
49 sql('ALTER TABLE cw_cwattribute RENAME COLUMN new_defaultval TO cw_defaultval') |
|
50 else: |
|
51 sql("sp_rename 'cw_cwattribute.new_defaultval', 'cw_defaultval', 'COLUMN'") |
|
52 |
|
53 elif driver == 'sqlite': |
|
54 |
|
55 import re |
|
56 create = sql("SELECT sql FROM sqlite_master WHERE name = 'cw_CWAttribute'")[0][0] |
|
57 create = re.sub('cw_defaultval varchar[^,]*,', 'cw_defaultval bytea,', create, re.I) |
|
58 create = re.sub('cw_CWAttribute', 'tmp_cw_CWAttribute', create, re.I) |
|
59 sql(create) |
|
60 sql("INSERT INTO tmp_cw_CWAttribute SELECT * FROM cw_CWAttribute") |
|
61 for cwattr in rql('CWAttribute X').entities(): |
|
62 olddefault = cwattr.defaultval |
|
63 if olddefault is None: |
|
64 continue |
|
65 req = "UPDATE tmp_cw_CWAttribute SET cw_defaultval = %(val)s WHERE cw_eid = %(eid)s" |
|
66 args = {'val': dbh.binary_value(convert_defaultval(cwattr, olddefault).getvalue()), |
|
67 'eid': cwattr.eid} |
|
68 sql(req, args, ask_confirm=False) |
49 sql(req, args, ask_confirm=False) |
69 |
50 |
70 sql('DROP TABLE cw_CWAttribute') |
51 sql('ALTER TABLE cw_cwattribute DROP COLUMN cw_defaultval') |
71 sql('ALTER TABLE tmp_cw_CWAttribute RENAME TO cw_CWAttribute') |
52 if driver == 'postgres': |
|
53 sql('ALTER TABLE cw_cwattribute RENAME COLUMN new_defaultval TO cw_defaultval') |
|
54 else: # sqlserver |
|
55 sql("sp_rename 'cw_cwattribute.new_defaultval', 'cw_defaultval', 'COLUMN'") |
72 |
56 |
73 else: |
|
74 assert False, 'upgrade not supported on this database backend' |
|
75 |
57 |
76 # Set object type to "Bytes" for CWAttribute's "defaultval" attribute |
58 # Set object type to "Bytes" for CWAttribute's "defaultval" attribute |
77 rql('SET X to_entity B WHERE X is CWAttribute, X from_entity Y, Y name "CWAttribute", ' |
59 rql('SET X to_entity B WHERE X is CWAttribute, X from_entity Y, Y name "CWAttribute", ' |
78 'X relation_type Z, Z name "defaultval", B name "Bytes"') |
60 'X relation_type Z, Z name "defaultval", B name "Bytes"') |
79 |
61 |
80 from yams import buildobjs as ybo |
62 from yams import buildobjs as ybo |
81 schema.add_relation_def(ybo.RelationDefinition('CWAttribute', 'defaultval', 'Bytes')) |
63 schema.add_relation_def(ybo.RelationDefinition('CWAttribute', 'defaultval', 'Bytes')) |
82 schema.del_relation_def('CWAttribute', 'defaultval', 'String') |
64 schema.del_relation_def('CWAttribute', 'defaultval', 'String') |
83 |
65 |
84 commit() |
66 commit() |
85 |
|
86 |
67 |
87 for rschema in schema.relations(): |
68 for rschema in schema.relations(): |
88 if rschema.symmetric: |
69 if rschema.symmetric: |
89 subjects = set(repr(e.type) for e in rschema.subjects()) |
70 subjects = set(repr(e.type) for e in rschema.subjects()) |
90 objects = set(repr(e.type) for e in rschema.objects()) |
71 objects = set(repr(e.type) for e in rschema.objects()) |
98 print 'deleting broken relations %s for eids %s' % (rschema.type, martians) |
79 print 'deleting broken relations %s for eids %s' % (rschema.type, martians) |
99 sql('DELETE FROM %s_relation WHERE eid_from IN (%s) OR eid_to IN (%s)' % (rschema.type, martians, martians)) |
80 sql('DELETE FROM %s_relation WHERE eid_from IN (%s) OR eid_to IN (%s)' % (rschema.type, martians, martians)) |
100 with session.deny_all_hooks_but(): |
81 with session.deny_all_hooks_but(): |
101 rql('SET X %(r)s Y WHERE Y %(r)s X, NOT X %(r)s Y' % {'r': rschema.type}) |
82 rql('SET X %(r)s Y WHERE Y %(r)s X, NOT X %(r)s Y' % {'r': rschema.type}) |
102 commit() |
83 commit() |
|
84 |
|
85 |
|
86 # multi columns unique constraints regeneration |
|
87 from cubicweb.server import schemaserial |
|
88 |
|
89 # syncschema hooks would try to remove indices but |
|
90 # 1) we already do that below |
|
91 # 2) the hook expects the CWUniqueTogetherConstraint.name attribute that hasn't |
|
92 # yet been added |
|
93 with session.allow_all_hooks_but('syncschema'): |
|
94 rql('DELETE CWUniqueTogetherConstraint C') |
|
95 commit() |
|
96 |
|
97 add_attribute('CWUniqueTogetherConstraint', 'name') |
|
98 |
|
99 # low-level wipe code for postgres & sqlserver, plain sql ... |
|
100 if driver == 'postgres': |
|
101 for indexname, in sql('select indexname from pg_indexes'): |
|
102 if indexname.startswith('unique_'): |
|
103 print 'dropping index', indexname |
|
104 sql('DROP INDEX %s' % indexname) |
|
105 commit() |
|
106 elif driver.startswith('sqlserver'): |
|
107 for viewname, in sql('select name from sys.views'): |
|
108 if viewname.startswith('utv_'): |
|
109 print 'dropping view (index should be cascade-deleted)', viewname |
|
110 sql('DROP VIEW %s' % viewname) |
|
111 commit() |
|
112 |
|
113 # recreate the constraints, hook will lead to low-level recreation |
|
114 for eschema in sorted(schema.entities()): |
|
115 if eschema._unique_together: |
|
116 rql_args = schemaserial.uniquetogether2rqls(eschema) |
|
117 for rql, args in rql_args: |
|
118 args['x'] = eschema.eid |
|
119 session.execute(rql, args) |
|
120 commit() |