parent_deletes,
child_deletes,
after_save,
- before_delete)
+ before_delete
+ )
def per_state_flush_actions(self, uow, states, isdelete):
"""
+ parent_base_mapper = self.parent.primary_base_mapper
+ child_base_mapper = self.mapper.primary_base_mapper
+ child_saves = unitofwork.SaveUpdateAll(uow, child_base_mapper)
+ child_deletes = unitofwork.DeleteAll(uow, child_base_mapper)
+
# locate and disable the aggregate processors
# for this dependency
# check if the "child" side is part of the cycle
- parent_base_mapper = self.parent.primary_base_mapper
- child_base_mapper = self.mapper.primary_base_mapper
- child_saves = unitofwork.SaveUpdateAll(uow, child_base_mapper)
- child_deletes = unitofwork.DeleteAll(uow, child_base_mapper)
-
if child_saves not in uow.cycles:
# based on the current dependencies we use, the saves/
# deletes should always be in the 'cycles' collection
# establish dependencies between our possibly per-state
# parent action and our possibly per-state child action.
- for (child_action, childisdelete) in child_actions:
+ for child_action, childisdelete in child_actions:
self.per_state_dependencies(uow, parent_saves,
parent_deletes,
child_action,
set
)
- def _post_update(self, state, uowcommit, related, processed):
+ def _post_update(self, state, uowcommit, related, processed, immediate):
if processed is not None and state in processed:
return
for x in related:
if x is not None:
uowcommit.issue_post_update(
state,
- [r for l, r in self.prop.synchronize_pairs]
+ [r for l, r in self.prop.synchronize_pairs],
+ immediate
)
if processed is not None:
processed.add(state)
parent_deletes,
child_deletes,
after_save,
- before_delete):
+ before_delete,
+ ):
if self.post_update:
+
uow.dependencies.update([
(child_saves, after_save),
(parent_saves, after_save),
(before_delete, parent_deletes),
(before_delete, child_deletes),
+
])
else:
uow.dependencies.update([
isdelete, childisdelete):
if self.post_update:
+
# TODO: this whole block is not covered
# by any tests
if not isdelete:
if childisdelete:
uow.dependencies.update([
(save_parent, after_save),
- (after_save, child_action)
+ (after_save, child_action),
])
else:
uow.dependencies.update([
(save_parent, after_save),
- (child_action, after_save)
+ (child_action, after_save),
])
else:
if childisdelete:
uow.dependencies.update([
(before_delete, delete_parent),
- (before_delete, child_action)
+ (before_delete, child_action),
])
else:
uow.dependencies.update([
- (before_delete, delete_parent),
- (child_action, before_delete)
+ (before_delete, delete_parent),
+ (child_action, before_delete),
])
elif not isdelete:
uow.dependencies.update([
self._post_update(
child,
uowcommit,
- [state], processed)
+ [state], processed, True)
if self.post_update or not self.cascade.delete:
for child in set(history.unchanged).\
difference(children_added):
self._post_update(
child,
uowcommit,
- [state], processed)
+ [state], processed, True)
# technically, we can even remove each child from the
# collection here too. but this would be a somewhat
# inconsistent behavior since it wouldn't happen if the old
child,
uowcommit,
[state],
- processed
+ processed,
+ True
)
for child in history.deleted:
before_delete):
if self.post_update:
+ child_post_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, False)
+ child_pre_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, True)
+
uow.dependencies.update([
(child_saves, after_save),
(parent_saves, after_save),
(before_delete, parent_deletes),
(before_delete, child_deletes),
+ (after_save, child_post_updates),
+ (before_delete, child_pre_updates),
+ (child_pre_updates, child_deletes),
])
else:
uow.dependencies.update([
isdelete, childisdelete):
if self.post_update:
+
if not isdelete:
+ child_post_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, False)
if childisdelete:
uow.dependencies.update([
(save_parent, after_save),
- (after_save, child_action)
+ (after_save, child_action), # can remove
+
+ (after_save, child_post_updates),
+ (child_post_updates, child_action)
])
else:
uow.dependencies.update([
(save_parent, after_save),
- (child_action, after_save)
+ (child_action, after_save),
+
+ (after_save, child_post_updates)
])
else:
+ child_pre_updates = unitofwork.PostUpdateThing(
+ uow, self.parent.primary_base_mapper, True)
+
uow.dependencies.update([
- (before_delete, delete_parent),
- (before_delete, child_action)
+ (before_delete, delete_parent), # can remove
+ (before_delete, child_action), # can remove
+
+ (before_delete, child_pre_updates),
+ (child_pre_updates, delete_parent),
+ (child_pre_updates, child_action)
])
elif not isdelete:
self._post_update(
state,
uowcommit,
- history.sum(), processed)
+ history.sum(), processed, False)
def process_saves(self, uowcommit, states):
if self.post_update:
if self.post_update:
self._post_update(
state,
- uowcommit, history.sum(), processed)
+ uowcommit, history.sum(), processed, False)
def _synchronize(self, state, child, associationrow, clearkeys, uowcommit):
if state is None or (not self.post_update and uowcommit.is_deleted(state)):
parent_deletes,
child_deletes,
after_save,
- before_delete):
+ before_delete
+ ):
uow.dependencies.update([
(parent_saves, after_save),
# or insert/updated, or just refreshed
self.states = {}
+ self.post_update_states = util.defaultdict(set)
+
@property
def has_work(self):
return bool(self.states)
if not listonly and (isdelete or cancel_delete):
self.states[state] = (isdelete, False)
- def issue_post_update(self, state, post_update_cols):
- mapper = state.manager.mapper.base_mapper
- mapper._save_obj([state], self, \
- postupdate=True, \
- post_update_cols=set(post_update_cols))
+ def issue_post_update(self, state, post_update_cols, immediate):
+ if immediate:
+ mapper = state.manager.mapper.base_mapper
+ mapper._save_obj([state], self, \
+ postupdate=True, \
+ post_update_cols=set(post_update_cols))
+ else:
+ self.post_update_states[state].update(post_update_cols)
@util.memoized_property
def _mapper_for_dep(self):
def execute(self):
postsort_actions = self._generate_actions()
- #sort = topological.sort(self.dependencies, postsort_actions)
+ sort = topological.sort(self.dependencies, postsort_actions)
#print "--------------"
#print self.dependencies
- #print list(sort)
+ print list(sort)
#print "COUNT OF POSTSORT ACTIONS", len(postsort_actions)
# execute
(isdelete, listonly) = uow.states[state]
if isdelete == self.delete and not listonly:
yield state
-
+
+class PostUpdateThing(PostSortRec):
+ def __init__(self, uow, mapper, isdelete):
+ self.mapper = mapper
+ self.isdelete = isdelete
+
+ def execute(self, uow):
+ states = []
+ update_cols = set()
+
+ for state in uow.states_for_mapper_hierarchy(self.mapper, self.isdelete, False):
+ if state not in uow.post_update_states:
+ continue
+ states.append(state)
+ update_cols.update(uow.post_update_states[state])
+
+ self.mapper._save_obj(states, uow, \
+ postupdate=True, \
+ post_update_cols=update_cols)
+
class SaveUpdateAll(PostSortRec):
def __init__(self, uow, mapper):
self.mapper = mapper