# HG changeset patch # User Sylvain Thénault # Date 1467965862 -7200 # Node ID 9c2fbb872e9128932f4e4c923ee60b37728bf5ba # Parent f87da59faea14988e56f40687ef28c33d2c7bf0d [schema] Add a method on yams constraints to compute its unique name used to identify it in the DB backend. diff -r f87da59faea1 -r 9c2fbb872e91 cubicweb/entities/adapters.py --- a/cubicweb/entities/adapters.py Fri Jul 08 10:17:14 2016 +0200 +++ b/cubicweb/entities/adapters.py Fri Jul 08 10:17:42 2016 +0200 @@ -21,7 +21,6 @@ from cubicweb import _ from itertools import chain -from hashlib import md5 from logilab.mtconverter import TransformError from logilab.common.decorators import cached @@ -413,9 +412,7 @@ for rschema, attrschema in eschema.attribute_definitions(): rdef = rschema.rdef(eschema, attrschema) for constraint in rdef.constraints: - if cstrname == 'cstr' + md5( - (eschema.type + rschema.type + constraint.type() + - (constraint.serialize() or '')).encode('ascii')).hexdigest(): + if cstrname == constraint.name_for(rdef): break else: continue diff -r f87da59faea1 -r 9c2fbb872e91 cubicweb/hooks/syncschema.py --- a/cubicweb/hooks/syncschema.py Fri Jul 08 10:17:14 2016 +0200 +++ b/cubicweb/hooks/syncschema.py Fri Jul 08 10:17:42 2016 +0200 @@ -28,7 +28,6 @@ import json from copy import copy -from hashlib import md5 from yams.schema import BASE_TYPES, BadSchemaDefinition, RelationDefinitionSchema from yams.constraints import UniqueConstraint @@ -754,10 +753,11 @@ elif cstrtype == 'UniqueConstraint': syssource.update_rdef_unique(cnx, rdef) self.unique_changed = True - if cstrtype in ('BoundaryConstraint', 'IntervalBoundConstraint', 'StaticVocabularyConstraint'): - cstrname = 'cstr' + md5((rdef.subject.type + rdef.rtype.type + cstrtype + - (self.oldcstr.serialize() or '')).encode('utf-8')).hexdigest() - cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s' % (SQL_PREFIX, rdef.subject.type, cstrname)) + elif cstrtype in ('BoundaryConstraint', + 'IntervalBoundConstraint', + 'StaticVocabularyConstraint'): + cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s' + % (SQL_PREFIX, rdef.subject, self.oldcstr.name_for(rdef))) def revertprecommit_event(self): # revert changes on in memory schema @@ -811,13 +811,12 @@ # oldcstr is the new constraint when the attribute is being added in the same # transaction or when constraint value is updated. So we've to take care... if oldcstr is not None: - oldcstrname = 'cstr' + md5((rdef.subject.type + rdef.rtype.type + cstrtype + - (self.oldcstr.serialize() or '')).encode('utf-8')).hexdigest() + oldcstrname = self.oldcstr.name_for(rdef) if oldcstrname != cstrname: cnx.system_sql('ALTER TABLE %s%s DROP CONSTRAINT %s' - % (SQL_PREFIX, rdef.subject.type, oldcstrname)) + % (SQL_PREFIX, rdef.subject, oldcstrname)) cnx.system_sql('ALTER TABLE %s%s ADD CONSTRAINT %s CHECK(%s)' % - (SQL_PREFIX, rdef.subject.type, cstrname, check)) + (SQL_PREFIX, rdef.subject, cstrname, check)) class CWUniqueTogetherConstraintAddOp(MemSchemaOperation): diff -r f87da59faea1 -r 9c2fbb872e91 cubicweb/schema.py --- a/cubicweb/schema.py Fri Jul 08 10:17:14 2016 +0200 +++ b/cubicweb/schema.py Fri Jul 08 10:17:42 2016 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -22,6 +22,7 @@ import re from os.path import join, basename +from hashlib import md5 from logging import getLogger from warnings import warn @@ -1145,6 +1146,16 @@ # additional cw specific constraints ########################################### +@monkeypatch(BaseConstraint) +def name_for(self, rdef): + """Return a unique, size controlled, name for this constraint applied to given `rdef`. + + This name may be used as name for the constraint in the database. + """ + return 'cstr' + md5((rdef.subject.type + rdef.rtype.type + self.type() + + (self.serialize() or '')).encode('ascii')).hexdigest() + + class BaseRQLConstraint(RRQLExpression, BaseConstraint): """base class for rql constraints""" distinct_query = None diff -r f87da59faea1 -r 9c2fbb872e91 cubicweb/server/schema2sql.py --- a/cubicweb/server/schema2sql.py Fri Jul 08 10:17:14 2016 +0200 +++ b/cubicweb/server/schema2sql.py Fri Jul 08 10:17:42 2016 +0200 @@ -168,11 +168,8 @@ """Return (constraint name, constraint SQL definition) for the given relation definition's constraint. Maybe (None, None) if the constraint is not handled in the backend. """ - eschema = rdef.subject attr = rdef.rtype.type - # XXX should find a better name - cstrname = 'cstr' + md5((eschema.type + attr + constraint.type() + - (constraint.serialize() or '')).encode('ascii')).hexdigest() + cstrname = constraint.name_for(rdef) if constraint.type() == 'BoundaryConstraint': value = constraint_value_as_sql(constraint.boundary, dbhelper, prefix) return cstrname, '%s%s %s %s' % (prefix, attr, constraint.operator, value) diff -r f87da59faea1 -r 9c2fbb872e91 cubicweb/server/test/unittest_migractions.py --- a/cubicweb/server/test/unittest_migractions.py Fri Jul 08 10:17:14 2016 +0200 +++ b/cubicweb/server/test/unittest_migractions.py Fri Jul 08 10:17:42 2016 +0200 @@ -602,9 +602,7 @@ self.assertEqual(len(constraints), 1, constraints) rdef = migrschema['promo'].rdefs['Personne', 'String'] cstr = rdef.constraint_by_type('StaticVocabularyConstraint') - cstrname = 'cstr' + md5((rdef.subject.type + rdef.rtype.type + cstr.type() + - (cstr.serialize() or '')).encode('ascii')).hexdigest() - self.assertIn(cstrname, constraints) + self.assertIn(cstr.name_for(rdef), constraints) def _erqlexpr_rset(self, cnx, action, ertype): rql = 'RQLExpression X WHERE ET is CWEType, ET %s_permission X, ET name %%(name)s' % action