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-20533 - Drop false indices directly from update indices button #10908

Merged
merged 1 commit into from
Sep 6, 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
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