mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°3065 - Failed enum comparison when values contains parenthesis - enhance db model parsing used during setup comparison with expected one to generate SQL migration queries
This commit is contained in:
@@ -1181,7 +1181,8 @@ class CMDBSource
|
||||
}
|
||||
|
||||
/**
|
||||
* There may have some differences between DB : for example in MySQL 5.7 we have "INT", while in MariaDB >= 10.2 you get "int DEFAULT 'NULL'"
|
||||
* There may have some differences between DB : for example in MySQL 5.7 we have "INT", while in MariaDB >= 10.2 you get "int DEFAULT
|
||||
* 'NULL'"
|
||||
*
|
||||
* We still do a case sensitive comparison for enum values !
|
||||
*
|
||||
@@ -1192,6 +1193,7 @@ class CMDBSource
|
||||
* @param string $sDbFieldType
|
||||
*
|
||||
* @return bool true if same type and options (case sensitive comparison only for type options), false otherwise
|
||||
* @throws \CoreException
|
||||
* @since 2.7.0 N°2490
|
||||
*/
|
||||
public static function IsSameFieldTypes($sItopGeneratedFieldType, $sDbFieldType)
|
||||
@@ -1245,18 +1247,55 @@ class CMDBSource
|
||||
* 1. data type : for example 'VARCHAR'
|
||||
* 2. type value : for example '255'
|
||||
* 3. other options : for example ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 0'
|
||||
* @throws \CoreException
|
||||
*/
|
||||
private static function GetFieldDataTypeAndOptions($sCompleteFieldType)
|
||||
{
|
||||
preg_match('/^([a-zA-Z]+)(\(([^\)]+)\))?( .+)?/', $sCompleteFieldType, $aMatches);
|
||||
|
||||
$sDataType = isset($aMatches[1]) ? $aMatches[1] : '';
|
||||
|
||||
if (strcasecmp($sDataType, 'ENUM') === 0){
|
||||
return self::GetEnumOptions($sDataType, $sCompleteFieldType);
|
||||
}
|
||||
|
||||
$sTypeOptions = isset($aMatches[2]) ? $aMatches[3] : '';
|
||||
$sOtherOptions = isset($aMatches[4]) ? $aMatches[4] : '';
|
||||
|
||||
return array($sDataType, $sTypeOptions, $sOtherOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.4 N°3065
|
||||
* Handle ENUM options
|
||||
*
|
||||
* @param $sDataType
|
||||
* @param $sCompleteFieldType
|
||||
* Example: ENUM('CSP A','CSP (aaaa) M','NA','OEM(ROC)','OPEN(VL)','RETAIL (Boite)') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
||||
*
|
||||
* @return string[] consisting of 3 items :
|
||||
* 1. data type : ENUM or enum here
|
||||
* 2. type value : in-between EUM parenthesis
|
||||
* 3. other options : for example ' CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 0'
|
||||
* @throws \CoreException
|
||||
*/
|
||||
private static function GetEnumOptions($sDataType, $sCompleteFieldType)
|
||||
{
|
||||
$iFirstOpeningParenthesis = strpos($sCompleteFieldType, '(');
|
||||
$iLastEndingParenthesis = strrpos($sCompleteFieldType, ')');
|
||||
|
||||
if ($iFirstOpeningParenthesis === false || $iLastEndingParenthesis === false ){
|
||||
//should never happen as GetFieldDataTypeAndOptions regexp matched.
|
||||
//except if regexp is modiied/broken somehow one day...
|
||||
throw new CoreException("GetEnumOptions issue with $sDataType parsing : " . $sCompleteFieldType);
|
||||
}
|
||||
|
||||
$sTypeOptions = substr($sCompleteFieldType, $iFirstOpeningParenthesis + 1, $iLastEndingParenthesis - 1);
|
||||
$sOtherOptions = substr($sCompleteFieldType, $iLastEndingParenthesis + 1);
|
||||
|
||||
return array($sDataType, $sTypeOptions, $sOtherOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTable
|
||||
* @param string $sField
|
||||
|
||||
@@ -5545,15 +5545,10 @@ abstract class MetaModel
|
||||
|
||||
// The field already exists, does it have the relevant properties?
|
||||
//
|
||||
$bToBeChanged = false;
|
||||
$sActualFieldSpec = CMDBSource::GetFieldSpec($sTable, $sField);
|
||||
if (!CMDBSource::IsSameFieldTypes($sDBFieldSpec, $sActualFieldSpec))
|
||||
{
|
||||
$bToBeChanged = true;
|
||||
$aErrors[$sClass][$sAttCode][] = "field '$sField' in table '$sTable' has a wrong type: found <code>$sActualFieldSpec</code> while expecting <code>$sDBFieldSpec</code>";
|
||||
}
|
||||
if ($bToBeChanged)
|
||||
{
|
||||
$aSugFix[$sClass][$sAttCode][] = "ALTER TABLE `$sTable` CHANGE `$sField` $sFieldDefinition";
|
||||
$aAlterTableItems[$sTable][$sField] = "CHANGE `$sField` $sFieldDefinition";
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class CMDBSourceTest extends ItopTestCase
|
||||
*/
|
||||
public function testCompareFieldTypes($bResult, $sItopFieldType, $sDbFieldType)
|
||||
{
|
||||
$this->assertEquals($bResult, CMDBSource::IsSameFieldTypes($sItopFieldType, $sDbFieldType));
|
||||
$this->assertEquals($bResult, CMDBSource::IsSameFieldTypes($sItopFieldType, $sDbFieldType), "$sItopFieldType\n VS\n $sDbFieldType");
|
||||
}
|
||||
|
||||
public function compareFieldTypesProvider()
|
||||
@@ -106,12 +106,12 @@ class CMDBSourceTest extends ItopTestCase
|
||||
"ENUM('CSP A','CSP M','NA','OEM(ROC)','OPEN(VL)','RETAIL (Boite)') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
"enum('CSP A','CSP M','NA','OEM(ROC)','OPEN(VL)','RETAIL (Boite)') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
),
|
||||
//FIXME N°3065 before the fix this returns true :(
|
||||
// 'ENUM with different values, containing parenthesis' => array(
|
||||
// false,
|
||||
// "ENUM('value 1 (with parenthesis)','value 2') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
// "enum('value 1 (with parenthesis)','value 3') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
// ),
|
||||
//FIXME N°3065 before the fix this returns true :(
|
||||
'ENUM with different values, containing parenthesis' => array(
|
||||
false,
|
||||
"ENUM('value 1 (with parenthesis)','value 2') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
"enum('value 1 (with parenthesis)','value 3') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user