17 # with yams. If not, see <http://www.gnu.org/licenses/>. |
17 # with yams. If not, see <http://www.gnu.org/licenses/>. |
18 """write a schema as sql""" |
18 """write a schema as sql""" |
19 |
19 |
20 from hashlib import md5 |
20 from hashlib import md5 |
21 |
21 |
22 from six import string_types, text_type |
|
23 from six.moves import range |
|
24 |
|
25 from yams.constraints import (SizeConstraint, UniqueConstraint, Attribute, |
22 from yams.constraints import (SizeConstraint, UniqueConstraint, Attribute, |
26 NOW, TODAY) |
23 NOW, TODAY) |
27 from logilab import database |
24 from logilab import database |
28 from logilab.common.decorators import monkeypatch |
25 from logilab.common.decorators import monkeypatch |
29 |
26 |
86 def unique_index_name(eschema, attrs): |
83 def unique_index_name(eschema, attrs): |
87 """Return a predictable-but-size-constrained name for a multi-columns unique index on |
84 """Return a predictable-but-size-constrained name for a multi-columns unique index on |
88 given attributes of the entity schema (actually, the later may be a schema or a string). |
85 given attributes of the entity schema (actually, the later may be a schema or a string). |
89 """ |
86 """ |
90 # keep giving eschema instead of table name for bw compat |
87 # keep giving eschema instead of table name for bw compat |
91 table = text_type(eschema) |
88 table = str(eschema) |
92 # unique_index_name is used as name of CWUniqueConstraint, hence it should be unicode |
89 # unique_index_name is used as name of CWUniqueConstraint, hence it should be unicode |
93 return text_type(build_index_name(table, attrs, 'unique_')) |
90 return build_index_name(table, attrs, 'unique_') |
94 |
91 |
95 |
92 |
96 def iter_unique_index_names(eschema): |
93 def iter_unique_index_names(eschema): |
97 """Yield (attrs, index name) where attrs is a list of entity type's attribute names that should |
94 """Yield (attrs, index name) where attrs is a list of entity type's attribute names that should |
98 be unique together, and index name the unique index name. |
95 be unique together, and index name the unique index name. |
202 value = constraint_value_as_sql(constraint.maxvalue, dbhelper, prefix) |
199 value = constraint_value_as_sql(constraint.maxvalue, dbhelper, prefix) |
203 condition.append('%s%s <= %s' % (prefix, attr, value)) |
200 condition.append('%s%s <= %s' % (prefix, attr, value)) |
204 return cstrname, ' AND '.join(condition) |
201 return cstrname, ' AND '.join(condition) |
205 elif constraint.type() == 'StaticVocabularyConstraint': |
202 elif constraint.type() == 'StaticVocabularyConstraint': |
206 sample = next(iter(constraint.vocabulary())) |
203 sample = next(iter(constraint.vocabulary())) |
207 if not isinstance(sample, string_types): |
204 if not isinstance(sample, str): |
208 values = ', '.join(str(word) for word in constraint.vocabulary()) |
205 values = ', '.join(str(word) for word in constraint.vocabulary()) |
209 else: |
206 else: |
210 # XXX better quoting? |
207 # XXX better quoting? |
211 values = ', '.join("'%s'" % word.replace("'", "''") for word in constraint.vocabulary()) |
208 values = ', '.join("'%s'" % word.replace("'", "''") for word in constraint.vocabulary()) |
212 return cstrname, '%s%s IN (%s)' % (prefix, attr, values) |
209 return cstrname, '%s%s IN (%s)' % (prefix, attr, values) |