def testStripHistory(self): case_ids = _make_some_cases(3) history_cache = CaseDbCache() for i, id in enumerate(case_ids): self.assertFalse(history_cache.in_cache(id)) case = history_cache.get(id) self.assertEqual(str(i), case.my_index) self.assertTrue(len(case.actions) > 0) nohistory_cache = CaseDbCache(strip_history=True) for i, id in enumerate(case_ids): self.assertFalse(nohistory_cache.in_cache(id)) case = nohistory_cache.get(id) self.assertEqual(str(i), case.my_index) self.assertTrue(len(case.actions) == 0) more_case_ids = _make_some_cases(3) history_cache.populate(more_case_ids) nohistory_cache.populate(more_case_ids) for i, id in enumerate(more_case_ids): self.assertTrue(history_cache.in_cache(id)) case = history_cache.get(id) self.assertEqual(str(i), case.my_index) self.assertTrue(len(case.actions) > 0) for i, id in enumerate(more_case_ids): self.assertTrue(nohistory_cache.in_cache(id)) case = nohistory_cache.get(id) self.assertEqual(str(i), case.my_index) self.assertTrue(len(case.actions) == 0)
def get_related_cases(initial_cases, domain, strip_history=False, search_up=True): """ Gets the flat list of related cases based on a starting list. Walks all the referenced indexes recursively. If search_up is True, all cases and their parent cases are returned. If search_up is False, all cases and their child cases are returned. """ if not initial_cases: return {} # infer whether to wrap or not based on whether the initial list is wrapped or not # initial_cases may be a list or a set wrap = isinstance(next(iter(initial_cases)), CommCareCase) # todo: should assert that domain exists here but this breaks tests case_db = CaseDbCache(domain=domain, strip_history=strip_history, deleted_ok=True, wrap=wrap, initial=initial_cases) def indices(case): return case['indices'] if search_up else reverse_indices(CommCareCase.get_db(), case, wrap=False) relevant_cases = {} relevant_deleted_case_ids = [] cases_to_process = list(case for case in initial_cases) directly_referenced_indices = itertools.chain( *[[index['referenced_id'] for index in indices(case)] for case in initial_cases] ) case_db.populate(directly_referenced_indices) def process_cases(cases): new_relations = set() for case in cases: if case and case['_id'] not in relevant_cases: relevant_cases[case['_id']] = case if case['doc_type'] == 'CommCareCase-Deleted': relevant_deleted_case_ids.append(case['_id']) new_relations.update(index['referenced_id'] for index in indices(case)) if new_relations: case_db.populate(new_relations) return [case_db.get(related_case) for related_case in new_relations] while cases_to_process: cases_to_process = process_cases(cases_to_process) if relevant_deleted_case_ids: logging.info('deleted cases included in footprint (restore): %s' % ( ', '.join(relevant_deleted_case_ids) )) return relevant_cases
def testPopulate(self): case_ids = _make_some_cases(3) cache = CaseDbCache() for id in case_ids: self.assertFalse(cache.in_cache(id)) cache.populate(case_ids) for id in case_ids: self.assertTrue(cache.in_cache(id)) # sanity check for i, id in enumerate(case_ids): case = cache.get(id) self.assertEqual(str(i), case.my_index)
def get_related_cases(initial_case_list, domain, strip_history=False, search_up=True): """ Gets the flat list of related cases based on a starting list. Walks all the referenced indexes recursively. If search_up is True, all cases and their parent cases are returned. If search_up is False, all cases and their child cases are returned. """ if not initial_case_list: return {} # todo: should assert that domain exists here but this breaks tests case_db = CaseDbCache(domain=domain, strip_history=strip_history, deleted_ok=True, initial=initial_case_list) def related(case_db, case): return [case_db.get(index.referenced_id) for index in (case.indices if search_up else case.reverse_indices)] relevant_cases = {} relevant_deleted_case_ids = [] queue = list(case for case in initial_case_list) directly_referenced_indices = itertools.chain(*[[index.referenced_id for index in (case.indices if search_up else case.reverse_indices)] for case in initial_case_list]) case_db.populate(directly_referenced_indices) while queue: case = queue.pop() if case and case.case_id not in relevant_cases: relevant_cases[case.case_id] = case if case.doc_type == 'CommCareCase-Deleted': relevant_deleted_case_ids.append(case.case_id) queue.extend(related(case_db, case)) if relevant_deleted_case_ids: logging.info('deleted cases included in footprint (restore): %s' % ( ', '.join(relevant_deleted_case_ids) )) return relevant_cases