diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-04-01 13:19:14 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2010-04-01 13:19:14 -0400 |
commit | bef05275aa5410b14ef5fd70c0677b6ea48e168e (patch) | |
tree | 42bd5245fcb9e735de6f0ad2c2bd6c81b41baabc /lib/sqlalchemy/orm/unitofwork.py | |
parent | cc8ec5ab78046379ddc5874605692a5853fc65f8 (diff) | |
download | sqlalchemy-bef05275aa5410b14ef5fd70c0677b6ea48e168e.tar.gz |
self-referential working to a small degree
Diffstat (limited to 'lib/sqlalchemy/orm/unitofwork.py')
-rw-r--r-- | lib/sqlalchemy/orm/unitofwork.py | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 65d85a37b..d2f5946df 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -167,20 +167,30 @@ class UOWTransaction(object): break self.cycles = cycles = topological.find_cycles(self.dependencies, self.postsort_actions.values()) - assert not cycles - for rec in cycles: - rec.per_state_flush_actions(self) + + if cycles: + convert = {} + for rec in cycles: + convert[rec] = set(rec.per_state_flush_actions(self)) for edge in list(self.dependencies): - # both nodes in this edge were part of a cycle. - # remove that from our deps as it has replaced - # itself with per-state actions + # remove old dependencies between two cycle nodes, + # splice dependencies for dependencies from/to cycle + # nodes from non-cycle nodes if cycles.issuperset(edge): self.dependencies.remove(edge) + elif edge[0] in cycles: + for dep in convert[edge[0]]: + self.dependencies.add((dep, edge[1])) + elif edge[1] in cycles: + for dep in convert[edge[1]]: + self.dependencies.add((edge[0], dep)) sort = topological.sort(self.dependencies, self.postsort_actions.values()) print sort for rec in sort: + if rec in cycles: + continue rec.execute(self) @@ -286,10 +296,11 @@ class ProcessAll(PropertyRecMixin, PostSortRec): def per_state_flush_actions(self, uow): for state in self._elements(uow): if self.delete: - self.dependency_processor.per_deleted_state_flush_actions(uow, self.dependency_processor, state) + self.dependency_processor.per_deleted_state_flush_actions(uow, state) else: - self.dependency_processor.per_saved_state_flush_actions(uow, self.dependency_processor, state) - + self.dependency_processor.per_saved_state_flush_actions(uow, state) + return iter([]) + class SaveUpdateAll(PostSortRec): def __init__(self, uow, mapper): self.mapper = mapper @@ -302,7 +313,7 @@ class SaveUpdateAll(PostSortRec): def per_state_flush_actions(self, uow): for state in uow.states_for_mapper_hierarchy(self.mapper, False, False): - SaveUpdateState(uow, state) + yield SaveUpdateState(uow, state) class DeleteAll(PostSortRec): def __init__(self, uow, mapper): @@ -316,20 +327,39 @@ class DeleteAll(PostSortRec): def per_state_flush_actions(self, uow): for state in uow.states_for_mapper_hierarchy(self.mapper, True, False): - DeleteState(uow, state) + yield DeleteState(uow, state) class ProcessState(PostSortRec): def __init__(self, uow, dependency_processor, delete, state): self.dependency_processor = dependency_processor self.delete = delete self.state = state + + def execute(self, uow): + if self.delete: + self.dependency_processor.process_deletes(uow, [self.state]) + else: + self.dependency_processor.process_saves(uow, [self.state]) class SaveUpdateState(PostSortRec): def __init__(self, uow, state): self.state = state + def execute(self, uow): + mapper = self.state.manager.mapper.base_mapper + mapper._save_obj( + [self.state], + uow + ) + class DeleteState(PostSortRec): def __init__(self, uow, state): self.state = state + def execute(self, uow): + mapper = self.state.manager.mapper.base_mapper + mapper._delete_obj( + [self.state], + uow + ) |