Skip to content

Commit

Permalink
CRM-20533 - Drop false/missing indices directly from update indices b…
Browse files Browse the repository at this point in the history
…utton
  • Loading branch information
Jitendra Purohit committed Aug 28, 2017
1 parent 068f403 commit 3d4602c
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 38 deletions.
18 changes: 10 additions & 8 deletions CRM/Core/BAO/SchemaHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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;
}
}
Expand All @@ -751,7 +753,7 @@ public static function getMissingIndices() {
}
}
}
return array($missingIndices, $existingKeyIndices);
return $missingIndices;
}

/**
Expand Down
17 changes: 5 additions & 12 deletions CRM/Utils/Check/Component/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
3 changes: 1 addition & 2 deletions api/v3/System.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
36 changes: 20 additions & 16 deletions tests/phpunit/CRM/Core/BAO/SchemaHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down Expand Up @@ -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(
Expand All @@ -242,37 +242,41 @@ 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));
}

/**
* 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);
}

/**
Expand Down

0 comments on commit 3d4602c

Please sign in to comment.