--- a/cubicweb/server/schema2sql.py Wed Jun 22 17:13:10 2016 +0200
+++ b/cubicweb/server/schema2sql.py Mon Jun 20 17:59:43 2016 +0200
@@ -26,12 +26,24 @@
from yams.constraints import (SizeConstraint, UniqueConstraint, Attribute,
NOW, TODAY)
+from logilab import database
+from logilab.common.decorators import monkeypatch
# default are usually not handled at the sql level. If you want them, set
# SET_DEFAULT to True
SET_DEFAULT = False
+# backport fix for lgdb #6662663
+@monkeypatch(database._GenericAdvFuncHelper)
+def sql_create_index(self, table, column, unique=False):
+ idx = self._index_name(table, column, unique)
+ if unique:
+ return 'ALTER TABLE %s ADD CONSTRAINT %s UNIQUE(%s);' % (table, idx, column)
+ else:
+ return 'CREATE INDEX %s ON %s(%s);' % (idx, table, column)
+
+
def rschema_has_table(rschema, skip_relations):
"""Return True if the given schema should have a table in the database"""
return not (rschema.final or rschema.inlined or rschema.rule or rschema.type in skip_relations)
@@ -146,6 +158,9 @@
rschema, attrschema = attrs[i]
if attrschema is None or eschema.rdef(rschema).indexed:
w(dbhelper.sql_create_index(table, prefix + rschema.type))
+ if attrschema and any(isinstance(cstr, UniqueConstraint)
+ for cstr in eschema.rdef(rschema).constraints):
+ w(dbhelper.sql_create_index(table, prefix + rschema.type, unique=True))
for columns, index_name in iter_unique_index_names(eschema):
cols = ['%s%s' % (prefix, col) for col in columns]
sqls = dbhelper.sqls_create_multicol_unique_index(table, cols, index_name)
@@ -198,7 +213,7 @@
"""write an attribute schema as SQL statements to stdout"""
attr = rschema.type
rdef = rschema.rdef(eschema.type, aschema.type)
- sqltype = type_from_rdef(dbhelper, rdef, creating)
+ sqltype = type_from_rdef(dbhelper, rdef)
if SET_DEFAULT:
default = eschema.default(attr)
if default is not None:
@@ -222,23 +237,19 @@
return sqltype
-def type_from_rdef(dbhelper, rdef, creating=True):
+def type_from_rdef(dbhelper, rdef):
"""return a sql type string corresponding to the relation definition"""
constraints = list(rdef.constraints)
- unique, sqltype = False, None
- for constraint in constraints:
- if isinstance(constraint, UniqueConstraint):
- unique = True
- elif (isinstance(constraint, SizeConstraint)
- and rdef.object.type == 'String'
- and constraint.max is not None):
- size_constrained_string = dbhelper.TYPE_MAPPING.get(
- 'SizeConstrainedString', 'varchar(%s)')
- sqltype = size_constrained_string % constraint.max
+ sqltype = None
+ if rdef.object.type == 'String':
+ for constraint in constraints:
+ if isinstance(constraint, SizeConstraint) and constraint.max is not None:
+ size_constrained_string = dbhelper.TYPE_MAPPING.get(
+ 'SizeConstrainedString', 'varchar(%s)')
+ sqltype = size_constrained_string % constraint.max
+ break
if sqltype is None:
sqltype = sql_type(dbhelper, rdef)
- if creating and unique:
- sqltype += ' UNIQUE'
return sqltype