CRM-20533 - Drop false/missing indices directly from update indices button
authorJitendra Purohit <jitendra@fuzion.co.nz>
Sat, 26 Aug 2017 16:07:37 +0000 (21:37 +0530)
committerJitendra Purohit <jitendra@fuzion.co.nz>
Mon, 28 Aug 2017 06:50:30 +0000 (12:20 +0530)
CRM/Core/BAO/SchemaHandler.php
CRM/Utils/Check/Component/Schema.php
api/v3/System.php
tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php

index c4f8c221ef86b24da420453c8d311bc602a2f2ad..b525903f4d67e06754e5cefb39c90d70c216af27 100644 (file)
@@ -701,10 +701,14 @@ MODIFY      {$columnName} varchar( $length )
   /**
    * 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 @@ MODIFY      {$columnName} varchar( $length )
     // 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 @@ MODIFY      {$columnName} varchar( $length )
         }
       }
     }
-    return array($missingIndices, $existingKeyIndices);
+    return $missingIndices;
   }
 
   /**
index 41781473d615c864fa19ba10abff4339e5ec0601..4e8c037274b5a26510f451e6a9a2386b48f04972 100644 (file)
@@ -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 .= "<tr><td>{$tableName}</td><td>{$index['name']}</td><td>$fields</td>";
         }
       }
-      $keyMessage = "<p>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. <p>
-        <p><table><thead><tr><th>Table Name</th><th>Key Name</th><th>Fields</th>
+      $message = "<p>The following tables have missing indices. Click 'Update Indices' button to create them.<p>
+        <p><table><thead><tr><th>Table Name</th><th>Key Name</th><th>Expected Indices</th>
         </tr></thead><tbody>
         $html
         </tbody></table></p>";
-    }
-    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),
index 83291c00cd143bb0063049766472e74111424f79..0669346f3a06ce797c7554a4d66e3d5dda290447 100644 (file)
@@ -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);
 }
 
index 6227a957d2123137126d96d227ab809b984e70fd..4e458cda3ae32f5489ee1e474ddf4024c42ab52a 100644 (file)
@@ -184,7 +184,7 @@ class CRM_Core_BAO_SchemaHandlerTest extends CiviUnitTestCase {
    * 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 @@ class CRM_Core_BAO_SchemaHandlerTest extends CiviUnitTestCase {
    */
   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 @@ class CRM_Core_BAO_SchemaHandlerTest extends CiviUnitTestCase {
       ),
     ), $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 @@ class CRM_Core_BAO_SchemaHandlerTest extends CiviUnitTestCase {
    * 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);
   }
 
   /**