DRY things out a bit and share as much code between MongoModuleStore and DraftMongoModuleStore

This commit is contained in:
Chris Dodge
2013-03-28 09:49:55 -04:00
parent 3cdd973af4
commit c7bafddace
2 changed files with 37 additions and 65 deletions

View File

@@ -191,66 +191,35 @@ class DraftModuleStore(ModuleStoreBase):
super(DraftModuleStore, self).clone_item(location, as_draft(location)) super(DraftModuleStore, self).clone_item(location, as_draft(location))
super(DraftModuleStore, self).delete_item(location) super(DraftModuleStore, self).delete_item(location)
def _cache_children(self, items, depth=0): def _query_children_for_cache_children(self, items):
""" # first get non-draft in a round-trip
Returns a dictionary mapping Location -> item data, populated with json data queried_children = []
for all descendents of items up to the specified depth. to_process_non_drafts = super(DraftModuleStore, self)._query_children_for_cache_children(items)
(0 = no descendents, 1 = children, 2 = grandchildren, etc)
If depth is None, will load all the children.
This will make a number of queries that is linear in the depth.
"""
data = {} to_process_dict = {}
to_process = list(items) for non_draft in to_process_non_drafts:
while to_process and depth is None or depth >= 0: to_process_dict[Location(non_draft["_id"])] = non_draft
children = []
for item in to_process:
self._clean_item_data(item)
children.extend(item.get('definition', {}).get('children', []))
data[Location(item['location'])] = item
if depth == 0: # now query all draft content in another round-trip
break; query = {
'_id': {'$in': [namedtuple_to_son(as_draft(Location(item))) for item in items]}
}
to_process_drafts = list(self.collection.find(query))
# Load all children by id. See # now we have to go through all drafts and replace the non-draft
# http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or # with the draft. This is because the semantics of the DraftStore is to
# for or-query syntax # always return the draft - if available
to_process = [] for draft in to_process_drafts:
if children: draft_loc = Location(draft["_id"])
# first get non-draft in a round-trip draft_as_non_draft_loc = draft_loc._replace(revision=None)
query = {
'_id': {'$in': [namedtuple_to_son(Location(child)) for child in children]}
}
to_process_non_drafts = list(self.collection.find(query))
to_process_dict = {} # does non-draft exist in the collection
for non_draft in to_process_non_drafts: # if so, replace it
to_process_dict[Location(non_draft["_id"])] = non_draft if draft_as_non_draft_loc in to_process_dict:
to_process_dict[draft_as_non_draft_loc] = draft
# now query all draft content in a round-trip # convert the dict - which is used for look ups - back into a list
query = { for key, value in to_process_dict.iteritems():
'_id': {'$in': [namedtuple_to_son(as_draft(Location(child))) for child in children]} queried_children.append(value)
}
to_process_drafts = list(self.collection.find(query))
# now we have to go through all drafts and replace the non-draft return queried_children
# with the draft. This is because the semantics of the DraftStore is to
# always return the draft - if available
for draft in to_process_drafts:
draft_loc = Location(draft["_id"])
draft_as_non_draft_loc = draft_loc._replace(revision=None)
# does non-draft exist in the collection
# if so, replace it
if draft_as_non_draft_loc in to_process_dict:
to_process_dict[draft_as_non_draft_loc] = draft
# convert the dict - which is used for look ups - back into a list
for key, value in to_process_dict.iteritems():
to_process.append(value)
# If depth is None, then we just recurse until we hit all the descendents
if depth is not None:
depth -= 1
return data

View File

@@ -363,6 +363,13 @@ class MongoModuleStore(ModuleStoreBase):
item['location'] = item['_id'] item['location'] = item['_id']
del item['_id'] del item['_id']
def _query_children_for_cache_children(self, items):
# first get non-draft in a round-trip
query = {
'_id': {'$in': [namedtuple_to_son(Location(item)) for item in items]}
}
return list(self.collection.find(query))
def _cache_children(self, items, depth=0): def _cache_children(self, items, depth=0):
""" """
Returns a dictionary mapping Location -> item data, populated with json data Returns a dictionary mapping Location -> item data, populated with json data
@@ -382,18 +389,14 @@ class MongoModuleStore(ModuleStoreBase):
data[Location(item['location'])] = item data[Location(item['location'])] = item
if depth == 0: if depth == 0:
break break;
# Load all children by id. See # Load all children by id. See
# http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or # http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or
# for or-query syntax # for or-query syntax
if children and depth > 0: to_process = []
query = { if children:
'_id': {'$in': [namedtuple_to_son(Location(child)) for child in children]} to_process = self._query_children_for_cache_children(children)
}
to_process = list(self.collection.find(query))
else:
break
# If depth is None, then we just recurse until we hit all the descendents # If depth is None, then we just recurse until we hit all the descendents
if depth is not None: if depth is not None: