def rebuild_and_diff_cases(sql_case, couch_case, original_couch_case, diff, dd_count): """Try rebuilding SQL case and save if rebuild resolves diffs :param sql_case: CommCareCaseSQL object. :param couch_case: JSON-ified version of CommCareCase. :param diff: function to produce diffs between couch and SQL case JSON. :param dd_count: metrics recording counter function. :returns: list of diffs returned by `diff(couch_case, rebuilt_case_json)` """ lock = CommCareCaseSQL.get_obj_lock_by_id(sql_case.case_id) acquire_lock(lock, degrade_gracefully=False) try: if should_sort_sql_transactions(sql_case, couch_case): new_case = rebuild_case_with_couch_action_order( sql_case, couch_case) dd_count("commcare.couchsqlmigration.case.rebuild.sql.sort") else: new_case = rebuild_case(sql_case) dd_count("commcare.couchsqlmigration.case.rebuild.sql") sql_json = new_case.to_json() diffs = diff(couch_case, sql_json) if diffs: original_diffs = diff(original_couch_case, sql_json) if not original_diffs: log.info("original Couch case matches rebuilt SQL case: %s", sql_case.case_id) diffs = original_diffs if not diffs: # save case only if rebuild resolves diffs CaseAccessorSQL.save_case(new_case) publish_case_saved(new_case) finally: release_lock(lock, degrade_gracefully=True) return sql_json, diffs
def hard_rebuild_case(domain, case_id, detail, lock=True): if lock: # only record metric if locking since otherwise it has been # (most likley) recorded elsewhere case_load_counter("rebuild_case", domain)() case, lock_obj = FormProcessorSQL.get_case_with_lock(case_id, lock=lock) found = bool(case) if not found: case = CommCareCaseSQL(case_id=case_id, domain=domain) if lock: lock_obj = CommCareCaseSQL.get_obj_lock_by_id(case_id) acquire_lock(lock_obj, degrade_gracefully=False) try: assert case.domain == domain, (case.domain, domain) case, rebuild_transaction = FormProcessorSQL._rebuild_case_from_transactions(case, detail) if case.is_deleted and not case.is_saved(): return None case.server_modified_on = rebuild_transaction.server_date CaseAccessorSQL.save_case(case) publish_case_saved(case) return case finally: release_lock(lock_obj, degrade_gracefully=True)
def hard_rebuild_case(domain, case_id, detail, lock=True): if lock: # only record metric if locking since otherwise it has been # (most likley) recorded elsewhere case_load_counter("rebuild_case", domain)() case, lock_obj = FormProcessorSQL.get_case_with_lock(case_id, lock=lock) found = bool(case) if not found: case = CommCareCaseSQL(case_id=case_id, domain=domain) if lock: lock_obj = CommCareCaseSQL.get_obj_lock_by_id(case_id) acquire_lock(lock_obj, degrade_gracefully=False)
def hard_rebuild_case(domain, case_id, detail, save=True, lock=True): if lock: # only record metric if locking since otherwise it has been # (most likley) recorded elsewhere case_load_counter("rebuild_case", domain)() case, lock_obj = FormProcessorCouch.get_case_with_lock(case_id, lock=lock, wrap=True) found = bool(case) if not found: case = CommCareCase() case.case_id = case_id case.domain = domain if lock: lock_obj = CommCareCase.get_obj_lock_by_id(case_id) acquire_lock(lock_obj, degrade_gracefully=False) try: assert case.domain == domain, (case.domain, domain) forms = FormProcessorCouch.get_case_forms(case_id) form_load_counter("rebuild_case", domain)(len(forms)) filtered_forms = [f for f in forms if f.is_normal] sorted_forms = sorted(filtered_forms, key=lambda f: f.received_on) actions = _get_actions_from_forms(domain, sorted_forms, case_id) if not found and case.domain is None: case.domain = domain rebuild_case_from_actions(case, actions) # todo: should this move to case.rebuild? if not case.xform_ids: if not found: return None # there were no more forms. 'delete' the case case.doc_type = 'CommCareCase-Deleted' # add a "rebuild" action case.actions.append(_rebuild_action()) if save: case.save() return case finally: release_lock(lock_obj, degrade_gracefully=True)
def hard_rebuild_case(domain, case_id, detail, lock=True): case, lock_obj = FormProcessorSQL.get_case_with_lock(case_id, lock=lock) found = bool(case) if not found: case = CommCareCaseSQL(case_id=case_id, domain=domain) if lock: lock_obj = CommCareCaseSQL.get_obj_lock_by_id(case_id) acquire_lock(lock_obj, degrade_gracefully=False) try: assert case.domain == domain, (case.domain, domain) case, rebuild_transaction = FormProcessorSQL._rebuild_case_from_transactions(case, detail) if case.is_deleted and not case.is_saved(): return None case.server_modified_on = rebuild_transaction.server_date CaseAccessorSQL.save_case(case) publish_case_saved(case) return case finally: release_lock(lock_obj, degrade_gracefully=True)
return touched_cases @staticmethod def hard_rebuild_case(domain, case_id, detail, save=True, lock=True): case, lock_obj = FormProcessorCouch.get_case_with_lock(case_id, lock=lock, wrap=True) found = bool(case) if not found: case = CommCareCase() case.case_id = case_id case.domain = domain if lock: lock_obj = CommCareCase.get_obj_lock_by_id(case_id) acquire_lock(lock_obj, degrade_gracefully=False) try: assert case.domain == domain, (case.domain, domain) forms = FormProcessorCouch.get_case_forms(case_id) filtered_forms = [f for f in forms if f.is_normal] sorted_forms = sorted(filtered_forms, key=lambda f: f.received_on) actions = _get_actions_from_forms(domain, sorted_forms, case_id) if not found and case.domain is None: case.domain = domain rebuild_case_from_actions(case, actions) # todo: should this move to case.rebuild? if not case.xform_ids: