39 from yams.reader import (CONSTRAINTS, PyFileReader, SchemaLoader, |
39 from yams.reader import (CONSTRAINTS, PyFileReader, SchemaLoader, |
40 obsolete as yobsolete, cleanup_sys_modules, |
40 obsolete as yobsolete, cleanup_sys_modules, |
41 fill_schema_from_namespace) |
41 fill_schema_from_namespace) |
42 |
42 |
43 from rql import parse, nodes, RQLSyntaxError, TypeResolverException |
43 from rql import parse, nodes, RQLSyntaxError, TypeResolverException |
|
44 from rql.analyze import ETypeResolver |
44 |
45 |
45 import cubicweb |
46 import cubicweb |
46 from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized |
47 from cubicweb import ETYPE_NAME_MAP, ValidationError, Unauthorized |
47 |
48 |
48 try: |
49 try: |
1005 super(CubicWebSchema, self).del_entity_type(etype) |
1006 super(CubicWebSchema, self).del_entity_type(etype) |
1006 |
1007 |
1007 def schema_by_eid(self, eid): |
1008 def schema_by_eid(self, eid): |
1008 return self._eid_index[eid] |
1009 return self._eid_index[eid] |
1009 |
1010 |
|
1011 def iter_computed_relations(self): |
|
1012 for relation in self.relations(): |
|
1013 if relation.rule: |
|
1014 yield relation |
|
1015 |
|
1016 def finalize(self): |
|
1017 super(CubicWebSchema, self).finalize() |
|
1018 self.finalize_computed_relations() |
|
1019 |
|
1020 def finalize_computed_relations(self): |
|
1021 """Build relation definitions for computed relations |
|
1022 |
|
1023 The subject and object types are infered using rql analyzer. |
|
1024 """ |
|
1025 analyzer = ETypeResolver(self) |
|
1026 for rschema in self.iter_computed_relations(): |
|
1027 # XXX rule is valid if both S and O are defined and not in an exists |
|
1028 rqlexpr = RRQLExpression(rschema.rule) |
|
1029 rqlst = rqlexpr.snippet_rqlst |
|
1030 analyzer.visit(rqlst) |
|
1031 couples = set((sol['S'], sol['O']) for sol in rqlst.solutions) |
|
1032 for subjtype, objtype in couples: |
|
1033 if self[objtype].final: |
|
1034 raise BadSchemaDefinition('computed relations cannot be final') |
|
1035 rdef = ybo.RelationDefinition( |
|
1036 subjtype, rschema.type, objtype) |
|
1037 rdef.infered = True |
|
1038 self.add_relation_def(rdef) |
|
1039 |
1010 |
1040 |
1011 # additional cw specific constraints ########################################### |
1041 # additional cw specific constraints ########################################### |
1012 |
1042 |
1013 class BaseRQLConstraint(RRQLExpression, BaseConstraint): |
1043 class BaseRQLConstraint(RRQLExpression, BaseConstraint): |
1014 """base class for rql constraints""" |
1044 """base class for rql constraints""" |