# HG changeset patch # User Sylvain Thénault # Date 1467285996 -7200 # Node ID 5be298ed4caa3a36be87592db7cedda13fafaf7d # Parent e6acdea9616c86a77b8571981aa50b078d7e3f89 [schema2sql] More docstrings and minor API improvements Along the way, renamed local `column` variable to `attr` where we're NOT manipulating a DB column name but a schema attribute. Related to #14050899 diff -r e6acdea9616c -r 5be298ed4caa cubicweb/server/schema2sql.py --- a/cubicweb/server/schema2sql.py Thu Jun 30 10:47:03 2016 +0200 +++ b/cubicweb/server/schema2sql.py Thu Jun 30 13:26:36 2016 +0200 @@ -53,13 +53,16 @@ def build_index_name(table, columns, prefix='idx_'): + """Return a predictable-but-size-constrained name for an index on `table(*columns)`, using an + md5 hash. + """ return '%s%s' % (prefix, md5((table + ',' + ','.join(sorted(columns))).encode('ascii')).hexdigest()) def rschema_has_table(rschema, skip_relations): - """Return True if the given schema should have a table in the database""" + """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) @@ -101,16 +104,22 @@ return '\n'.join(output) -def unique_index_name(eschema, columns): +def unique_index_name(eschema, attrs): + """Return a predictable-but-size-constrained name for a multi-columns unique index on + given attributes of the entity schema (actually, the later may be a schema or a string). + """ # keep giving eschema instead of table name for bw compat table = text_type(eschema) # unique_index_name is used as name of CWUniqueConstraint, hence it should be unicode - return text_type(build_index_name(table, columns, 'unique_')) + return text_type(build_index_name(table, attrs, 'unique_')) def iter_unique_index_names(eschema): - for columns in eschema._unique_together or (): - yield columns, unique_index_name(eschema, columns) + """Yield (attrs, index name) where attrs is a list of entity type's attribute names that should + be unique together, and index name the unique index name. + """ + for attrs in eschema._unique_together or (): + yield attrs, unique_index_name(eschema, attrs) def dropeschema2sql(dbhelper, eschema, skip_relations=(), prefix=''): @@ -121,10 +130,10 @@ statements = [] 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] - sqls = dbhelper.sqls_drop_multicol_unique_index(tablename, cols, index_name) - statements += sqls + for attrs, index_name in iter_unique_index_names(eschema): + cols = ['%s%s' % (prefix, attr) for attr in attrs] + for sql in dbhelper.sqls_drop_multicol_unique_index(tablename, cols, index_name): + yield sql statements += ['DROP TABLE %s;' % (tablename)] return statements @@ -169,9 +178,9 @@ 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) + for attrs, index_name in iter_unique_index_names(eschema): + columns = ['%s%s' % (prefix, attr) for attr in attrs] + sqls = dbhelper.sqls_create_multicol_unique_index(table, columns, index_name) for sql in sqls: w(sql) w('') @@ -179,6 +188,9 @@ def as_sql(value, dbhelper, prefix): + """Return the SQL value from a Yams constraint's value, handling special cases where it's a + `Attribute`, `TODAY` or `NOW` instance instead of a literal value. + """ if isinstance(value, Attribute): return prefix + value.attr elif isinstance(value, TODAY): @@ -223,7 +235,7 @@ def aschema2sql(dbhelper, eschema, rschema, aschema, creating=True, indent=''): - """write an attribute schema as SQL statements to stdout""" + """Return string containing a SQL table's column definition from attribute schema.""" attr = rschema.type rdef = rschema.rdef(eschema.type, aschema.type) sqltype = type_from_rdef(dbhelper, rdef) @@ -251,7 +263,7 @@ def type_from_rdef(dbhelper, rdef): - """return a sql type string corresponding to the relation definition""" + """Return a string containing SQL type name for the given relation definition.""" constraints = list(rdef.constraints) sqltype = None if rdef.object.type == 'String': @@ -267,6 +279,8 @@ def sql_type(dbhelper, rdef): + """Return a string containing SQL type to use to store values of the given relation definition. + """ sqltype = dbhelper.TYPE_MAPPING[rdef.object] if callable(sqltype): sqltype = sqltype(rdef)