117 with security_enabled(session, read=False): |
117 with security_enabled(session, read=False): |
118 session.execute('DELETE X %s Y WHERE Y eid %%(y)s, ' |
118 session.execute('DELETE X %s Y WHERE Y eid %%(y)s, ' |
119 'NOT X eid %%(x)s' % rtype, |
119 'NOT X eid %%(x)s' % rtype, |
120 {'x': eidfrom, 'y': eidto}) |
120 {'x': eidfrom, 'y': eidto}) |
121 |
121 |
|
122 |
|
123 def preprocess_inlined_relations(session, entity): |
|
124 """when an entity is added, check if it has some inlined relation which |
|
125 requires to be extrated for proper call hooks |
|
126 """ |
|
127 relations = [] |
|
128 activeintegrity = session.is_hook_category_activated('activeintegrity') |
|
129 eschema = entity.e_schema |
|
130 for attr in entity.cw_edited.iterkeys(): |
|
131 rschema = eschema.subjrels[attr] |
|
132 if not rschema.final: # inlined relation |
|
133 value = entity.cw_edited[attr] |
|
134 relations.append((attr, value)) |
|
135 session.update_rel_cache_add(entity.eid, attr, value) |
|
136 rdef = session.rtype_eids_rdef(attr, entity.eid, value) |
|
137 if rdef.cardinality[1] in '1?' and activeintegrity: |
|
138 with security_enabled(session, read=False): |
|
139 session.execute('DELETE X %s Y WHERE Y eid %%(y)s' % attr, |
|
140 {'x': entity.eid, 'y': value}) |
|
141 return relations |
122 |
142 |
123 |
143 |
124 class NullEventBus(object): |
144 class NullEventBus(object): |
125 def publish(self, msg): |
145 def publish(self, msg): |
126 pass |
146 pass |
1351 """ |
1371 """ |
1352 entity = edited.entity |
1372 entity = edited.entity |
1353 entity._cw_is_saved = False # entity has an eid but is not yet saved |
1373 entity._cw_is_saved = False # entity has an eid but is not yet saved |
1354 # init edited_attributes before calling before_add_entity hooks |
1374 # init edited_attributes before calling before_add_entity hooks |
1355 entity.cw_edited = edited |
1375 entity.cw_edited = edited |
1356 eschema = entity.e_schema |
|
1357 source = self.locate_etype_source(entity.__regid__) |
1376 source = self.locate_etype_source(entity.__regid__) |
1358 # allocate an eid to the entity before calling hooks |
1377 # allocate an eid to the entity before calling hooks |
1359 entity.eid = self.system_source.create_eid(session) |
1378 entity.eid = self.system_source.create_eid(session) |
1360 # set caches asap |
1379 # set caches asap |
1361 extid = self.init_entity_caches(session, entity, source) |
1380 extid = self.init_entity_caches(session, entity, source) |
1362 if server.DEBUG & server.DBG_REPO: |
1381 if server.DEBUG & server.DBG_REPO: |
1363 print 'ADD entity', self, entity.__regid__, entity.eid, edited |
1382 print 'ADD entity', self, entity.__regid__, entity.eid, edited |
1364 prefill_entity_caches(entity) |
1383 prefill_entity_caches(entity) |
1365 if source.should_call_hooks: |
1384 if source.should_call_hooks: |
1366 self.hm.call_hooks('before_add_entity', session, entity=entity) |
1385 self.hm.call_hooks('before_add_entity', session, entity=entity) |
1367 relations = [] |
1386 relations = preprocess_inlined_relations(session, entity) |
1368 activeintegrity = session.is_hook_category_activated('activeintegrity') |
|
1369 for attr in edited.iterkeys(): |
|
1370 rschema = eschema.subjrels[attr] |
|
1371 if not rschema.final: # inlined relation |
|
1372 value = edited[attr] |
|
1373 relations.append((attr, value)) |
|
1374 session.update_rel_cache_add(entity.eid, attr, value) |
|
1375 rdef = session.rtype_eids_rdef(attr, entity.eid, value) |
|
1376 if rdef.cardinality[1] in '1?' and activeintegrity: |
|
1377 with security_enabled(session, read=False): |
|
1378 session.execute('DELETE X %s Y WHERE Y eid %%(y)s' % attr, |
|
1379 {'x': entity.eid, 'y': value}) |
|
1380 edited.set_defaults() |
1387 edited.set_defaults() |
1381 if session.is_hook_category_activated('integrity'): |
1388 if session.is_hook_category_activated('integrity'): |
1382 edited.check(creation=True) |
1389 edited.check(creation=True) |
1383 try: |
1390 try: |
1384 source.add_entity(session, entity) |
1391 source.add_entity(session, entity) |