From 05fe457afe95ce7d684ce1943a4da8957a4b64f2 Mon Sep 17 00:00:00 2001 From: eileen Date: Mon, 13 Jul 2020 13:15:28 +1200 Subject: [PATCH] dev/core#1862 Skip cache tables during merge, rely on cache management processes We later call Contact.create on both contacts so that should manage the caches for this update 'as well as for any other update' and solve the bug + reduce locking queries --- CRM/Dedupe/Merger.php | 5 +++++ tests/phpunit/CRM/Dedupe/MergerTest.php | 6 ++++-- tests/phpunit/api/v3/JobTest.php | 18 +++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index a6213effc9..9bdc157ac1 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -225,6 +225,11 @@ class CRM_Dedupe_Merger { } $contactReferences = $coreReferences = CRM_Core_DAO::getReferencesToContactTable(); + foreach (['civicrm_group_contact_cache', 'civicrm_acl_cache', 'civicrm_acl_contact_cache'] as $tableName) { + // Don't merge cache tables. These should be otherwise cleared at some point in the dedupe + // but they are prone to locking to let's not touch during the dedupe. + unset($contactReferences[$tableName], $coreReferences[$tableName]); + } CRM_Utils_Hook::merge('cidRefs', $contactReferences); if ($contactReferences !== $coreReferences) { diff --git a/tests/phpunit/CRM/Dedupe/MergerTest.php b/tests/phpunit/CRM/Dedupe/MergerTest.php index e796173fa4..8f4bf06043 100644 --- a/tests/phpunit/CRM/Dedupe/MergerTest.php +++ b/tests/phpunit/CRM/Dedupe/MergerTest.php @@ -285,8 +285,10 @@ class CRM_Dedupe_MergerTest extends CiviUnitTestCase { */ public function testGetCidRefs() { $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'Contacts'); - $this->assertEquals($this->getStaticCIDRefs(), CRM_Dedupe_Merger::cidRefs()); - $this->assertEquals($this->getCalculatedCIDRefs(), CRM_Dedupe_Merger::cidRefs()); + // These are deliberately unset. + $unsetRefs = array_fill_keys(['civicrm_group_contact_cache', 'civicrm_acl_cache', 'civicrm_acl_contact_cache'], 1); + $this->assertEquals(array_diff_key($this->getStaticCIDRefs(), $unsetRefs), CRM_Dedupe_Merger::cidRefs()); + $this->assertEquals(array_diff_key($this->getCalculatedCIDRefs(), $unsetRefs), CRM_Dedupe_Merger::cidRefs()); } /** diff --git a/tests/phpunit/api/v3/JobTest.php b/tests/phpunit/api/v3/JobTest.php index 444714204a..f6a9bfb27c 100644 --- a/tests/phpunit/api/v3/JobTest.php +++ b/tests/phpunit/api/v3/JobTest.php @@ -573,11 +573,27 @@ class api_v3_JobTest extends CiviUnitTestCase { foreach ($groupResult['values'] as $groupValues) { $this->assertEquals($contactID, $groupValues['contact_id']); $this->assertEquals('Added', $groupValues['status']); - $this->assertTrue(in_array($groupValues['group_id'], $expectedGroups)); + $this->assertContains($groupValues['group_id'], $expectedGroups); } } + /** + * Test that we handle cache entries without clashes. + */ + public function testMergeCaches() { + $contactID = $this->individualCreate(); + $contact2ID = $this->individualCreate(); + $groupID = $this->groupCreate(); + $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contactID]); + $this->callAPISuccess('GroupContact', 'create', ['group_id' => $groupID, 'contact_id' => $contact2ID]); + CRM_Core_DAO::executeQuery("INSERT INTO civicrm_group_contact_cache(group_id, contact_id) VALUES + ($groupID, $contactID), + ($groupID, $contact2ID) + "); + $this->callAPISuccess('Job', 'process_batch_merge', ['mode' => 'safe']); + } + /** * Test the decisions made for addresses when merging. * -- 2.25.1