From f4f835ed225bb18bc78f4e32006733b028938240 Mon Sep 17 00:00:00 2001 From: Jitendra Purohit Date: Mon, 26 Jun 2017 16:55:19 +0530 Subject: [PATCH 1/3] Add check for existing key index in table --- CRM/Core/BAO/SchemaHandler.php | 19 ++++++++++++++++++- CRM/Utils/Check/Component/Schema.php | 24 +++++++++++++++++++++--- api/v3/System.php | 3 ++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CRM/Core/BAO/SchemaHandler.php b/CRM/Core/BAO/SchemaHandler.php index 1f4a93c17183..c4f8c221ef86 100644 --- a/CRM/Core/BAO/SchemaHandler.php +++ b/CRM/Core/BAO/SchemaHandler.php @@ -723,6 +723,23 @@ public static function getMissingIndices() { // Compare $missingSigs = array_diff($requiredSigs, $existingSigs); + + //CRM-20774 - Get index key which exist in db but the value varies. + $existingKeyIndices = array(); + $existingKeySigs = array_intersect_key($missingSigs, $existingSigs); + if (!empty($existingKeySigs)) { + $missingSigs = array_diff_key($missingSigs, $existingKeySigs); + foreach ($existingKeySigs as $sig) { + $sigParts = explode('::', $sig); + foreach ($requiredIndices[$sigParts[0]] as $index) { + if ($index['sig'] == $sig) { + $existingKeyIndices[$sigParts[0]][] = $index; + continue; + } + } + } + } + // Get missing indices $missingIndices = array(); foreach ($missingSigs as $sig) { @@ -734,7 +751,7 @@ public static function getMissingIndices() { } } } - return $missingIndices; + return array($missingIndices, $existingKeyIndices); } /** diff --git a/CRM/Utils/Check/Component/Schema.php b/CRM/Utils/Check/Component/Schema.php index 6c8f7608e76f..caf8558f22be 100644 --- a/CRM/Utils/Check/Component/Schema.php +++ b/CRM/Utils/Check/Component/Schema.php @@ -37,11 +37,29 @@ class CRM_Utils_Check_Component_Schema extends CRM_Utils_Check_Component { */ public function checkIndices() { $messages = array(); - $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); - if ($missingIndices) { + list($missingIndices, $existingKeyIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + if ($existingKeyIndices) { + $html = ''; + foreach ($existingKeyIndices as $tableName => $indices) { + foreach ($indices as $index) { + $fields = implode(', ', $index['field']); + $html .= "{$tableName}{$index['name']}$fields"; + } + } + $keyMessage = "

The following tables have an index key with a mismatch in value. Please delete the key indices listed from the below table and then click on 'Update Indices' button.

+

+ + $html +
Table NameKey NameFields

"; + } + if ($missingIndices || $existingKeyIndices) { + $message = "You have missing indices on some tables. This may cause poor performance."; + if ($keyMessage) { + $message = $keyMessage; + } $msg = new CRM_Utils_Check_Message( __FUNCTION__, - ts('You have missing indices on some tables. This may cause poor performance.'), + ts($message), ts('Performance warning: Missing indices'), \Psr\Log\LogLevel::WARNING, 'fa-server' diff --git a/api/v3/System.php b/api/v3/System.php index b71103297259..b4b4974bf0d7 100644 --- a/api/v3/System.php +++ b/api/v3/System.php @@ -408,6 +408,7 @@ function civicrm_api3_system_updatelogtables() { * This adds any indexes that exist in the schema but not the database. */ function civicrm_api3_system_updateindexes() { - CRM_Core_BAO_SchemaHandler::createMissingIndices(CRM_Core_BAO_SchemaHandler::getMissingIndices()); + list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + CRM_Core_BAO_SchemaHandler::createMissingIndices($missingIndices); return civicrm_api3_create_success(1); } From eaf81f0036267c84043057bf6ca73300cf68b669 Mon Sep 17 00:00:00 2001 From: Jitendra Purohit Date: Tue, 27 Jun 2017 09:54:15 +0530 Subject: [PATCH 2/3] existing test fixes --- CRM/Utils/Check/Component/Schema.php | 2 +- tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CRM/Utils/Check/Component/Schema.php b/CRM/Utils/Check/Component/Schema.php index caf8558f22be..d281c26a405c 100644 --- a/CRM/Utils/Check/Component/Schema.php +++ b/CRM/Utils/Check/Component/Schema.php @@ -54,7 +54,7 @@ public function checkIndices() { } if ($missingIndices || $existingKeyIndices) { $message = "You have missing indices on some tables. This may cause poor performance."; - if ($keyMessage) { + if (!empty($keyMessage)) { $message = $keyMessage; } $msg = new CRM_Utils_Check_Message( diff --git a/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php b/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php index e2bcba688233..2571ca3cf43c 100644 --- a/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php +++ b/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php @@ -184,7 +184,7 @@ public function testSafeDropForeignKey($tableName, $key) { * Check there are no missing indices */ public function testGetMissingIndices() { - $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); $this->assertTrue(empty($missingIndices)); } @@ -230,7 +230,7 @@ public function testCreateMissingIndices() { */ public function testReconcileMissingIndices() { CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_contact DROP INDEX index_sort_name'); - $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); $this->assertEquals(array( 'civicrm_contact' => array( array( @@ -242,7 +242,7 @@ public function testReconcileMissingIndices() { ), ), $missingIndices); $this->callAPISuccess('System', 'updateindexes', array()); - $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); $this->assertTrue(empty($missingIndices)); } From d7367cefbb28ead6b6305addf133f24f6e381125 Mon Sep 17 00:00:00 2001 From: Jitendra Purohit Date: Tue, 27 Jun 2017 19:48:01 +0530 Subject: [PATCH 3/3] add test --- .../CRM/Core/BAO/SchemaHandlerTest.php | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php b/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php index 2571ca3cf43c..6227a957d212 100644 --- a/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php +++ b/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php @@ -246,6 +246,35 @@ public function testReconcileMissingIndices() { $this->assertTrue(empty($missingIndices)); } + /** + * Check for partial indices + */ + public function testPartialIndices() { + CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_prevnext_cache DROP INDEX index_all'); + //Missing Column `is_selected`. + CRM_Core_DAO::executeQuery('CREATE INDEX index_all ON civicrm_prevnext_cache (cacheKey, entity_id1, entity_id2, entity_table)'); + list($missingIndices, $existingKeyIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $this->assertNotEmpty($existingKeyIndices); + + CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_entity_tag DROP INDEX UI_entity_id_entity_table_tag_id'); + //Test incorrect Ordering(correct order defined is entity_id and then entity_table, tag_id). + CRM_Core_DAO::executeQuery('CREATE INDEX UI_entity_id_entity_table_tag_id ON civicrm_entity_tag (entity_table, entity_id, tag_id)'); + list($missingIndices, $existingKeyIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $this->assertNotEmpty($existingKeyIndices); + $this->assertEquals(array('civicrm_prevnext_cache', 'civicrm_entity_tag'), array_keys($existingKeyIndices)); + + //Drop false index and create again. + CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_prevnext_cache DROP INDEX index_all'); + CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_entity_tag DROP INDEX UI_entity_id_entity_table_tag_id'); + list($missingIndices, $existingKeyIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $this->assertEmpty($existingKeyIndices); + CRM_Core_BAO_SchemaHandler::createMissingIndices($missingIndices); + //Both vars should be empty now. + list($missingIndices, $existingKeyIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $this->assertEmpty($missingIndices); + $this->assertEmpty($existingKeyIndices); + } + /** * Test index signatures are added correctly */