"""
- # TODO: this check sucks. somehow get mapper to
- # not even call this.
- if ('has_flush_activity', self) not in uow.attributes:
- return
+ # assertions to ensure this method isn't being
+ # called unnecessarily. can comment these out when
+ # code is stable
+ assert ('has_flush_activity', self) in uow.attributes
+ assert not self.post_update or not self._check_reverse(uow)
- # TODO: why are we calling this ? shouldnt per_property
- # have stopped us from getting keyhere ?
- if self.post_update and self._check_reverse(uow):
- # TODO: coverage here
- return
# locate and disable the aggregate processors
# for this dependency
for prop in self._props.values():
prop.per_property_flush_actions(uow)
- def _property_iterator(self, mappers):
- """return an iterator of all MapperProperty objects
- and a list containing all mappers which use that property,
- descending through the polymorphic hierarchy of this
- mapper.
-
- 'mappers' is a set which will limit the traversal
- to just those mappers.
-
- """
- props = set()
- for mapper in self.polymorphic_iterator():
- if mapper not in mappers:
- continue
-
- for prop in mapper._props.values():
- if prop not in props:
- props.add(prop)
- yield prop, [m for m in mappers
- if m._props.get(prop.key) is prop]
-
def _per_state_flush_actions(self, uow, states, isdelete):
- mappers_to_states = util.defaultdict(set)
-
base_mapper = self.base_mapper
save_all = unitofwork.SaveUpdateAll(uow, base_mapper)
delete_all = unitofwork.DeleteAll(uow, base_mapper)
action = unitofwork.SaveUpdateState(uow, state, base_mapper)
uow.dependencies.add((action, delete_all))
- mappers_to_states[state.manager.mapper].add(state)
yield action
- # TODO: can't we just loop through the frigging entries
- # that are already in the uow instead of this goofy
- # polymorphic BS ?
- for prop, mappers in self._property_iterator(set(mappers_to_states)):
- states_for_prop = []
- for mapper in mappers:
- states_for_prop += list(mappers_to_states[mapper])
-
- prop.per_state_flush_actions(uow, states_for_prop, isdelete)
-
def _save_obj(self, states, uowtransaction, postupdate=False,
post_update_cols=None, single=False):
"""Issue ``INSERT`` and/or ``UPDATE`` statements for a list of objects.
# information.
self.attributes = {}
+ self.deps = util.defaultdict(set)
self.mappers = util.defaultdict(set)
self.presort_actions = {}
self.postsort_actions = {}
postupdate=True, \
post_update_cols=set(post_update_cols))
+ @util.memoized_property
+ def _mapper_for_dep(self):
+ return util.PopulateDict(
+ lambda tup:tup[0]._props.get(tup[1].key) is tup[1].prop
+ )
+
+ def filter_states_for_dep(self, dep, states):
+ mapper_for_dep = self._mapper_for_dep
+ return [s for s in states if mapper_for_dep[(s.manager.mapper, dep)]]
+
def states_for_mapper(self, mapper, isdelete, listonly):
checktup = (isdelete, listonly)
for state in self.mappers[mapper]:
return False
class ProcessAll(PropertyRecMixin, PostSortRec):
+ def __init__(self, uow, *args):
+ super(ProcessAll, self).__init__(uow, *args)
+ uow.deps[self.dependency_processor.parent.base_mapper].add(self.dependency_processor)
+
def execute(self, uow):
states = list(self._elements(uow))
if self.delete:
)
def per_state_flush_actions(self, uow):
+ states = list(uow.states_for_mapper_hierarchy(self.mapper, False, False))
for rec in self.mapper._per_state_flush_actions(
uow,
- uow.states_for_mapper_hierarchy(self.mapper, False, False),
+ states,
False):
yield rec
+
+ for dep in uow.deps[self.mapper]:
+ states_for_prop = uow.filter_states_for_dep(dep, states)
+ dep.per_state_flush_actions(uow, states_for_prop, False)
class DeleteAll(PostSortRec):
def __init__(self, uow, mapper):
)
def per_state_flush_actions(self, uow):
+ states = list(uow.states_for_mapper_hierarchy(self.mapper, True, False))
for rec in self.mapper._per_state_flush_actions(
uow,
- uow.states_for_mapper_hierarchy(self.mapper, True, False),
+ states,
True):
yield rec
+
+ for dep in uow.deps[self.mapper]:
+ states_for_prop = uow.filter_states_for_dep(dep, states)
+ dep.per_state_flush_actions(uow, states_for_prop, True)
class ProcessState(PostSortRec):
def __init__(self, uow, dependency_processor, delete, state):
n1.children.append(n2)
- self._assert_uow_size(sess, 4)
+ self._assert_uow_size(sess, 3)
sess.flush()
self._assert_uow_size(sess, 2)
n1.children
- self._assert_uow_size(sess, 3)
+ self._assert_uow_size(sess, 2)
class SingleCycleM2MTest(_base.MappedTest, testing.AssertsExecutionResults):