13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
14 # details. |
14 # details. |
15 # |
15 # |
16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
18 """functions for schema / permissions (de)serialization using RQL |
18 """functions for schema / permissions (de)serialization using RQL""" |
19 |
19 |
20 """ |
|
21 __docformat__ = "restructuredtext en" |
20 __docformat__ = "restructuredtext en" |
22 |
21 |
23 import os |
22 import os |
24 from itertools import chain |
23 from itertools import chain |
25 |
24 |
26 from logilab.common.shellutils import ProgressBar |
25 from logilab.common.shellutils import ProgressBar |
27 |
26 |
28 from yams import schema as schemamod, buildobjs as ybo |
27 from yams import schema as schemamod, buildobjs as ybo |
29 |
28 |
30 from cubicweb.schema import CONSTRAINTS, ETYPE_NAME_MAP, VIRTUAL_RTYPES |
29 from cubicweb import CW_SOFTWARE_ROOT, typed_eid |
|
30 from cubicweb.schema import (CONSTRAINTS, ETYPE_NAME_MAP, |
|
31 VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES) |
31 from cubicweb.server import sqlutils |
32 from cubicweb.server import sqlutils |
32 |
33 |
33 def group_mapping(cursor, interactive=True): |
34 def group_mapping(cursor, interactive=True): |
34 """create a group mapping from an rql cursor |
35 """create a group mapping from an rql cursor |
35 |
36 |
55 while True: |
56 while True: |
56 value = raw_input('eid for group %s: ' % group).strip() |
57 value = raw_input('eid for group %s: ' % group).strip() |
57 if not value: |
58 if not value: |
58 continue |
59 continue |
59 try: |
60 try: |
60 res[group] = int(value) |
61 eid = typed_eid(value) |
61 except ValueError: |
62 except ValueError: |
62 print 'eid should be an integer' |
63 print 'eid should be an integer' |
63 continue |
64 continue |
|
65 for eid_ in res.values(): |
|
66 if eid == eid_: |
|
67 break |
|
68 else: |
|
69 print 'eid is not a group eid' |
|
70 continue |
|
71 res[name] = eid |
|
72 break |
64 return res |
73 return res |
65 |
74 |
66 def cstrtype_mapping(cursor): |
75 def cstrtype_mapping(cursor): |
67 """cached constraint types mapping""" |
76 """cached constraint types mapping""" |
68 map = dict(cursor.execute('Any T, X WHERE X is CWConstraintType, X name T')) |
77 map = dict(cursor.execute('Any T, X WHERE X is CWConstraintType, X name T')) |
98 eschema = schema.eschema(etype) |
107 eschema = schema.eschema(etype) |
99 eschema.eid = eid |
108 eschema.eid = eid |
100 sidx[eid] = eschema |
109 sidx[eid] = eschema |
101 continue |
110 continue |
102 if etype in ETYPE_NAME_MAP: |
111 if etype in ETYPE_NAME_MAP: |
|
112 needcopy = False |
103 netype = ETYPE_NAME_MAP[etype] |
113 netype = ETYPE_NAME_MAP[etype] |
104 # can't use write rql queries at this point, use raw sql |
114 # can't use write rql queries at this point, use raw sql |
105 session.system_sql('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s' |
115 sqlexec = session.system_sql |
106 % {'p': sqlutils.SQL_PREFIX}, |
116 if sqlexec('SELECT 1 FROM %(p)sCWEType WHERE %(p)sname=%%(n)s' |
107 {'x': eid, 'n': netype}) |
117 % {'p': sqlutils.SQL_PREFIX}, {'n': netype}).fetchone(): |
108 session.system_sql('UPDATE entities SET type=%(n)s WHERE type=%(x)s', |
118 # the new type already exists, we should merge |
109 {'x': etype, 'n': netype}) |
119 assert etype.lower() != netype.lower() |
|
120 needcopy = True |
|
121 else: |
|
122 # the new type doesn't exist, we should rename |
|
123 sqlexec('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s' |
|
124 % {'p': sqlutils.SQL_PREFIX}, {'x': eid, 'n': netype}) |
|
125 if etype.lower() != netype.lower(): |
|
126 sqlexec('ALTER TABLE %s%s RENAME TO %s%s' % ( |
|
127 sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype)) |
|
128 sqlexec('UPDATE entities SET type=%(n)s WHERE type=%(x)s', |
|
129 {'x': etype, 'n': netype}) |
110 session.commit(False) |
130 session.commit(False) |
111 try: |
131 try: |
112 session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s', |
132 sqlexec('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s', |
113 {'x': etype, 'n': netype}) |
133 {'x': etype, 'n': netype}) |
114 except: |
134 except: |
115 pass |
135 pass |
116 tocleanup = [eid] |
136 tocleanup = [eid] |
117 tocleanup += (eid for eid, (eidetype, uri, extid) in repo._type_source_cache.items() |
137 tocleanup += (eid for eid, (eidetype, uri, extid) in repo._type_source_cache.items() |
118 if etype == eidetype) |
138 if etype == eidetype) |
119 repo.clear_caches(tocleanup) |
139 repo.clear_caches(tocleanup) |
120 session.commit(False) |
140 session.commit(False) |
|
141 if needcopy: |
|
142 from logilab.common.testlib import mock_object |
|
143 sidx[eid] = mock_object(type=netype) |
|
144 # copy / CWEType entity removal expected to be done through |
|
145 # rename_entity_type in a migration script |
|
146 continue |
121 etype = netype |
147 etype = netype |
122 etype = ybo.EntityType(name=etype, description=desc, eid=eid) |
148 etype = ybo.EntityType(name=etype, description=desc, eid=eid) |
123 eschema = schema.add_entity_type(etype) |
149 eschema = schema.add_entity_type(etype) |
124 sidx[eid] = eschema |
150 sidx[eid] = eschema |
125 set_perms(eschema, permsdict) |
151 set_perms(eschema, permsdict) |