diff -r 12d226a5bab9 -r 7c565548fb09 cubicweb/server/schema2sql.py --- a/cubicweb/server/schema2sql.py Fri Apr 15 10:20:34 2016 +0200 +++ b/cubicweb/server/schema2sql.py Mon Jun 20 15:04:14 2016 +0200 @@ -1,4 +1,4 @@ -# copyright 2004-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2004-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of cubicweb. @@ -31,6 +31,7 @@ # SET_DEFAULT to True SET_DEFAULT = False + 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) @@ -82,15 +83,18 @@ if not rschema.final and rschema.inlined] return attrs + def unique_index_name(eschema, columns): return u'unique_%s' % md5((eschema.type + - ',' + - ','.join(sorted(columns))).encode('ascii')).hexdigest() + ',' + + ','.join(sorted(columns))).encode('ascii')).hexdigest() + def iter_unique_index_names(eschema): for columns in eschema._unique_together or (): yield columns, unique_index_name(eschema, columns) + def dropeschema2sql(dbhelper, eschema, skip_relations=(), prefix=''): """return sql to drop an entity type's table""" # not necessary to drop indexes, that's implictly done when @@ -100,7 +104,7 @@ tablename = prefix + eschema.type if eschema._unique_together is not None: for columns, index_name in iter_unique_index_names(eschema): - cols = ['%s%s' % (prefix, col) for col in columns] + cols = ['%s%s' % (prefix, col) for col in columns] sqls = dbhelper.sqls_drop_multicol_unique_index(tablename, cols, index_name) statements += sqls statements += ['DROP TABLE %s;' % (tablename)] @@ -120,7 +124,7 @@ if attrschema is not None: sqltype = aschema2sql(dbhelper, eschema, rschema, attrschema, indent=' ') - else: # inline relation + else: # inline relation sqltype = 'integer REFERENCES entities (eid)' if i == len(attrs) - 1: w(' %s%s %s' % (prefix, rschema.type, sqltype)) @@ -132,7 +136,8 @@ attr = rschema.type rdef = rschema.rdef(eschema.type, aschema.type) for constraint in rdef.constraints: - cstrname, check = check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=prefix) + cstrname, check = check_constraint(eschema, aschema, attr, constraint, dbhelper, + prefix=prefix) if cstrname is not None: w(', CONSTRAINT %s CHECK(%s)' % (cstrname, check)) w(');') @@ -142,13 +147,14 @@ if attrschema is None or eschema.rdef(rschema).indexed: w(dbhelper.sql_create_index(table, prefix + rschema.type)) for columns, index_name in iter_unique_index_names(eschema): - cols = ['%s%s' % (prefix, col) for col in columns] + cols = ['%s%s' % (prefix, col) for col in columns] sqls = dbhelper.sqls_create_multicol_unique_index(table, cols, index_name) for sql in sqls: w(sql) w('') return '\n'.join(output) + def as_sql(value, dbhelper, prefix): if isinstance(value, Attribute): return prefix + value.attr @@ -160,6 +166,7 @@ # XXX more quoting for literals? return value + def check_constraint(eschema, aschema, attr, constraint, dbhelper, prefix=''): # XXX should find a better name cstrname = 'cstr' + md5((eschema.type + attr + constraint.type() + @@ -186,6 +193,7 @@ return cstrname, '%s%s IN (%s)' % (prefix, attr, values) return None, None + def aschema2sql(dbhelper, eschema, rschema, aschema, creating=True, indent=''): """write an attribute schema as SQL statements to stdout""" attr = rschema.type @@ -218,15 +226,15 @@ """return a sql type string corresponding to the relation definition""" constraints = list(rdef.constraints) unique, sqltype = False, None - if rdef.object.type == 'String': - for constraint in constraints: - if isinstance(constraint, SizeConstraint): - if constraint.max is not None: - size_constrained_string = dbhelper.TYPE_MAPPING.get( - 'SizeConstrainedString', 'varchar(%s)') - sqltype = size_constrained_string % constraint.max - elif isinstance(constraint, UniqueConstraint): - unique = True + 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 if sqltype is None: sqltype = sql_type(dbhelper, rdef) if creating and unique: