# HG changeset patch # User Sylvain Thénault # Date 1254490288 -7200 # Node ID 26e586f3c15c3f52977241a4ec305bfe2a129242 # Parent 76b4a177a018e2e29268aa2b87a635a47698074e [schema] make RQL* constraints usable w/ attributes diff -r 76b4a177a018 -r 26e586f3c15c schema.py --- a/schema.py Fri Oct 02 14:22:23 2009 +0200 +++ b/schema.py Fri Oct 02 15:31:28 2009 +0200 @@ -557,11 +557,6 @@ def __init__(self, restriction): self.restriction = restriction - def check_consistency(self, subjschema, objschema, rdef): - if objschema.is_final(): - raise BadSchemaDefinition("unique constraint doesn't apply to " - "final entity type") - def serialize(self): return self.restriction @@ -577,7 +572,7 @@ def repo_check(self, session, eidfrom, rtype, eidto): """raise ValidationError if the relation doesn't satisfy the constraint """ - pass # this is a vocabulary constraint, not enforce + pass # this is a vocabulary constraint, not enforce XXX why? def __str__(self): return self.restriction @@ -591,13 +586,17 @@ are also enforced at the repository level """ def exec_query(self, session, eidfrom, eidto): + if eidto is None: + rql = 'Any S WHERE S eid %(s)s, ' + self.restriction + return session.unsafe_execute(rql, {'s': eidfrom}, 's', + build_descr=False) rql = 'Any S,O WHERE S eid %(s)s, O eid %(o)s, ' + self.restriction return session.unsafe_execute(rql, {'s': eidfrom, 'o': eidto}, ('s', 'o'), build_descr=False) def error(self, eid, rtype, msg): raise ValidationError(eid, {rtype: msg}) - def repo_check(self, session, eidfrom, rtype, eidto): + def repo_check(self, session, eidfrom, rtype, eidto=None): """raise ValidationError if the relation doesn't satisfy the constraint """ if not self.exec_query(session, eidfrom, eidto): @@ -610,7 +609,7 @@ """the unique rql constraint check that the result of the query isn't greater than one """ - def repo_check(self, session, eidfrom, rtype, eidto): + def repo_check(self, session, eidfrom, rtype, eidto=None): """raise ValidationError if the relation doesn't satisfy the constraint """ if len(self.exec_query(session, eidfrom, eidto)) > 1: diff -r 76b4a177a018 -r 26e586f3c15c server/hooks.py --- a/server/hooks.py Fri Oct 02 14:22:23 2009 +0200 +++ b/server/hooks.py Fri Oct 02 15:31:28 2009 +0200 @@ -11,7 +11,7 @@ from datetime import datetime from cubicweb import UnknownProperty, ValidationError, BadConnectionId - +from cubicweb.schema import RQLVocabularyConstraint from cubicweb.server.pool import Operation, LateOperation, PreCommitOperation from cubicweb.server.hookhelper import (check_internal_entity, get_user_sessions, rproperty) @@ -241,6 +241,16 @@ msg = session._('the value "%s" is already used, use another one') raise ValidationError(entity.eid, {attr: msg % val}) +def cstrcheck_after_update_attributes(session, entity): + schema = session.vreg.schema + for attr in entity.edited_attributes: + if schema.rschema(attr).is_final(): + constraints = [c for c in entity.e_schema.constraints(attr) + if isinstance(c, RQLVocabularyConstraint)] + if constraints: + CheckConstraintsOperation(session, rdef=(entity.eid, attr, None), + constraints=constraints) + class CheckRequiredRelationOperation(LateOperation): """checking relation cardinality has to be done after commit in @@ -334,7 +344,8 @@ hm.register_hook(cstrcheck_after_add_relation, 'after_add_relation', '') hm.register_hook(uniquecstrcheck_before_modification, 'before_add_entity', '') hm.register_hook(uniquecstrcheck_before_modification, 'before_update_entity', '') - + hm.register_hook(cstrcheck_after_update_attributes, 'after_add_entity', '') + hm.register_hook(cstrcheck_after_update_attributes, 'after_update_entity', '') # user/groups synchronisation #################################################