mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-06-01 21:38:55 -04:00
refined system bywhich dependencyprocessor per-state actions
are established
This commit is contained in:
@@ -115,16 +115,12 @@ class DependencyProcessor(object):
|
||||
|
||||
"""
|
||||
|
||||
# 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
|
||||
|
||||
@@ -1265,31 +1265,8 @@ class Mapper(object):
|
||||
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)
|
||||
@@ -1303,19 +1280,8 @@ class Mapper(object):
|
||||
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.
|
||||
|
||||
@@ -79,6 +79,7 @@ class UOWTransaction(object):
|
||||
# information.
|
||||
self.attributes = {}
|
||||
|
||||
self.deps = util.defaultdict(set)
|
||||
self.mappers = util.defaultdict(set)
|
||||
self.presort_actions = {}
|
||||
self.postsort_actions = {}
|
||||
@@ -146,6 +147,16 @@ class UOWTransaction(object):
|
||||
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]:
|
||||
@@ -341,6 +352,10 @@ class GetDependentObjects(PropertyRecMixin, PreSortRec):
|
||||
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:
|
||||
@@ -368,11 +383,16 @@ class SaveUpdateAll(PostSortRec):
|
||||
)
|
||||
|
||||
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):
|
||||
@@ -386,11 +406,16 @@ class DeleteAll(PostSortRec):
|
||||
)
|
||||
|
||||
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):
|
||||
|
||||
@@ -466,7 +466,7 @@ class SingleCycleTest(UOWTest):
|
||||
|
||||
n1.children.append(n2)
|
||||
|
||||
self._assert_uow_size(sess, 4)
|
||||
self._assert_uow_size(sess, 3)
|
||||
|
||||
sess.flush()
|
||||
|
||||
@@ -476,7 +476,7 @@ class SingleCycleTest(UOWTest):
|
||||
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):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user