def test_hard_delete_case(self): case1 = _create_case() case2 = _create_case(domain='other_domain') self.addCleanup(lambda: CaseAccessorSQL.hard_delete_cases('other_domain', [case2.case_id])) case1.track_create(CommCareCaseIndexSQL( case=case1, identifier='parent', referenced_type='mother', referenced_id=uuid.uuid4().hex, relationship_id=CommCareCaseIndexSQL.CHILD )) case1.track_create(CaseAttachmentSQL( case=case1, attachment_id=uuid.uuid4().hex, name='pic.jpg', content_type='image/jpeg', blob_id='122', md5='123', identifier='pic.jpg', )) CaseAccessorSQL.save_case(case1) num_deleted = CaseAccessorSQL.hard_delete_cases(DOMAIN, [case1.case_id, case2.case_id]) self.assertEqual(1, num_deleted) with self.assertRaises(CaseNotFound): CaseAccessorSQL.get_case(case1.case_id) self.assertEqual([], CaseAccessorSQL.get_indices(case1.domain, case1.case_id)) self.assertEqual([], CaseAccessorSQL.get_attachments(case1.case_id)) self.assertEqual([], CaseAccessorSQL.get_transactions(case1.case_id))
def test_reconcile_transactions_within_fudge_factor(self, soft_assert_mock): """ tests a transanction with an early client date and late server date """ with freeze_time("2018-10-10"): case = self._create_case() with freeze_time("2018-10-11 06:00"): new_old_xform = self._create_form() with freeze_time("2018-10-10 18:00"): new_old_trans = self._create_case_transaction(case, new_old_xform) with freeze_time("2018-10-11 06:00"): case.track_create(new_old_trans) FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case]) with freeze_time("2018-10-11"): new_old_xform = self._create_form() new_old_trans = self._create_case_transaction(case, new_old_xform) case.track_create(new_old_trans) FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case]) case = CaseAccessorSQL.get_case(case.case_id) update_strategy = SqlCaseUpdateStrategy(case) self.assertTrue(update_strategy.reconcile_transactions_if_necessary()) self._check_for_reconciliation_error_soft_assert(soft_assert_mock) CaseAccessorSQL.save_case(case) case = CaseAccessorSQL.get_case(case.case_id) update_strategy = SqlCaseUpdateStrategy(case) self.assertFalse(update_strategy.reconcile_transactions_if_necessary()) self._check_for_reconciliation_error_soft_assert(soft_assert_mock)
def _get_case(self, case_id): try: if self.lock: try: case, lock = CommCareCaseSQL.get_locked_obj(_id=case_id) except redis.RedisError: case = CaseAccessorSQL.get_case(case_id)
def get_case_with_lock(case_id, lock=False, wrap=False): try: if lock: try: return CommCareCaseSQL.get_locked_obj(_id=case_id) except redis.RedisError: case = CaseAccessorSQL.get_case(case_id) else:
def _hard_delete_data(args_json): def discard_case_diffs(statedb): statedb.add_diffed_cases([case_id]) statedb.replace_case_diffs([("CommCareCase", case_id, [])]) statedb.replace_case_changes([("CommCareCase", case_id, [])]) return [] # TODO remove form and case diffs, if any, for hard-deleted items case_id, form_ids = args_json try: case = CaseAccessorSQL.get_case(case_id)
def test_reprocess_unfinished_submission_ledger_create(self): from corehq.apps.commtrack.tests.util import get_single_balance_block case_id = uuid.uuid4().hex self.factory.create_or_update_cases([ CaseStructure(case_id=case_id, attrs={ 'case_type': 'parent', 'create': True }) ]) transaction_patch = patch( 'corehq.form_processor.backends.sql.processor.transaction') ledger_save_patch = patch( 'corehq.form_processor.backends.sql.dbaccessors.LedgerAccessorSQL.save_ledger_values', side_effect=InternalError) with transaction_patch, ledger_save_patch, self.assertRaises( InternalError): submit_case_blocks( get_single_balance_block(case_id, 'product1', 100), self.domain) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) ledgers = LedgerAccessorSQL.get_ledger_values_for_case(case_id) self.assertEqual(0, len(ledgers)) # case transaction got saved case = CaseAccessorSQL.get_case(case_id) self.assertEqual(2, len(case.transactions)) self.assertTrue(case.transactions[0].is_case_create) self.assertTrue(case.transactions[1].is_ledger_transaction) ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case( case_id) self.assertEqual(0, len(ledger_transactions)) result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(0, len(result.cases)) self.assertEqual(1, len(result.ledgers)) ledgers = LedgerAccessorSQL.get_ledger_values_for_case(case_id) self.assertEqual(1, len(ledgers)) ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case( case_id) self.assertEqual(1, len(ledger_transactions)) # case still only has 2 transactions case = CaseAccessorSQL.get_case(case_id) self.assertEqual(2, len(case.transactions))
def get_case_with_lock(case_id, lock=False, strip_history=False, wrap=False): try: if lock: try: return CommCareCaseSQL.get_locked_obj(_id=case_id) except redis.RedisError: case = CaseAccessorSQL.get_case(case_id) else: case = CaseAccessorSQL.get_case(case_id) except CaseNotFound: return None, None return case, None
def test_reprocess_unfinished_submission_case_update(self): case_id = uuid.uuid4().hex form_ids = [] form_ids.append( submit_case_blocks( CaseBlock(case_id=case_id, create=True, case_type='box').as_string(), self.domain)[0].form_id) transaction_patch = patch( 'corehq.form_processor.backends.sql.processor.transaction') case_save_patch = patch( 'corehq.form_processor.backends.sql.dbaccessors.CaseAccessorSQL.save_case', side_effect=InternalError) with transaction_patch, case_save_patch, self.assertRaises( InternalError): submit_case_blocks( CaseBlock(case_id=case_id, update={ 'prop': 'a' }).as_string(), self.domain) stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain, saved=False).all() self.assertEqual(1, len(stubs)) form_ids.append(stubs[0].xform_id) # submit second form with case update form_ids.append( submit_case_blocks( CaseBlock(case_id=case_id, update={ 'prop': 'b' }).as_string(), self.domain)[0].form_id) case = CaseAccessorSQL.get_case(case_id) self.assertEqual(2, len(case.transactions)) self.assertEqual('b', case.get_case_property('prop')) result = reprocess_unfinished_stub(stubs[0]) self.assertEqual(1, len(result.cases)) self.assertEqual(0, len(result.ledgers)) case = CaseAccessorSQL.get_case(case_id) self.assertEqual('b', case.get_case_property( 'prop')) # should be property value from most recent form self.assertEqual(4, len(case.transactions)) self.assertEqual(form_ids + [None], [trans.form_id for trans in case.transactions]) with self.assertRaises(UnfinishedSubmissionStub.DoesNotExist): UnfinishedSubmissionStub.objects.get(pk=stubs[0].pk)
def _get_case(self, case_id): try: if self.lock: try: case, lock = CommCareCaseSQL.get_locked_obj(_id=case_id) except redis.RedisError: case = CaseAccessorSQL.get_case(case_id) else: self.locks.append(lock) else: case = CaseAccessorSQL.get_case(case_id) except CaseNotFound: return None return case
def test_get_case_by_id(self): case = _create_case() with self.assertNumQueries(1, using=db_for_read_write(CommCareCaseSQL)): case = CaseAccessorSQL.get_case(case.case_id) self.assertIsNotNone(case) self.assertIsInstance(case, CommCareCaseSQL) self.assertEqual(DOMAIN, case.domain) self.assertEqual('user1', case.owner_id)
def referenced_case(self): """ For a 'forward' index this is the case that the the index points to. For a 'reverse' index this is the case that owns the index. See ``CaseAccessorSQL.get_reverse_indices`` :return: referenced case """ from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL return CaseAccessorSQL.get_case(self.referenced_id)
def referenced_case(self): """ For a 'forward' index this is the case that the the index points to. For a 'reverse' index this is the case that owns the index. See ``CaseAccessorSQL.get_reverse_indices`` :return: referenced case """ from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL return CaseAccessorSQL.get_case(self.referenced_id)
def get_case(self, case_id): try: return CaseAccessorSQL.get_case(case_id) except CaseNotFound: pass try: return CaseAccessorCouch.get_case(case_id) except ResourceNotFound: pass return None
def get_case(self, case_id): try: return CaseAccessorSQL.get_case(case_id) except CaseNotFound: pass try: return CaseAccessorCouch.get_case(case_id) except ResourceNotFound: pass return None
def test_reconcile_not_necessary(self): with freeze_time("2018-10-10"): case = self._create_case() with freeze_time("2018-10-11"): new_old_xform = self._create_form() new_old_trans = self._create_case_transaction(case, new_old_xform) case.track_create(new_old_trans) FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case]) case = CaseAccessorSQL.get_case(case.case_id) update_strategy = SqlCaseUpdateStrategy(case) self.assertFalse(update_strategy.reconcile_transactions_if_necessary())
def hard_rebuild_case(domain, case_id, detail): try: case = CaseAccessorSQL.get_case(case_id) assert case.domain == domain found = True except CaseNotFound: case = CommCareCaseSQL(case_id=case_id, domain=domain) found = False case = FormProcessorSQL._rebuild_case_from_transactions(case, detail) if case.is_deleted and not found: return None CaseAccessorSQL.save_case(case)
def test_first_transaction_not_create(self): with freeze_time("2018-10-10"): case = self._create_case() with freeze_time("2018-10-08"): new_old_xform = self._create_form() new_old_trans = self._create_case_transaction(case, new_old_xform) case.track_create(new_old_trans) FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case]) self.assertTrue(case.check_transaction_order()) case = CaseAccessorSQL.get_case(case.case_id) update_strategy = SqlCaseUpdateStrategy(case) self.assertRaises(ReconciliationError, update_strategy.reconcile_transactions)
def _create_case(self, case_type=None, user_id=None, case_id=None): case_id = case_id or uuid.uuid4().hex user_id = user_id or 'mr_wednesday' utcnow = datetime.utcnow() case = CommCareCaseSQL( case_id=case_id, domain=self.DOMAIN, type=case_type or '', owner_id=user_id, opened_on=utcnow, modified_on=utcnow, modified_by=utcnow, server_modified_on=utcnow ) form = self._create_form(user_id, utcnow) case.track_create(self._create_case_transaction(case, form, utcnow, action_types=[128])) FormProcessorSQL.save_processed_models(ProcessedForms(form, []), [case]) return CaseAccessorSQL.get_case(case_id)
def _create_case(self, case_type=None, user_id=None, case_id=None): case_id = case_id or uuid.uuid4().hex user_id = user_id or 'mr_wednesday' utcnow = datetime.utcnow() case = CommCareCaseSQL(case_id=case_id, domain=self.DOMAIN, type=case_type or '', owner_id=user_id, opened_on=utcnow, modified_on=utcnow, modified_by=utcnow, server_modified_on=utcnow) form = self._create_form(user_id, utcnow) trans = self._create_case_transaction(case, form, utcnow, action_types=[128]) self._save(form, case, trans) return CaseAccessorSQL.get_case(case_id)
def _create_case(domain=None, form_id=None, case_type=None, user_id=None, closed=False): """ Create the models directly so that these tests aren't dependent on any other apps. Not testing form processing here anyway. :return: case_id """ domain = domain or DOMAIN form_id = form_id or uuid.uuid4().hex case_id = uuid.uuid4().hex user_id = user_id or 'user1' utcnow = datetime.utcnow() form = XFormInstanceSQL( form_id=form_id, xmlns='http://openrosa.org/formdesigner/form-processor', received_on=utcnow, user_id=user_id, domain=domain ) cases = [] if case_id: case = CommCareCaseSQL( case_id=case_id, domain=domain, type=case_type or '', owner_id=user_id, opened_on=utcnow, modified_on=utcnow, modified_by=user_id, server_modified_on=utcnow, closed=closed or False ) case.track_create(CaseTransaction.form_transaction(case, form)) cases = [case] FormProcessorSQL.save_processed_models(ProcessedForms(form, None), cases) return CaseAccessorSQL.get_case(case_id)
def _create_case(domain=None, form_id=None, case_type=None, user_id=None, closed=False, case_id=None): """ Create the models directly so that these tests aren't dependent on any other apps. Not testing form processing here anyway. :return: CommCareCaseSQL """ domain = domain or DOMAIN form_id = form_id or uuid.uuid4().hex case_id = case_id or uuid.uuid4().hex user_id = user_id or 'user1' utcnow = datetime.utcnow() form = XFormInstanceSQL( form_id=form_id, xmlns='http://openrosa.org/formdesigner/form-processor', received_on=utcnow, user_id=user_id, domain=domain) case = CommCareCaseSQL(case_id=case_id, domain=domain, type=case_type or '', owner_id=user_id, opened_on=utcnow, modified_on=utcnow, modified_by=user_id, server_modified_on=utcnow, closed=closed or False) case.track_create(CaseTransaction.form_transaction(case, form, utcnow)) cases = [case] FormProcessorSQL.save_processed_models(ProcessedForms(form, None), cases) return CaseAccessorSQL.get_case(case_id)
def test_ignores_before_rebuild_transaction(self): with freeze_time("2018-10-10"): case = self._create_case() with freeze_time("2018-10-11"): new_old_xform = self._create_form() with freeze_time("2018-10-08"): new_old_trans = self._create_case_transaction(case, new_old_xform) with freeze_time("2018-10-11"): case.track_create(new_old_trans) FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case]) self.assertFalse(case.check_transaction_order()) with freeze_time("2018-10-13"): new_rebuild_xform = self._create_form() rebuild_detail = RebuildWithReason(reason="shadow's golden coin") rebuild_transaction = CaseTransaction.rebuild_transaction(case, rebuild_detail) case.track_create(rebuild_transaction) FormProcessorSQL.save_processed_models(ProcessedForms(new_rebuild_xform, []), [case]) case = CaseAccessorSQL.get_case(case.case_id) update_strategy = SqlCaseUpdateStrategy(case) self.assertFalse(update_strategy.reconcile_transactions_if_necessary())
relationship_id=CommCareCaseIndexSQL.CHILD )) case1.track_create(CaseAttachmentSQL( case=case1, attachment_id=uuid.uuid4().hex, name='pic.jpg', content_type='image/jpeg', blob_id='122', md5='123', )) CaseAccessorSQL.save_case(case1) num_deleted = CaseAccessorSQL.hard_delete_cases(DOMAIN, [case1.case_id, case2.case_id]) self.assertEqual(1, num_deleted) with self.assertRaises(CaseNotFound): CaseAccessorSQL.get_case(case1.case_id) self.assertEqual([], CaseAccessorSQL.get_indices(case1.domain, case1.case_id)) self.assertEqual([], CaseAccessorSQL.get_attachments(case1.case_id)) self.assertEqual([], CaseAccessorSQL.get_transactions(case1.case_id)) def test_get_attachment_by_name(self): case = _create_case() case.track_create(CaseAttachmentSQL( case=case, attachment_id=uuid.uuid4().hex, name='pic.jpg', content_type='image/jpeg', blob_id='123', md5='123'
def test_get_case_by_id_missing(self): with self.assertRaises(CaseNotFound): CaseAccessorSQL.get_case('missing_case')
def test_get_case_by_id_missing(self): with self.assertRaises(CaseNotFound): CaseAccessorSQL.get_case('missing_case')
def get_sql_case(case_id): return CaseAccessorSQL.get_case(case_id)
def hard_rebuild_case(domain, case_id, detail): try: case = CaseAccessorSQL.get_case(case_id) assert case.domain == domain found = True
def _hard_delete_data(args_json): # TODO remove form and case diffs, if any, for hard-deleted items case_id, form_ids = args_json try: case = CaseAccessorSQL.get_case(case_id)
def get_obj_by_id(cls, case_id): from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL return CaseAccessorSQL.get_case(case_id)
def get_supply_point(supply_point_id): return CaseAccessorSQL.get_case(supply_point_id)
def get_supply_point(supply_point_id): return CaseAccessorSQL.get_case(supply_point_id)
xform_ids = CaseAccessorSQL.get_case_xform_ids(case_id) return FormAccessorSQL.get_forms_with_attachments_meta(xform_ids) @staticmethod def get_case_with_lock(case_id, lock=False, strip_history=False, wrap=False): try: if lock: try: return CommCareCaseSQL.get_locked_obj(_id=case_id) except redis.RedisError: case = CaseAccessorSQL.get_case(case_id) else: case = CaseAccessorSQL.get_case(case_id) except CaseNotFound: return None, None return case, None @staticmethod def case_exists(case_id): return CaseAccessorSQL.case_exists(case_id) def get_case_transactions(case_id, updated_xforms=None): """ This fetches all the transactions required to rebuild the case along with all the forms for those transactions.
def get_obj_by_id(cls, case_id): from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL return CaseAccessorSQL.get_case(case_id)