Changeset 3266
- Timestamp:
- 05/29/07 19:52:59 (1 year ago)
- Files:
-
- trunk/Schevo/schevo/transaction.py (modified) (5 diffs)
- trunk/Schevo/tests/test_on_delete.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Schevo/schevo/transaction.py
r3254 r3266 376 376 377 377 378 def find_chains(entity): 379 db = entity.sys.db 380 traversed = set() 381 chains = [] 382 _find_chains(db, entity, traversed, chains) 383 return chains 384 385 386 def _find_chains(db, entity, traversed, chains, chain=None): 387 if chain is None: 388 chain = [] 389 chain.append(entity) 390 if entity in traversed: 391 chains.append(chain) 392 return 393 traversed.add(entity) 394 entity_extent_name = entity._extent.name 395 for (e_name, f_name), others in entity.sys.links().iteritems(): 396 extent = db.extent(e_name) 397 for referrer in others: 398 _find_chains(db, referrer, traversed, chains, chain) 399 400 378 401 class Delete(Transaction): 379 402 """Delete an existing entity instance.""" … … 414 437 'Original entity revision was %i, is now %i' 415 438 % (self._rev, entity._rev)) 439 deletes = self._deletes 416 440 # Before execute callback. 417 441 self._before_execute(db, entity) … … 427 451 # also requesting cascade deletion. 428 452 restricter_keys = set(restricters) - set(cascaders) 453 # Starting at the entity whose deletion is requested, find 454 # chains of circular references that contain that entity, and 455 # make sure they are not in the restricters. 456 chains = find_chains(entity) 457 for chain in chains: 458 if chain[0] == entity and chain[0] == chain[-1]: 459 chain = frozenset(chain) 460 for referrer, restricter_set in restricters.iteritems(): 461 for f_name, referred in frozenset(restricter_set): 462 if referred in chain: 463 restricter_set.remove((f_name, referred)) 464 if len(restricter_set) == 0: 465 restricter_keys.discard(referrer) 429 466 if len(restricter_keys) != 0: 430 467 # Raise DeleteRestricted if there are any restricters left … … 486 523 referrers.add((extent_name, oid, referrer)) 487 524 # Delete entities in a deterministic (sorted) fashion. 525 deletes.add((entity.__class__, entity._oid)) 488 526 for extent_name, oid, referrer in sorted(referrers): 489 if referrer == entity: 527 referrer_e_o = referrer.__class__, referrer._oid 528 if referrer_e_o in deletes: 490 529 # Skip the original entity whose deletion was 491 530 # requested, since we must delete it using a call to 492 # the database's `_delete_entity` method. 531 # the database's `_delete_entity` method. Also skip 532 # any entity that has already been deleted. 493 533 continue 494 534 if not db._extent_contains_oid(extent_name, oid): … … 497 537 continue 498 538 tx = referrer.t.delete() 539 tx._deletes.update(deletes) 499 540 db.execute(tx, strict=False) 500 541 # Attempt to delete the entity itself. trunk/Schevo/tests/test_on_delete.py
r3262 r3266 131 131 132 132 bam = f.entity('Bam') 133 134 135 # ---------------------------------------------------------------- 133 136 134 137
