author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
Tue, 26 Jan 2010 13:38:02 +0100 | |
changeset 4367 | fa02f7dccfe4 |
parent 4312 | 740397c24ec3 |
child 4467 | 0e73d299730a |
permissions | -rw-r--r-- |
0 | 1 |
"""functions for schema / permissions (de)serialization using RQL |
2 |
||
3 |
:organization: Logilab |
|
4212
ab6573088b4a
update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3897
diff
changeset
|
4 |
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2. |
0 | 5 |
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
1977
606923dff11b
big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
1913
diff
changeset
|
6 |
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
0 | 7 |
""" |
8 |
__docformat__ = "restructuredtext en" |
|
9 |
||
3854
8633cd05b6b5
no progress bar in apycot environment
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
10 |
import os |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
11 |
import sys |
3723
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
12 |
import os |
0 | 13 |
from itertools import chain |
14 |
||
15 |
from logilab.common.shellutils import ProgressBar |
|
16 |
||
17 |
from yams import schema as schemamod, buildobjs as ybo |
|
18 |
||
2596
d02eed70937f
[R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2458
diff
changeset
|
19 |
from cubicweb.schema import CONSTRAINTS, ETYPE_NAME_MAP, VIRTUAL_RTYPES |
1869
642a1a120a92
should use sql prefix here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1630
diff
changeset
|
20 |
from cubicweb.server import sqlutils |
0 | 21 |
|
22 |
def group_mapping(cursor, interactive=True): |
|
23 |
"""create a group mapping from an rql cursor |
|
24 |
||
25 |
A group mapping has standard group names as key (managers, owners at least) |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
26 |
and the actual CWGroup entity's eid as associated value. |
0 | 27 |
In interactive mode (the default), missing groups'eid will be prompted |
28 |
from the user. |
|
29 |
""" |
|
30 |
res = {} |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
31 |
for eid, name in cursor.execute('Any G, N WHERE G is CWGroup, G name N', |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
32 |
build_descr=False): |
0 | 33 |
res[name] = eid |
34 |
if not interactive: |
|
35 |
return res |
|
36 |
missing = [g for g in ('owners', 'managers', 'users', 'guests') if not g in res] |
|
37 |
if missing: |
|
38 |
print 'some native groups are missing but the following groups have been found:' |
|
39 |
print '\n'.join('* %s (%s)' % (n, eid) for n, eid in res.items()) |
|
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
40 |
print |
0 | 41 |
print 'enter the eid of a to group to map to each missing native group' |
42 |
print 'or just type enter to skip permissions granted to a group' |
|
43 |
for group in missing: |
|
44 |
while True: |
|
45 |
value = raw_input('eid for group %s: ' % group).strip() |
|
46 |
if not value: |
|
47 |
continue |
|
48 |
try: |
|
49 |
res[group] = int(value) |
|
50 |
except ValueError: |
|
51 |
print 'eid should be an integer' |
|
52 |
continue |
|
53 |
return res |
|
54 |
||
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
55 |
def _set_sql_prefix(prefix): |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
56 |
"""3.2.0 migration function: allow to unset/reset SQL_PREFIX""" |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
57 |
for module in ('checkintegrity', 'migractions', 'schemahooks', |
1913
7d7bfd30c7f5
should reset sqlutils.SQL_PREFIX as well
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1869
diff
changeset
|
58 |
'sources.rql2sql', 'sources.native', 'sqlutils'): |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
59 |
try: |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
60 |
sys.modules['cubicweb.server.%s' % module].SQL_PREFIX = prefix |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
61 |
print 'changed SQL_PREFIX for %s' % module |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
62 |
except KeyError: |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
63 |
pass |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
64 |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
65 |
def _update_database(schema, sqlcu): |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
66 |
"""3.2.0 migration function: update database schema by adding SQL_PREFIX to |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
67 |
entity type tables and columns |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
68 |
""" |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
69 |
for etype in schema.entities(): |
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2955
diff
changeset
|
70 |
if etype.final: |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
71 |
continue |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
72 |
try: |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
73 |
sql = 'ALTER TABLE %s RENAME TO cw_%s' % ( |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
74 |
etype, ETYPE_NAME_MAP.get(etype, etype)) |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
75 |
print sql |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
76 |
sqlcu.execute(sql) |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
77 |
except: |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
78 |
pass |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
79 |
for rschema in etype.subject_relations(): |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
80 |
if rschema == 'has_text': |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
81 |
continue |
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2955
diff
changeset
|
82 |
if rschema.final or rschema.inlined: |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
83 |
sql = 'ALTER TABLE cw_%s RENAME %s TO cw_%s' % ( |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
84 |
etype, rschema, rschema) |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
85 |
print sql |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
86 |
sqlcu.execute(sql) |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
87 |
|
0 | 88 |
# schema / perms deserialization ############################################## |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
89 |
OLD_SCHEMA_TYPES = frozenset(('EFRDef', 'ENFRDef', 'ERType', 'EEType', |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
90 |
'EConstraintType', 'EConstraint', 'EGroup', |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
91 |
'EUser', 'ECache', 'EPermission', 'EProperty')) |
0 | 92 |
|
93 |
def deserialize_schema(schema, session): |
|
94 |
"""return a schema according to information stored in an rql database |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
95 |
as CWRType and CWEType entities |
0 | 96 |
""" |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
97 |
# |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
98 |
repo = session.repo |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
99 |
sqlcu = session.pool['system'] |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
100 |
_3_2_migration = False |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
101 |
dbhelper = repo.system_source.dbhelper |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
102 |
tables = set(t.lower() for t in dbhelper.list_tables(sqlcu)) |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
103 |
if 'eetype' in tables: |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
104 |
_3_2_migration = True |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
105 |
# 3.2 migration |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
106 |
_set_sql_prefix('') |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
107 |
# first rename entity types whose name changed in 3.2 without adding the |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
108 |
# cw_ prefix |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
109 |
for etype in OLD_SCHEMA_TYPES: |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
110 |
if etype.lower() in tables: |
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
111 |
sql = 'ALTER TABLE %s RENAME TO %s' % (etype, |
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
112 |
ETYPE_NAME_MAP[etype]) |
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
113 |
print sql |
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
114 |
sqlcu.execute(sql) |
2130
caa5acbecc08
[javascript] provide a simple function to limit textarea size (+minor cosmetic changes)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2044
diff
changeset
|
115 |
# other table renaming done once schema has been read |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
116 |
sidx = {} |
0 | 117 |
permsdict = deserialize_ertype_permissions(session) |
118 |
schema.reading_from_database = True |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
119 |
for eid, etype, desc in session.execute( |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
120 |
'Any X, N, D WHERE X is CWEType, X name N, X description D', |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
121 |
build_descr=False): |
0 | 122 |
# base types are already in the schema, skip them |
123 |
if etype in schemamod.BASE_TYPES: |
|
124 |
# just set the eid |
|
125 |
eschema = schema.eschema(etype) |
|
126 |
eschema.eid = eid |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
127 |
sidx[eid] = eschema |
0 | 128 |
continue |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
129 |
if etype in ETYPE_NAME_MAP: |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
130 |
netype = ETYPE_NAME_MAP[etype] |
0 | 131 |
# can't use write rql queries at this point, use raw sql |
1869
642a1a120a92
should use sql prefix here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1630
diff
changeset
|
132 |
session.system_sql('UPDATE %(p)sCWEType SET %(p)sname=%%(n)s WHERE %(p)seid=%%(x)s' |
642a1a120a92
should use sql prefix here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1630
diff
changeset
|
133 |
% {'p': sqlutils.SQL_PREFIX}, |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
134 |
{'x': eid, 'n': netype}) |
0 | 135 |
session.system_sql('UPDATE entities SET type=%(n)s WHERE type=%(x)s', |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
136 |
{'x': etype, 'n': netype}) |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
137 |
# XXX should be donne as well on sqlite based sources |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
138 |
if not etype in OLD_SCHEMA_TYPES and \ |
2172
cf8f9180e63e
delete-trailing-whitespace
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
2044
diff
changeset
|
139 |
(getattr(dbhelper, 'case_sensitive', False) |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
140 |
or etype.lower() != netype.lower()): |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
141 |
session.system_sql('ALTER TABLE %s%s RENAME TO %s%s' % ( |
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
142 |
sqlutils.SQL_PREFIX, etype, sqlutils.SQL_PREFIX, netype)) |
0 | 143 |
session.commit(False) |
144 |
try: |
|
145 |
session.system_sql('UPDATE deleted_entities SET type=%(n)s WHERE type=%(x)s', |
|
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
146 |
{'x': etype, 'n': netype}) |
0 | 147 |
except: |
148 |
pass |
|
149 |
tocleanup = [eid] |
|
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
150 |
tocleanup += (eid for eid, (eidetype, uri, extid) in repo._type_source_cache.items() |
0 | 151 |
if etype == eidetype) |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
152 |
repo.clear_caches(tocleanup) |
0 | 153 |
session.commit(False) |
2044
d5589c5bc4e6
alter table in schema serial when a renamed type is detected
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
1977
diff
changeset
|
154 |
etype = netype |
2126
a25859917ccc
stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2044
diff
changeset
|
155 |
etype = ybo.EntityType(name=etype, description=desc, eid=eid) |
0 | 156 |
eschema = schema.add_entity_type(etype) |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
157 |
sidx[eid] = eschema |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
158 |
set_perms(eschema, permsdict) |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
159 |
for etype, stype in session.execute( |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
160 |
'Any XN, ETN WHERE X is CWEType, X name XN, X specializes ET, ET name ETN', |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
161 |
build_descr=False): |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
162 |
schema.eschema(etype)._specialized_type = stype |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
163 |
schema.eschema(stype)._specialized_by.append(etype) |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
164 |
for eid, rtype, desc, sym, il, ftc in session.execute( |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
165 |
'Any X,N,D,S,I,FTC WHERE X is CWRType, X name N, X description D, ' |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
166 |
'X symetric S, X inlined I, X fulltext_container FTC', build_descr=False): |
2126
a25859917ccc
stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2044
diff
changeset
|
167 |
rtype = ybo.RelationType(name=rtype, description=desc, |
0 | 168 |
symetric=bool(sym), inlined=bool(il), |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
169 |
fulltext_container=ftc, eid=eid) |
0 | 170 |
rschema = schema.add_relation_type(rtype) |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
171 |
sidx[eid] = rschema |
0 | 172 |
cstrsdict = deserialize_rdef_constraints(session) |
173 |
for values in session.execute( |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
174 |
'Any X,SE,RT,OE,CARD,ORD,DESC,IDX,FTIDX,I18N,DFLT WHERE X is CWAttribute,' |
0 | 175 |
'X relation_type RT, X cardinality CARD, X ordernum ORD, X indexed IDX,' |
176 |
'X description DESC, X internationalizable I18N, X defaultval DFLT,' |
|
177 |
'X fulltextindexed FTIDX, X from_entity SE, X to_entity OE', |
|
178 |
build_descr=False): |
|
179 |
rdefeid, seid, reid, teid, card, ord, desc, idx, ftidx, i18n, default = values |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
180 |
rdef = ybo.RelationDefinition(sidx[seid].type, sidx[reid].type, sidx[teid].type, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
181 |
cardinality=card, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
182 |
constraints=cstrsdict.get(rdefeid, ()), |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
183 |
order=ord, description=desc, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
184 |
indexed=idx, fulltextindexed=ftidx, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
185 |
internationalizable=i18n, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
186 |
default=default, eid=rdefeid) |
4003
b9436fe77c9e
fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
3998
diff
changeset
|
187 |
rdefs = schema.add_relation_def(rdef) |
4010
b2d0b14a365d
[server] don't try to set perms twice on the same relation (e.g. symetric relations)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4003
diff
changeset
|
188 |
# rdefs can be None on duplicated relation definitions (e.g. symetrics) |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
189 |
if rdefs is not None: |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
190 |
set_perms(rdefs, permsdict) |
0 | 191 |
for values in session.execute( |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
192 |
'Any X,SE,RT,OE,CARD,ORD,DESC,C WHERE X is CWRelation, X relation_type RT,' |
0 | 193 |
'X cardinality CARD, X ordernum ORD, X description DESC, ' |
194 |
'X from_entity SE, X to_entity OE, X composite C', build_descr=False): |
|
195 |
rdefeid, seid, reid, teid, card, ord, desc, c = values |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
196 |
rdef = ybo.RelationDefinition(sidx[seid].type, sidx[reid].type, sidx[teid].type, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
197 |
constraints=cstrsdict.get(rdefeid, ()), |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
198 |
cardinality=card, order=ord, description=desc, |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
199 |
composite=c, eid=rdefeid) |
4003
b9436fe77c9e
fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
3998
diff
changeset
|
200 |
rdefs = schema.add_relation_def(rdef) |
4010
b2d0b14a365d
[server] don't try to set perms twice on the same relation (e.g. symetric relations)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4003
diff
changeset
|
201 |
# rdefs can be None on duplicated relation definitions (e.g. symetrics) |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
202 |
if rdefs is not None: |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
203 |
set_perms(rdefs, permsdict) |
0 | 204 |
schema.infer_specialization_rules() |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
205 |
if _3_2_migration: |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
206 |
_update_database(schema, sqlcu) |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
207 |
_set_sql_prefix('cw_') |
0 | 208 |
session.commit() |
209 |
schema.reading_from_database = False |
|
210 |
||
211 |
||
212 |
def deserialize_ertype_permissions(session): |
|
213 |
"""return sect action:groups associations for the given |
|
214 |
entity or relation schema with its eid, according to schema's |
|
215 |
permissions stored in the database as [read|add|delete|update]_permission |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
216 |
relations between CWEType/CWRType and CWGroup entities |
0 | 217 |
""" |
218 |
res = {} |
|
219 |
for action in ('read', 'add', 'update', 'delete'): |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
220 |
rql = 'Any E,N WHERE G is CWGroup, G name N, E %s_permission G' % action |
0 | 221 |
for eid, gname in session.execute(rql, build_descr=False): |
222 |
res.setdefault(eid, {}).setdefault(action, []).append(gname) |
|
223 |
rql = ('Any E,X,EXPR,V WHERE X is RQLExpression, X expression EXPR, ' |
|
224 |
'E %s_permission X, X mainvars V' % action) |
|
225 |
for eid, expreid, expr, mainvars in session.execute(rql, build_descr=False): |
|
226 |
# we don't know yet if it's a rql expr for an entity or a relation, |
|
227 |
# so append a tuple to differentiate from groups and so we'll be |
|
228 |
# able to instantiate it later |
|
229 |
res.setdefault(eid, {}).setdefault(action, []).append( (expr, mainvars, expreid) ) |
|
230 |
return res |
|
231 |
||
232 |
def set_perms(erschema, permsdict): |
|
233 |
"""set permissions on the given erschema according to the permission |
|
234 |
definition dictionary as built by deserialize_ertype_permissions for a |
|
235 |
given erschema's eid |
|
236 |
""" |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
237 |
try: |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
238 |
thispermsdict = permsdict[erschema.eid] |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
239 |
except KeyError: |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
240 |
return |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
241 |
permissions = erschema.permissions |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
242 |
for action, somethings in thispermsdict.iteritems(): |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
243 |
permissions[action] = tuple( |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
244 |
isinstance(p, tuple) and erschema.rql_expression(*p) or p |
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
245 |
for p in somethings) |
0 | 246 |
|
247 |
||
248 |
def deserialize_rdef_constraints(session): |
|
249 |
"""return the list of relation definition's constraints as instances""" |
|
250 |
res = {} |
|
251 |
for rdefeid, ceid, ct, val in session.execute( |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
252 |
'Any E, X,TN,V WHERE E constrained_by X, X is CWConstraint, ' |
0 | 253 |
'X cstrtype T, T name TN, X value V', build_descr=False): |
254 |
cstr = CONSTRAINTS[ct].deserialize(val) |
|
255 |
cstr.eid = ceid |
|
256 |
res.setdefault(rdefeid, []).append(cstr) |
|
257 |
return res |
|
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
258 |
|
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
259 |
|
0 | 260 |
# schema / perms serialization ################################################ |
261 |
||
262 |
def serialize_schema(cursor, schema, verbose=False): |
|
263 |
"""synchronize schema and permissions in the database according to |
|
264 |
current schema |
|
265 |
""" |
|
3737 | 266 |
quiet = os.environ.get('APYCOT_ROOT') |
3723
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
267 |
if not quiet: |
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
268 |
_title = '-> storing the schema in the database ' |
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
269 |
print _title, |
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
270 |
execute = cursor.execute |
0 | 271 |
eschemas = schema.entities() |
272 |
aller = eschemas + schema.relations() |
|
3723
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
273 |
if not verbose and not quiet: |
0 | 274 |
pb_size = len(aller) + len(CONSTRAINTS) + len([x for x in eschemas if x.specializes()]) |
2396
8bfb99d7bbcc
[cw-ctl] improve dialog messages
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
2395
diff
changeset
|
275 |
pb = ProgressBar(pb_size, title=_title) |
3857
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
276 |
else: |
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
277 |
pb = None |
2597
d9c5a7e0563c
[C schema seria] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
278 |
rql = 'INSERT CWConstraintType X: X name %(ct)s' |
0 | 279 |
for cstrtype in CONSTRAINTS: |
280 |
if verbose: |
|
281 |
print rql |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
282 |
execute(rql, {'ct': unicode(cstrtype)}, build_descr=False) |
3857
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
283 |
if pb is not None: |
0 | 284 |
pb.update() |
285 |
groupmap = group_mapping(cursor, interactive=False) |
|
286 |
for ertype in aller: |
|
287 |
# skip eid and has_text relations |
|
2596
d02eed70937f
[R repo, schema] use VIRTUAL_RTYPES const
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2458
diff
changeset
|
288 |
if ertype in VIRTUAL_RTYPES: |
3857
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
289 |
if pb is not None: |
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
290 |
pb.update() |
0 | 291 |
continue |
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
292 |
for rql, kwargs in erschema2rql(schema[ertype], groupmap): |
0 | 293 |
if verbose: |
294 |
print rql % kwargs |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
295 |
execute(rql, kwargs, build_descr=False) |
3857
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
296 |
if pb is not None: |
0 | 297 |
pb.update() |
298 |
for rql, kwargs in specialize2rql(schema): |
|
299 |
if verbose: |
|
300 |
print rql % kwargs |
|
4312
740397c24ec3
minor schema deserialization optimizations
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4252
diff
changeset
|
301 |
execute(rql, kwargs, build_descr=False) |
3857
6676a839dc97
ensure pb is not None
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3854
diff
changeset
|
302 |
if pb is not None: |
0 | 303 |
pb.update() |
3723
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
304 |
if not quiet: |
a961c7cb2644
be quiet w/ apycot
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3689
diff
changeset
|
305 |
print |
0 | 306 |
|
307 |
||
308 |
def _ervalues(erschema): |
|
309 |
try: |
|
310 |
type_ = unicode(erschema.type) |
|
311 |
except UnicodeDecodeError, e: |
|
312 |
raise Exception("can't decode %s [was %s]" % (erschema.type, e)) |
|
313 |
try: |
|
314 |
desc = unicode(erschema.description) or u'' |
|
315 |
except UnicodeDecodeError, e: |
|
316 |
raise Exception("can't decode %s [was %s]" % (erschema.description, e)) |
|
317 |
return { |
|
318 |
'name': type_, |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2955
diff
changeset
|
319 |
'final': erschema.final, |
0 | 320 |
'description': desc, |
321 |
} |
|
322 |
||
323 |
def eschema_relations_values(eschema): |
|
324 |
values = _ervalues(eschema) |
|
325 |
relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)] |
|
326 |
return relations, values |
|
327 |
||
328 |
# XXX 2.47 migration |
|
329 |
HAS_FULLTEXT_CONTAINER = True |
|
330 |
||
331 |
def rschema_relations_values(rschema): |
|
332 |
values = _ervalues(rschema) |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2955
diff
changeset
|
333 |
values['final'] = rschema.final |
0 | 334 |
values['symetric'] = rschema.symetric |
335 |
values['inlined'] = rschema.inlined |
|
336 |
if HAS_FULLTEXT_CONTAINER: |
|
337 |
if isinstance(rschema.fulltext_container, str): |
|
338 |
values['fulltext_container'] = unicode(rschema.fulltext_container) |
|
339 |
else: |
|
340 |
values['fulltext_container'] = rschema.fulltext_container |
|
341 |
relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)] |
|
342 |
return relations, values |
|
343 |
||
344 |
def _rdef_values(rschema, objtype, props): |
|
345 |
amap = {'order': 'ordernum'} |
|
346 |
values = {} |
|
4024
6a14cff373c3
more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4021
diff
changeset
|
347 |
for prop, default in schemamod.RelationDefinitionSchema.rproperty_defs(objtype).iteritems(): |
4003
b9436fe77c9e
fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
3998
diff
changeset
|
348 |
if prop in ('eid', 'constraints', 'uid', 'infered', 'permissions'): |
0 | 349 |
continue |
350 |
value = props.get(prop, default) |
|
351 |
if prop in ('indexed', 'fulltextindexed', 'internationalizable'): |
|
352 |
value = bool(value) |
|
353 |
elif prop == 'ordernum': |
|
354 |
value = int(value) |
|
355 |
elif isinstance(value, str): |
|
356 |
value = unicode(value) |
|
357 |
values[amap.get(prop, prop)] = value |
|
358 |
return values |
|
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
359 |
|
0 | 360 |
def nfrdef_relations_values(rschema, objtype, props): |
361 |
values = _rdef_values(rschema, objtype, props) |
|
362 |
relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)] |
|
363 |
return relations, values |
|
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
364 |
|
0 | 365 |
def frdef_relations_values(rschema, objtype, props): |
366 |
values = _rdef_values(rschema, objtype, props) |
|
367 |
default = values['default'] |
|
368 |
del values['default'] |
|
369 |
if default is not None: |
|
370 |
if default is False: |
|
371 |
default = u'' |
|
372 |
elif not isinstance(default, unicode): |
|
373 |
default = unicode(default) |
|
374 |
values['defaultval'] = default |
|
375 |
relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)] |
|
376 |
return relations, values |
|
377 |
||
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
378 |
|
4033
732eccbed54a
missing groupmap propagation to rschema2rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4024
diff
changeset
|
379 |
def __rdef2rql(genmap, rschema, subjtype=None, objtype=None, props=None, |
732eccbed54a
missing groupmap propagation to rschema2rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4024
diff
changeset
|
380 |
groupmap=None): |
0 | 381 |
if subjtype is None: |
382 |
assert objtype is None |
|
383 |
assert props is None |
|
4189
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
384 |
targets = sorted(rschema.rdefs) |
0 | 385 |
else: |
386 |
assert not objtype is None |
|
387 |
targets = [(subjtype, objtype)] |
|
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
388 |
# relation schema |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
389 |
if rschema.final: |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
390 |
etype = 'CWAttribute' |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
391 |
else: |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
392 |
etype = 'CWRelation' |
0 | 393 |
for subjtype, objtype in targets: |
394 |
if props is None: |
|
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
395 |
_props = rschema.rdef(subjtype, objtype) |
0 | 396 |
else: |
397 |
_props = props |
|
398 |
# don't serialize infered relations |
|
399 |
if _props.get('infered'): |
|
400 |
continue |
|
3689
deb13e88e037
follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2955
diff
changeset
|
401 |
gen = genmap[rschema.final] |
0 | 402 |
for rql, values in gen(rschema, subjtype, objtype, _props): |
403 |
yield rql, values |
|
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
404 |
# no groupmap means "no security insertion" |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
405 |
if groupmap: |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
406 |
for rql, args in _erperms2rql(_props, groupmap): |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
407 |
args['st'] = str(subjtype) |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
408 |
args['rt'] = str(rschema) |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
409 |
args['ot'] = str(objtype) |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
410 |
yield rql + 'X is %s, X from_entity ST, X to_entity OT, '\ |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
411 |
'X relation_type RT, RT name %%(rt)s, ST name %%(st)s, '\ |
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
412 |
'OT name %%(ot)s' % etype, args |
0 | 413 |
|
414 |
||
415 |
def schema2rql(schema, skip=None, allow=None): |
|
416 |
"""return a list of rql insert statements to enter the schema in the |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
417 |
database as CWRType and CWEType entities |
0 | 418 |
""" |
419 |
assert not (skip is not None and allow is not None), \ |
|
420 |
'can\'t use both skip and allow' |
|
421 |
all = schema.entities() + schema.relations() |
|
422 |
if skip is not None: |
|
423 |
return chain(*[erschema2rql(schema[t]) for t in all if not t in skip]) |
|
424 |
elif allow is not None: |
|
425 |
return chain(*[erschema2rql(schema[t]) for t in all if t in allow]) |
|
426 |
return chain(*[erschema2rql(schema[t]) for t in all]) |
|
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
427 |
|
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
428 |
def erschema2rql(erschema, groupmap): |
0 | 429 |
if isinstance(erschema, schemamod.EntitySchema): |
4033
732eccbed54a
missing groupmap propagation to rschema2rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4024
diff
changeset
|
430 |
return eschema2rql(erschema, groupmap=groupmap) |
732eccbed54a
missing groupmap propagation to rschema2rql
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4024
diff
changeset
|
431 |
return rschema2rql(erschema, groupmap=groupmap) |
0 | 432 |
|
4189
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
433 |
def eschema2rql(eschema, groupmap=None): |
0 | 434 |
"""return a list of rql insert statements to enter an entity schema |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
435 |
in the database as an CWEType entity |
0 | 436 |
""" |
437 |
relations, values = eschema_relations_values(eschema) |
|
438 |
# NOTE: 'specializes' relation can't be inserted here since there's no |
|
439 |
# way to make sure the parent type is inserted before the child type |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
440 |
yield 'INSERT CWEType X: %s' % ','.join(relations) , values |
4189
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
441 |
# entity permissions |
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
442 |
if groupmap is not None: |
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
443 |
for rql, args in _erperms2rql(eschema, groupmap): |
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
444 |
args['name'] = str(eschema) |
bd552b341334
make groupmap argument optional / sort for testing purpose
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4033
diff
changeset
|
445 |
yield rql + 'X is CWEType, X name %(name)s', args |
0 | 446 |
|
447 |
def specialize2rql(schema): |
|
448 |
for eschema in schema.entities(): |
|
449 |
for rql, kwargs in eschemaspecialize2rql(eschema): |
|
450 |
yield rql, kwargs |
|
451 |
||
452 |
def eschemaspecialize2rql(eschema): |
|
453 |
specialized_type = eschema.specializes() |
|
454 |
if specialized_type: |
|
455 |
values = {'x': eschema.type, 'et': specialized_type.type} |
|
456 |
yield 'SET X specializes ET WHERE X name %(x)s, ET name %(et)s', values |
|
457 |
||
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
458 |
def rschema2rql(rschema, addrdef=True, groupmap=None): |
0 | 459 |
"""return a list of rql insert statements to enter a relation schema |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
460 |
in the database as an CWRType entity |
0 | 461 |
""" |
462 |
if rschema.type == 'has_text': |
|
463 |
return |
|
464 |
relations, values = rschema_relations_values(rschema) |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
465 |
yield 'INSERT CWRType X: %s' % ','.join(relations), values |
0 | 466 |
if addrdef: |
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
467 |
for rql, values in rdef2rql(rschema, groupmap=groupmap): |
0 | 468 |
yield rql, values |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
469 |
|
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
470 |
def rdef2rql(rschema, subjtype=None, objtype=None, props=None, groupmap=None): |
0 | 471 |
genmap = {True: frdef2rql, False: nfrdef2rql} |
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
472 |
return __rdef2rql(genmap, rschema, subjtype, objtype, props, groupmap) |
0 | 473 |
|
474 |
||
475 |
_LOCATE_RDEF_RQL0 = 'X relation_type ER,X from_entity SE,X to_entity OE' |
|
476 |
_LOCATE_RDEF_RQL1 = 'SE name %(se)s,ER name %(rt)s,OE name %(oe)s' |
|
477 |
||
478 |
def frdef2rql(rschema, subjtype, objtype, props): |
|
479 |
relations, values = frdef_relations_values(rschema, objtype, props) |
|
480 |
relations.append(_LOCATE_RDEF_RQL0) |
|
481 |
values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)}) |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
482 |
yield 'INSERT CWAttribute X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values |
0 | 483 |
for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props): |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
484 |
yield rql + ', EDEF is CWAttribute', values |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
485 |
|
0 | 486 |
def nfrdef2rql(rschema, subjtype, objtype, props): |
487 |
relations, values = nfrdef_relations_values(rschema, objtype, props) |
|
488 |
relations.append(_LOCATE_RDEF_RQL0) |
|
489 |
values.update({'se': str(subjtype), 'rt': str(rschema), 'oe': str(objtype)}) |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
490 |
yield 'INSERT CWRelation X: %s WHERE %s' % (','.join(relations), _LOCATE_RDEF_RQL1), values |
0 | 491 |
for rql, values in rdefrelations2rql(rschema, subjtype, objtype, props): |
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
492 |
yield rql + ', EDEF is CWRelation', values |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
493 |
|
0 | 494 |
def rdefrelations2rql(rschema, subjtype, objtype, props): |
495 |
iterators = [] |
|
4021
280c910c8710
move i18n / migration modules from cw.common to cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4014
diff
changeset
|
496 |
for constraint in props.constraints: |
0 | 497 |
iterators.append(constraint2rql(rschema, subjtype, objtype, constraint)) |
498 |
return chain(*iterators) |
|
499 |
||
500 |
def constraint2rql(rschema, subjtype, objtype, constraint): |
|
501 |
values = {'ctname': unicode(constraint.type()), |
|
502 |
'value': unicode(constraint.serialize()), |
|
503 |
'rt': str(rschema), 'se': str(subjtype), 'oe': str(objtype)} |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
504 |
yield 'INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE \ |
0 | 505 |
CT name %(ctname)s, EDEF relation_type ER, EDEF from_entity SE, EDEF to_entity OE, \ |
506 |
ER name %(rt)s, SE name %(se)s, OE name %(oe)s', values |
|
507 |
||
508 |
||
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
509 |
def _erperms2rql(erschema, groupmap): |
0 | 510 |
"""return rql insert statements to enter the entity or relation |
511 |
schema's permissions in the database as |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
512 |
[read|add|delete|update]_permission relations between CWEType/CWRType |
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
513 |
and CWGroup entities |
0 | 514 |
""" |
515 |
for action in erschema.ACTIONS: |
|
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
516 |
for group_or_rqlexpr in erschema.action_permissions(action): |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
517 |
if isinstance(group_or_rqlexpr, basestring): |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
518 |
# group |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
519 |
try: |
4003
b9436fe77c9e
fix bad merge
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
3998
diff
changeset
|
520 |
yield ('SET X %s_permission Y WHERE Y eid %%(g)s, ' % action, |
4011
394f853bb653
[migration] write migration instructions for permissions handling on relation definition
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
4010
diff
changeset
|
521 |
{'g': groupmap[group_or_rqlexpr]}) |
3877
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
522 |
except KeyError: |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
523 |
continue |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
524 |
else: |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
525 |
# rqlexpr |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
526 |
rqlexpr = group_or_rqlexpr |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
527 |
yield ('INSERT RQLExpression E: E expression %%(e)s, E exprtype %%(t)s, ' |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
528 |
'E mainvars %%(v)s, X %s_permission E WHERE ' % action, |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
529 |
{'e': unicode(rqlexpr.expression), |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
530 |
'v': unicode(rqlexpr.mainvars), |
7ca53fc72a0a
reldefsecurity branch :
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3876
diff
changeset
|
531 |
't': unicode(rqlexpr.__class__.__name__)}) |
0 | 532 |
|
533 |
||
534 |
def updateeschema2rql(eschema): |
|
535 |
relations, values = eschema_relations_values(eschema) |
|
536 |
values['et'] = eschema.type |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
537 |
yield 'SET %s WHERE X is CWEType, X name %%(et)s' % ','.join(relations), values |
0 | 538 |
|
539 |
def updaterschema2rql(rschema): |
|
540 |
relations, values = rschema_relations_values(rschema) |
|
541 |
values['rt'] = rschema.type |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
542 |
yield 'SET %s WHERE X is CWRType, X name %%(rt)s' % ','.join(relations), values |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
543 |
|
0 | 544 |
def updaterdef2rql(rschema, subjtype=None, objtype=None, props=None): |
545 |
genmap = {True: updatefrdef2rql, False: updatenfrdef2rql} |
|
546 |
return __rdef2rql(genmap, rschema, subjtype, objtype, props) |
|
547 |
||
548 |
def updatefrdef2rql(rschema, subjtype, objtype, props): |
|
549 |
relations, values = frdef_relations_values(rschema, objtype, props) |
|
550 |
values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype}) |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
551 |
yield 'SET %s WHERE %s, %s, X is CWAttribute' % (','.join(relations), |
2597
d9c5a7e0563c
[C schema seria] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
552 |
_LOCATE_RDEF_RQL0, |
d9c5a7e0563c
[C schema seria] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
553 |
_LOCATE_RDEF_RQL1), values |
1630
41aadba8b29f
delete-trailing-whitespaces, check table existance
sylvain.thenault@logilab.fr
parents:
1398
diff
changeset
|
554 |
|
0 | 555 |
def updatenfrdef2rql(rschema, subjtype, objtype, props): |
556 |
relations, values = nfrdef_relations_values(rschema, objtype, props) |
|
557 |
values.update({'se': subjtype, 'rt': str(rschema), 'oe': objtype}) |
|
1398
5fe84a5f7035
rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents:
0
diff
changeset
|
558 |
yield 'SET %s WHERE %s, %s, X is CWRelation' % (','.join(relations), |
2597
d9c5a7e0563c
[C schema seria] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
559 |
_LOCATE_RDEF_RQL0, |
d9c5a7e0563c
[C schema seria] cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2596
diff
changeset
|
560 |
_LOCATE_RDEF_RQL1), values |