Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRM-20774 - Add check for existing key index in table #10566

Merged
merged 3 commits into from
Jun 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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