41 |
41 |
42 def uidtype(union, col, etype, args): |
42 def uidtype(union, col, etype, args): |
43 select, col = union.locate_subquery(col, etype, args) |
43 select, col = union.locate_subquery(col, etype, args) |
44 return getattr(select.selection[col], 'uidtype', None) |
44 return getattr(select.selection[col], 'uidtype', None) |
45 |
45 |
|
46 def load_mapping_file(mappingfile): |
|
47 mapping = {} |
|
48 execfile(mappingfile, mapping) |
|
49 for junk in ('__builtins__', '__doc__'): |
|
50 mapping.pop(junk, None) |
|
51 mapping.setdefault('support_relations', {}) |
|
52 mapping.setdefault('dont_cross_relations', set()) |
|
53 mapping.setdefault('cross_relations', set()) |
|
54 |
|
55 # do some basic checks of the mapping content |
|
56 assert 'support_entities' in mapping, \ |
|
57 'mapping file should at least define support_entities' |
|
58 assert isinstance(mapping['support_entities'], dict) |
|
59 assert isinstance(mapping['support_relations'], dict) |
|
60 assert isinstance(mapping['dont_cross_relations'], set) |
|
61 assert isinstance(mapping['cross_relations'], set) |
|
62 unknown = set(mapping) - set( ('support_entities', 'support_relations', |
|
63 'dont_cross_relations', 'cross_relations') ) |
|
64 assert not unknown, 'unknown mapping attribute(s): %s' % unknown |
|
65 # relations that are necessarily not crossed |
|
66 mapping['dont_cross_relations'] |= set(('owned_by', 'created_by')) |
|
67 for rtype in ('is', 'is_instance_of'): |
|
68 assert rtype not in mapping['dont_cross_relations'], \ |
|
69 '%s relation should not be in dont_cross_relations' % rtype |
|
70 assert rtype not in mapping['support_relations'], \ |
|
71 '%s relation should not be in support_relations' % rtype |
|
72 return mapping |
|
73 |
46 |
74 |
47 class ReplaceByInOperator(Exception): |
75 class ReplaceByInOperator(Exception): |
48 def __init__(self, eids): |
76 def __init__(self, eids): |
49 self.eids = eids |
77 self.eids = eids |
50 |
78 |
122 AbstractSource.__init__(self, repo, appschema, source_config, |
150 AbstractSource.__init__(self, repo, appschema, source_config, |
123 *args, **kwargs) |
151 *args, **kwargs) |
124 mappingfile = source_config['mapping-file'] |
152 mappingfile = source_config['mapping-file'] |
125 if not mappingfile[0] == '/': |
153 if not mappingfile[0] == '/': |
126 mappingfile = join(repo.config.apphome, mappingfile) |
154 mappingfile = join(repo.config.apphome, mappingfile) |
127 mapping = {} |
155 mapping = load_mapping_file(mappingfile) |
128 execfile(mappingfile, mapping) |
|
129 self.support_entities = mapping['support_entities'] |
156 self.support_entities = mapping['support_entities'] |
130 self.support_relations = mapping.get('support_relations', {}) |
157 self.support_relations = mapping['support_relations'] |
131 self.dont_cross_relations = set(mapping.get('dont_cross_relations', ())) |
158 self.dont_cross_relations = mapping['dont_cross_relations'] |
132 self.cross_relations = set(mapping.get('cross_relations', ())) |
159 self.cross_relations = mapping['cross_relations'] |
133 self.dont_cross_relations.add('owned_by') |
|
134 self.dont_cross_relations.add('created_by') |
|
135 baseurl = source_config.get('base-url') |
160 baseurl = source_config.get('base-url') |
136 if baseurl and not baseurl.endswith('/'): |
161 if baseurl and not baseurl.endswith('/'): |
137 source_config['base-url'] += '/' |
162 source_config['base-url'] += '/' |
138 self.config = source_config |
163 self.config = source_config |
139 myoptions = (('%s.latest-update-time' % self.uri, |
164 myoptions = (('%s.latest-update-time' % self.uri, |