Skip to content

Commit

Permalink
Merge pull request #10566 from jitendrapurohit/indexfix
Browse files Browse the repository at this point in the history
CRM-20774 - Add check for existing key index in table
  • Loading branch information
eileenmcnaughton authored Jun 28, 2017
2 parents 8deabd9 + d7367ce commit b8fdc7b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 8 deletions.
19 changes: 18 additions & 1 deletion CRM/Core/BAO/SchemaHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -734,7 +751,7 @@ public static function getMissingIndices() {
}
}
}
return $missingIndices;
return array($missingIndices, $existingKeyIndices);
}

/**
Expand Down
24 changes: 21 additions & 3 deletions CRM/Utils/Check/Component/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 .= "<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>
</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;
}
$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'
Expand Down
3 changes: 2 additions & 1 deletion api/v3/System.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
35 changes: 32 additions & 3 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() {
$missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices();
list($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');
$missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices();
list($missingIndices) = CRM_Core_BAO_SchemaHandler::getMissingIndices();
$this->assertEquals(array(
'civicrm_contact' => array(
array(
Expand All @@ -242,10 +242,39 @@ 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));
}

/**
* 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
*/
Expand Down

0 comments on commit b8fdc7b

Please sign in to comment.