diff --git a/application/config/version.php b/application/config/version.php index b5a0dfef1d4..37d7689cdcc 100644 --- a/application/config/version.php +++ b/application/config/version.php @@ -12,7 +12,7 @@ */ $config['versionnumber'] = '5.2.0-dev'; -$config['dbversionnumber'] = 474; +$config['dbversionnumber'] = 475; $config['buildnumber'] = ''; $config['updatable'] = true; $config['templateapiversion'] = 3; diff --git a/application/helpers/update/updatedb_helper.php b/application/helpers/update/updatedb_helper.php index 112819c6e0a..91a6f35dcbe 100644 --- a/application/helpers/update/updatedb_helper.php +++ b/application/helpers/update/updatedb_helper.php @@ -3161,48 +3161,6 @@ function db_upgrade_all($iOldDBVersion, $bSilent = false) $oDB->createCommand()->createIndex('{{answers_idx}}', '{{answers}}', ['qid', 'code', 'scale_id'], true); $oDB->createCommand()->createIndex('{{answers_idx2}}', '{{answers}}', 'sortorder', false); - /** - * Regenerate codes for problematic label sets - * Helper function (TODO: Put in separate class) - * Fails silently - * - * @param int $lid Label set id - * @return void - */ - $regenerateCodes = function (int $lid) { - $oDB = Yii::app()->getDb(); - - $labelSet = $oDB->createCommand( - sprintf("SELECT * FROM {{labelsets}} WHERE lid = %d", (int) $lid) - )->queryRow(); - if (empty($labelSet)) { - return; - } - - foreach (explode(',', $labelSet['languages']) as $lang) { - $labels = $oDB->createCommand( - sprintf( - "SELECT * FROM {{labels}} WHERE lid = %d AND language = %s", - (int) $lid, - $oDB->quoteValue($lang) - ) - )->queryAll(); - if (empty($labels)) { - continue; - } - foreach ($labels as $key => $label) { - $oDB->createCommand( - sprintf( - "UPDATE {{labels}} SET code = %s WHERE id = %d", - // Use simply nr as label code - $oDB->quoteValue((string) $key + 1), - $label['id'] - ) - )->execute(); - } - } - }; - // Apply integrity fix before starting label set update. // List of label set ids which contain code duplicates. $lids = $oDB->createCommand( @@ -3212,7 +3170,7 @@ function db_upgrade_all($iOldDBVersion, $bSilent = false) HAVING COUNT(DISTINCT({{labels}}.code)) < COUNT({{labels}}.id)" )->queryAll(); foreach ($lids as $lid) { - $regenerateCodes($lid['lid']); + regenerateLabelCodes400($lid['lid']); } // Labels table @@ -4973,20 +4931,22 @@ function ($v) { $oDB->createCommand()->update('{{settings_global}}', array('stg_value' => 473), "stg_name='DBVersion'"); $oTransaction->commit(); } - - if ($iOldDBVersion < 474) { + // 474 was left out for technical reasons + if ($iOldDBVersion < 475) { $oTransaction = $oDB->beginTransaction(); - $aDefaultSurveyMenuEntries = LsDefaultDataSets::getSurveyMenuEntryData(); - foreach ($aDefaultSurveyMenuEntries as $aSurveymenuentry) { - if ($aSurveymenuentry['name'] == 'listQuestionGroups') { - if (SurveymenuEntries::model()->findByAttributes(['name' => $aSurveymenuentry['name']]) == null) { - $oDB->createCommand()->insert('{{surveymenu_entries}}', $aSurveymenuentry); - SurveymenuEntries::reorderMenu(2); - } - break; - } + // Apply integrity fix before adding unique constraint. + // List of label set ids which contain code duplicates. + $lids = $oDB->createCommand( + "SELECT lime_labels.lid AS lid + FROM lime_labels + GROUP BY lime_labels.lid + HAVING COUNT(DISTINCT(lime_labels.code)) < COUNT(lime_labels.id)" + )->queryAll(); + foreach ($lids as $lid) { + regenerateLabelCodes400($lid['lid']); } - $oDB->createCommand()->update('{{settings_global}}', array('stg_value' => 474), "stg_name='DBVersion'"); + $oDB->createCommand()->createIndex('{{idx5_labels}}', '{{labels}}', ['lid','code'], true); + $oDB->createCommand()->update('{{settings_global}}', array('stg_value' => 475), "stg_name='DBVersion'"); $oTransaction->commit(); } } catch (Exception $e) { @@ -8075,3 +8035,46 @@ function runAddPrimaryKeyonAnswersTable400(&$oDB) $oDB->createCommand()->dropTable('answertemp'); } } + +/** + * Regenerate codes for problematic label sets + * Helper function (TODO: Put in separate class) + * Fails silently + * + * @param int $lid Label set id + * @return void + */ +function regenerateLabelCodes400(int $lid) +{ + $oDB = Yii::app()->getDb(); + + $labelSet = $oDB->createCommand( + sprintf("SELECT * FROM {{labelsets}} WHERE lid = %d", (int) $lid) + )->queryRow(); + if (empty($labelSet)) { + return; + } + + foreach (explode(',', $labelSet['languages']) as $lang) { + $labels = $oDB->createCommand( + sprintf( + "SELECT * FROM {{labels}} WHERE lid = %d AND language = %s", + (int) $lid, + $oDB->quoteValue($lang) + ) + )->queryAll(); + if (empty($labels)) { + continue; + } + foreach ($labels as $key => $label) { + $oDB->createCommand( + sprintf( + "UPDATE {{labels}} SET code = %s WHERE id = %d", + // Use simply nr as label code + $oDB->quoteValue((string) $key + 1), + $label['id'] + ) + )->execute(); + } + } +} diff --git a/installer/create-database.php b/installer/create-database.php index ccfb4bf18a9..6daaf44aae4 100755 --- a/installer/create-database.php +++ b/installer/create-database.php @@ -175,6 +175,7 @@ function populateDatabase($oDB) $oDB->createCommand()->createIndex('{{idx1_labels}}', '{{labels}}', 'code', false); $oDB->createCommand()->createIndex('{{idx2_labels}}', '{{labels}}', 'sortorder', false); $oDB->createCommand()->createIndex('{{idx4_labels}}', '{{labels}}', ['lid','sortorder'], false); + $oDB->createCommand()->createIndex('{{idx5_labels}}', '{{labels}}', ['lid','code'], true); // label_l10ns $oDB->createCommand()->createTable('{{label_l10ns}}', array(