author | Julien Cristau <julien.cristau@logilab.fr> |
Fri, 13 Feb 2015 14:32:15 +0100 | |
changeset 10251 | 2daa5c6dea4d |
parent 10204 | f8ccae1e271d |
child 10443 | 2d3834df64ab |
permissions | -rw-r--r-- |
10199
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
1 |
# copyright 2004-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
3 |
# |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
4 |
# This file is part of yams. |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
5 |
# |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
6 |
# yams is free software: you can redistribute it and/or modify it under the |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
9 |
# any later version. |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
10 |
# |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
11 |
# yams is distributed in the hope that it will be useful, but WITHOUT ANY |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
12 |
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
13 |
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
14 |
# details. |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
15 |
# |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
17 |
# with yams. If not, see <http://www.gnu.org/licenses/>. |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
18 |
"""write a schema as sql""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
19 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
20 |
__docformat__ = "restructuredtext en" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
21 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
22 |
from hashlib import md5 |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
23 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
24 |
from six.moves import range |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
25 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
26 |
from yams.constraints import SizeConstraint, UniqueConstraint |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
27 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
28 |
# default are usually not handled at the sql level. If you want them, set |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
29 |
# SET_DEFAULT to True |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
30 |
SET_DEFAULT = False |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
31 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
32 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
33 |
def schema2sql(dbhelper, schema, skip_entities=(), skip_relations=(), prefix=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
34 |
"""write to the output stream a SQL schema to store the objects |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
35 |
corresponding to the given schema |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
36 |
""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
37 |
output = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
38 |
w = output.append |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
39 |
for etype in sorted(schema.entities()): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
40 |
eschema = schema.eschema(etype) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
41 |
if eschema.final or eschema.type in skip_entities: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
42 |
continue |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
43 |
w(eschema2sql(dbhelper, eschema, skip_relations, prefix=prefix)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
44 |
for rtype in sorted(schema.relations()): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
45 |
rschema = schema.rschema(rtype) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
46 |
if rschema.final or rschema.inlined or rschema.rule: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
47 |
continue |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
48 |
w(rschema2sql(rschema)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
49 |
return '\n'.join(output) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
50 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
51 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
52 |
def dropschema2sql(dbhelper, schema, skip_entities=(), skip_relations=(), prefix=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
53 |
"""write to the output stream a SQL schema to store the objects |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
54 |
corresponding to the given schema |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
55 |
""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
56 |
output = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
57 |
w = output.append |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
58 |
for etype in sorted(schema.entities()): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
59 |
eschema = schema.eschema(etype) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
60 |
if eschema.final or eschema.type in skip_entities: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
61 |
continue |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
62 |
stmts = dropeschema2sql(dbhelper, eschema, skip_relations, prefix=prefix) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
63 |
for stmt in stmts: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
64 |
w(stmt) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
65 |
for rtype in sorted(schema.relations()): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
66 |
rschema = schema.rschema(rtype) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
67 |
if rschema.final or rschema.inlined: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
68 |
continue |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
69 |
w(droprschema2sql(rschema)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
70 |
return '\n'.join(output) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
71 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
72 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
73 |
def eschema_attrs(eschema, skip_relations): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
74 |
attrs = [attrdef for attrdef in eschema.attribute_definitions() |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
75 |
if not attrdef[0].type in skip_relations] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
76 |
attrs += [(rschema, None) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
77 |
for rschema in eschema.subject_relations() |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
78 |
if not rschema.final and rschema.inlined] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
79 |
return attrs |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
80 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
81 |
def unique_index_name(eschema, columns): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
82 |
return u'unique_%s' % md5((eschema.type + |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
83 |
',' + |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
84 |
','.join(sorted(columns))).encode('ascii')).hexdigest() |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
85 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
86 |
def iter_unique_index_names(eschema): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
87 |
for columns in eschema._unique_together or (): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
88 |
yield columns, unique_index_name(eschema, columns) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
89 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
90 |
def dropeschema2sql(dbhelper, eschema, skip_relations=(), prefix=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
91 |
"""return sql to drop an entity type's table""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
92 |
# not necessary to drop indexes, that's implictly done when |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
93 |
# dropping the table, but we need to drop SQLServer views used to |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
94 |
# create multicol unique indices |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
95 |
statements = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
96 |
tablename = prefix + eschema.type |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
97 |
if eschema._unique_together is not None: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
98 |
for columns, index_name in iter_unique_index_names(eschema): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
99 |
cols = ['%s%s' % (prefix, col) for col in columns] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
100 |
sqls = dbhelper.sqls_drop_multicol_unique_index(tablename, cols, index_name) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
101 |
statements += sqls |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
102 |
statements += ['DROP TABLE %s;' % (tablename)] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
103 |
return statements |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
104 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
105 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
106 |
def eschema2sql(dbhelper, eschema, skip_relations=(), prefix=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
107 |
"""write an entity schema as SQL statements to stdout""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
108 |
output = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
109 |
w = output.append |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
110 |
table = prefix + eschema.type |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
111 |
w('CREATE TABLE %s(' % (table)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
112 |
attrs = eschema_attrs(eschema, skip_relations) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
113 |
# XXX handle objectinline physical mode |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
114 |
for i in range(len(attrs)): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
115 |
rschema, attrschema = attrs[i] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
116 |
if attrschema is not None: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
117 |
sqltype = aschema2sql(dbhelper, eschema, rschema, attrschema, |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
118 |
indent=' ') |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
119 |
else: # inline relation |
10201
989bbadbcd8d
Add foreign key for inline relations
Julien Cristau <julien.cristau@logilab.fr>
parents:
10199
diff
changeset
|
120 |
sqltype = 'integer REFERENCES entities (eid)' |
10199
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
121 |
if i == len(attrs) - 1: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
122 |
w(' %s%s %s' % (prefix, rschema.type, sqltype)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
123 |
else: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
124 |
w(' %s%s %s,' % (prefix, rschema.type, sqltype)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
125 |
w(');') |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
126 |
# create indexes |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
127 |
for i in range(len(attrs)): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
128 |
rschema, attrschema = attrs[i] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
129 |
if attrschema is None or eschema.rdef(rschema).indexed: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
130 |
w(dbhelper.sql_create_index(table, prefix + rschema.type)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
131 |
for columns, index_name in iter_unique_index_names(eschema): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
132 |
cols = ['%s%s' % (prefix, col) for col in columns] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
133 |
sqls = dbhelper.sqls_create_multicol_unique_index(table, cols, index_name) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
134 |
for sql in sqls: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
135 |
w(sql) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
136 |
w('') |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
137 |
return '\n'.join(output) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
138 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
139 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
140 |
def aschema2sql(dbhelper, eschema, rschema, aschema, creating=True, indent=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
141 |
"""write an attribute schema as SQL statements to stdout""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
142 |
attr = rschema.type |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
143 |
rdef = rschema.rdef(eschema.type, aschema.type) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
144 |
sqltype = type_from_constraints(dbhelper, aschema.type, rdef.constraints, |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
145 |
creating) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
146 |
if SET_DEFAULT: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
147 |
default = eschema.default(attr) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
148 |
if default is not None: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
149 |
if aschema.type == 'Boolean': |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
150 |
sqltype += ' DEFAULT %s' % dbhelper.boolean_value(default) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
151 |
elif aschema.type == 'String': |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
152 |
sqltype += ' DEFAULT %r' % str(default) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
153 |
elif aschema.type in ('Int', 'BigInt', 'Float'): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
154 |
sqltype += ' DEFAULT %s' % default |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
155 |
# XXX ignore default for other type |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
156 |
# this is expected for NOW / TODAY |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
157 |
if creating: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
158 |
if rdef.uid: |
10204
f8ccae1e271d
Add reference from etype table's eid column to the entities table
Julien Cristau <julien.cristau@logilab.fr>
parents:
10202
diff
changeset
|
159 |
sqltype += ' PRIMARY KEY REFERENCES entities (eid)' |
10199
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
160 |
elif rdef.cardinality[0] == '1': |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
161 |
# don't set NOT NULL if backend isn't able to change it later |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
162 |
if dbhelper.alter_column_support: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
163 |
sqltype += ' NOT NULL' |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
164 |
# else we're getting sql type to alter a column, we don't want key / indexes |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
165 |
# / null modifiers |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
166 |
return sqltype |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
167 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
168 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
169 |
def type_from_constraints(dbhelper, etype, constraints, creating=True): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
170 |
"""return a sql type string corresponding to the constraints""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
171 |
constraints = list(constraints) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
172 |
unique, sqltype = False, None |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
173 |
size_constrained_string = dbhelper.TYPE_MAPPING.get('SizeConstrainedString', 'varchar(%s)') |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
174 |
if etype == 'String': |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
175 |
for constraint in constraints: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
176 |
if isinstance(constraint, SizeConstraint): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
177 |
if constraint.max is not None: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
178 |
sqltype = size_constrained_string % constraint.max |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
179 |
elif isinstance(constraint, UniqueConstraint): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
180 |
unique = True |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
181 |
if sqltype is None: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
182 |
sqltype = dbhelper.TYPE_MAPPING[etype] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
183 |
if creating and unique: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
184 |
sqltype += ' UNIQUE' |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
185 |
return sqltype |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
186 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
187 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
188 |
_SQL_SCHEMA = """ |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
189 |
CREATE TABLE %(table)s ( |
10202
aaabcb64f77f
Use foreign keys for relations tables
Julien Cristau <julien.cristau@logilab.fr>
parents:
10201
diff
changeset
|
190 |
eid_from INTEGER NOT NULL REFERENCES entities (eid), |
aaabcb64f77f
Use foreign keys for relations tables
Julien Cristau <julien.cristau@logilab.fr>
parents:
10201
diff
changeset
|
191 |
eid_to INTEGER NOT NULL REFERENCES entities (eid), |
10199
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
192 |
CONSTRAINT %(table)s_p_key PRIMARY KEY(eid_from, eid_to) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
193 |
); |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
194 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
195 |
CREATE INDEX %(table)s_from_idx ON %(table)s(eid_from); |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
196 |
CREATE INDEX %(table)s_to_idx ON %(table)s(eid_to);""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
197 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
198 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
199 |
def rschema2sql(rschema): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
200 |
assert not rschema.rule |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
201 |
return _SQL_SCHEMA % {'table': '%s_relation' % rschema.type} |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
202 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
203 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
204 |
def droprschema2sql(rschema): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
205 |
"""return sql to drop a relation type's table""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
206 |
# not necessary to drop indexes, that's implictly done when dropping |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
207 |
# the table |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
208 |
return 'DROP TABLE %s_relation;' % rschema.type |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
209 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
210 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
211 |
def grant_schema(schema, user, set_owner=True, skip_entities=(), prefix=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
212 |
"""write to the output stream a SQL schema to store the objects |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
213 |
corresponding to the given schema |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
214 |
""" |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
215 |
output = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
216 |
w = output.append |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
217 |
for etype in sorted(schema.entities()): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
218 |
eschema = schema.eschema(etype) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
219 |
if eschema.final or etype in skip_entities: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
220 |
continue |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
221 |
w(grant_eschema(eschema, user, set_owner, prefix=prefix)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
222 |
for rtype in sorted(schema.relations()): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
223 |
rschema = schema.rschema(rtype) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
224 |
if rschema.final or rschema.inlined: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
225 |
continue |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
226 |
w(grant_rschema(rschema, user, set_owner)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
227 |
return '\n'.join(output) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
228 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
229 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
230 |
def grant_eschema(eschema, user, set_owner=True, prefix=''): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
231 |
output = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
232 |
w = output.append |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
233 |
etype = eschema.type |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
234 |
if set_owner: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
235 |
w('ALTER TABLE %s%s OWNER TO %s;' % (prefix, etype, user)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
236 |
w('GRANT ALL ON %s%s TO %s;' % (prefix, etype, user)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
237 |
return '\n'.join(output) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
238 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
239 |
|
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
240 |
def grant_rschema(rschema, user, set_owner=True): |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
241 |
output = [] |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
242 |
if set_owner: |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
243 |
output.append('ALTER TABLE %s_relation OWNER TO %s;' % (rschema.type, user)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
244 |
output.append('GRANT ALL ON %s_relation TO %s;' % (rschema.type, user)) |
218c28bff695
Steal schema2sql module from yams
Julien Cristau <julien.cristau@logilab.fr>
parents:
diff
changeset
|
245 |
return '\n'.join(output) |