From 3d4602c34174a53f56be0ffe1ba41d914f606742 Mon Sep 17 00:00:00 2001 From: Jitendra Purohit Date: Sat, 26 Aug 2017 21:37:37 +0530 Subject: [PATCH] CRM-20533 - Drop false/missing indices directly from update indices button --- CRM/Core/BAO/SchemaHandler.php | 18 +++++----- CRM/Utils/Check/Component/Schema.php | 17 +++------ api/v3/System.php | 3 +- .../CRM/Core/BAO/SchemaHandlerTest.php | 36 ++++++++++--------- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/CRM/Core/BAO/SchemaHandler.php b/CRM/Core/BAO/SchemaHandler.php index c4f8c221ef86..b525903f4d67 100644 --- a/CRM/Core/BAO/SchemaHandler.php +++ b/CRM/Core/BAO/SchemaHandler.php @@ -701,10 +701,14 @@ public static function addIndexSignature($table, &$indices) { /** * Compare the indices specified in the XML files with those in the DB. * + * @param bool $dropFalseIndices + * If set - this function deletes false indices present in the DB which mismatches the expected + * values of xml file so that civi re-creates them with correct values using createMissingIndices() function. + * * @return array * index specifications */ - public static function getMissingIndices() { + public static function getMissingIndices($dropFalseIndices = FALSE) { $requiredSigs = $existingSigs = array(); // Get the indices defined (originally) in the xml files $requiredIndices = CRM_Core_DAO_AllCoreTables::indices(); @@ -724,16 +728,14 @@ 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(); + //CRM-20774 - Drop index key which exist in db but the value varies. $existingKeySigs = array_intersect_key($missingSigs, $existingSigs); - if (!empty($existingKeySigs)) { - $missingSigs = array_diff_key($missingSigs, $existingKeySigs); + if ($dropFalseIndices && !empty($existingKeySigs)) { foreach ($existingKeySigs as $sig) { $sigParts = explode('::', $sig); foreach ($requiredIndices[$sigParts[0]] as $index) { - if ($index['sig'] == $sig) { - $existingKeyIndices[$sigParts[0]][] = $index; + if ($index['sig'] == $sig && !empty($index['name'])) { + self::dropIndexIfExists($sigParts[0], $index['name']); continue; } } @@ -751,7 +753,7 @@ public static function getMissingIndices() { } } } - return array($missingIndices, $existingKeyIndices); + return $missingIndices; } /** diff --git a/CRM/Utils/Check/Component/Schema.php b/CRM/Utils/Check/Component/Schema.php index 41781473d615..4e8c037274b5 100644 --- a/CRM/Utils/Check/Component/Schema.php +++ b/CRM/Utils/Check/Component/Schema.php @@ -37,27 +37,20 @@ class CRM_Utils_Check_Component_Schema extends CRM_Utils_Check_Component { */ public function checkIndices() { $messages = array(); - list($missingIndices, $existingKeyIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); - if ($existingKeyIndices) { + $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + if ($missingIndices) { $html = ''; - foreach ($existingKeyIndices as $tableName => $indices) { + foreach ($missingIndices 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.

-

+ $message = "

The following tables have missing indices. Click 'Update Indices' button to create them.

+

Table NameKey NameFields
$html
Table NameKey NameExpected Indices

"; - } - if ($missingIndices || $existingKeyIndices) { - $message = "You have missing indices on some tables. This may cause poor performance."; - if (!empty($keyMessage)) { - $message = $keyMessage; - $message .= ts("If you are unsure how to perform this action or do not know what to do please contact your system administrator for assistance"); - } $msg = new CRM_Utils_Check_Message( __FUNCTION__, ts($message), diff --git a/api/v3/System.php b/api/v3/System.php index 83291c00cd14..0669346f3a06 100644 --- a/api/v3/System.php +++ b/api/v3/System.php @@ -408,8 +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() { - list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); - CRM_Core_BAO_SchemaHandler::createMissingIndices($missingIndices); + CRM_Core_BAO_SchemaHandler::createMissingIndices(CRM_Core_BAO_SchemaHandler::getMissingIndices(TRUE)); return civicrm_api3_create_success(1); } diff --git a/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php b/tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php index 6227a957d212..4e458cda3ae3 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() { - list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $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'); - list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $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()); - list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); $this->assertTrue(empty($missingIndices)); } @@ -250,29 +250,33 @@ public function testReconcileMissingIndices() { * Check for partial indices */ public function testPartialIndices() { - CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_prevnext_cache DROP INDEX index_all'); + $tables = array( + 'index_all' => 'civicrm_prevnext_cache', + 'UI_entity_id_entity_table_tag_id' => 'civicrm_entity_tag', + ); + CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_prevnext_cache', '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); + $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); + $this->assertNotEmpty($missingIndices); - CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_entity_tag DROP INDEX UI_entity_id_entity_table_tag_id'); + CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_entity_tag', '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)); + $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(TRUE); + $this->assertNotEmpty($missingIndices); + $this->assertEquals(array_values($tables), array_keys($missingIndices)); + //Check if both indices are deleted. + $indices = CRM_Core_BAO_SchemaHandler::getIndexes($tables); + foreach ($tables as $index => $tableName) { + $this->assertFalse(in_array($index, array_keys($indices[$tableName]))); + } //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(); + $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); $this->assertEmpty($missingIndices); - $this->assertEmpty($existingKeyIndices); } /**