14 |
14 |
15 from cubicweb.server.pool import Operation, LateOperation, PreCommitOperation |
15 from cubicweb.server.pool import Operation, LateOperation, PreCommitOperation |
16 from cubicweb.server.hookhelper import (check_internal_entity, previous_state, |
16 from cubicweb.server.hookhelper import (check_internal_entity, previous_state, |
17 get_user_sessions, rproperty) |
17 get_user_sessions, rproperty) |
18 from cubicweb.server.repository import FTIndexEntityOp |
18 from cubicweb.server.repository import FTIndexEntityOp |
|
19 |
|
20 # special relations that don't have to be checked for integrity, usually |
|
21 # because they are handled internally by hooks (so we trust ourselves) |
|
22 DONT_CHECK_RTYPES_ON_ADD = set(('owned_by', 'created_by', |
|
23 'is', 'is_instance_of', |
|
24 'wf_info_for', 'from_state', 'to_state')) |
|
25 DONT_CHECK_RTYPES_ON_DEL = set(('is', 'is_instance_of', |
|
26 'wf_info_for', 'from_state', 'to_state')) |
|
27 |
19 |
28 |
20 def relation_deleted(session, eidfrom, rtype, eidto): |
29 def relation_deleted(session, eidfrom, rtype, eidto): |
21 session.transaction_data.setdefault('pendingrelations', []).append( |
30 session.transaction_data.setdefault('pendingrelations', []).append( |
22 (eidfrom, rtype, eidto)) |
31 (eidfrom, rtype, eidto)) |
23 |
32 |
278 def cardinalitycheck_after_add_entity(session, entity): |
287 def cardinalitycheck_after_add_entity(session, entity): |
279 """check cardinalities are satisfied""" |
288 """check cardinalities are satisfied""" |
280 eid = entity.eid |
289 eid = entity.eid |
281 for rschema, targetschemas, x in entity.e_schema.relation_definitions(): |
290 for rschema, targetschemas, x in entity.e_schema.relation_definitions(): |
282 # skip automatically handled relations |
291 # skip automatically handled relations |
283 if rschema.type in ('owned_by', 'created_by', 'is', 'is_instance_of'): |
292 if rschema.type in DONT_CHECK_RTYPES_ON_ADD: |
284 continue |
293 continue |
285 if x == 'subject': |
294 if x == 'subject': |
286 subjtype = entity.e_schema |
295 subjtype = entity.e_schema |
287 objtype = targetschemas[0].type |
296 objtype = targetschemas[0].type |
288 cardindex = 0 |
297 cardindex = 0 |
297 checkrel_if_necessary(session, opcls, rschema.type, eid) |
306 checkrel_if_necessary(session, opcls, rschema.type, eid) |
298 |
307 |
299 |
308 |
300 def cardinalitycheck_before_del_relation(session, eidfrom, rtype, eidto): |
309 def cardinalitycheck_before_del_relation(session, eidfrom, rtype, eidto): |
301 """check cardinalities are satisfied""" |
310 """check cardinalities are satisfied""" |
|
311 if rtype in DONT_CHECK_RTYPES_ON_DEL: |
|
312 return |
302 card = rproperty(session, rtype, eidfrom, eidto, 'cardinality') |
313 card = rproperty(session, rtype, eidfrom, eidto, 'cardinality') |
303 pendingeids = session.transaction_data.get('pendingeids', ()) |
314 pendingeids = session.transaction_data.get('pendingeids', ()) |
304 if card[0] in '1+' and not eidfrom in pendingeids: |
315 if card[0] in '1+' and not eidfrom in pendingeids: |
305 checkrel_if_necessary(session, CheckSRelationOp, rtype, eidfrom) |
316 checkrel_if_necessary(session, CheckSRelationOp, rtype, eidfrom) |
306 if card[1] in '1+' and not eidto in pendingeids: |
317 if card[1] in '1+' and not eidto in pendingeids: |