Bläddra i källkod

#975 Continuation of the fix implemented in [r3431] - Renaming an enum requires to call RenameEnumValueInDB

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3438 a333f486-631f-4898-b8df-5754b55c2be0
romainq 10 år sedan
förälder
incheckning
269c124a56

+ 1 - 0
datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php

@@ -89,6 +89,7 @@ if (!class_exists('ConfigMgmtInstaller'))
 				self::RenameEnumValueInDB('Software', 'type', 'Webserver', 'WebServer');
 				self::RenameEnumValueInDB('Model', 'type', 'SANswitch', 'SANSwitch');
 				self::RenameEnumValueInDB('Model', 'type', 'IpPhone', 'IPPhone');
+				self::RenameEnumValueInDB('Model', 'type', 'Telephone', 'Phone');
 				self::RenameClassInDB('DBserver', 'DBServer');
 				self::RenameClassInDB('OSfamily', 'OSFamily');
 				self::RenameClassInDB('OSversion', 'OSVersion');

+ 64 - 32
setup/moduleinstaller.class.inc.php

@@ -91,6 +91,7 @@ abstract class ModuleInstallerAPI
 	 * Helper to modify an enum value	
 	 * The change is made in the datamodel definition, but the value has to be changed in the DB as well	 	 
 	 * Must be called BEFORE DB update, i.e within an implementation of BeforeDatabaseCreation()
+	 * This helper does change ONE value at a time	 
 	 * 	 
 	 * @param string $sClass A valid class name
 	 * @param string $sAttCode The enum attribute code
@@ -112,42 +113,73 @@ abstract class ModuleInstallerAPI
 				$aNewValues = array_keys($oValDef->GetValues(array(), ""));
 				if (in_array($sTo, $aNewValues))
 				{
-					$aAllValues = $aNewValues;
-					$aAllValues[] = $sFrom;
-					if (!in_array($sFrom, $aNewValues))
+					$sEnumCol = $oAttDef->Get("sql");
+					$aFields = CMDBSource::QueryToArray("SHOW COLUMNS FROM `$sTableName` WHERE Field = '$sEnumCol'");
+					if (isset($aFields[0]['Type']))
 					{
-						$sEnumCol = $oAttDef->Get("sql");
-						$sNullSpec = $oAttDef->IsNullAllowed() ? 'NULL' : 'NOT NULL';
-
-						if (strtolower($sTo) == strtolower($sFrom))
+						$sColType = $aFields[0]['Type'];
+						// Note: the parsing should rely on str_getcsv (requires PHP 5.3) to cope with escaped string
+						if (preg_match("/^enum\(\'(.*)\'\)$/", $sColType, $aMatches))
 						{
-							SetupPage::log_info("Changing enum in DB - $sClass::$sAttCode from '$sFrom' to '$sTo' (just a change in the case)"); 
-							$sColumnDefinition = "ENUM(".implode(",", CMDBSource::Quote($aNewValues)).") $sNullSpec";
-							$sRepair = "ALTER TABLE `$sTableName` MODIFY `$sEnumCol` $sColumnDefinition";
-							CMDBSource::Query($sRepair);
+							$aCurrentValues = explode("','", $aMatches[1]);
 						}
-						else
+					}
+					if (!in_array($sFrom, $aNewValues))
+					{
+						if (!in_array($sTo, $aCurrentValues)) // if not already transformed!
 						{
-							// 1st - Allow both values in the column definition
-							//
-							SetupPage::log_info("Changing enum in DB - $sClass::$sAttCode from '$sFrom' to '$sTo'"); 
-							$sColumnDefinition = "ENUM(".implode(",", CMDBSource::Quote($aAllValues)).") $sNullSpec";
-							$sRepair = "ALTER TABLE `$sTableName` MODIFY `$sEnumCol` $sColumnDefinition";
-							CMDBSource::Query($sRepair);
-			
-							// 2nd - Change the old value into the new value
-							//
-							$sRepair = "UPDATE `$sTableName` SET `$sEnumCol` = '$sTo' WHERE `$sEnumCol` = BINARY '$sFrom'";
-							CMDBSource::Query($sRepair);
-							$iAffectedRows = CMDBSource::AffectedRows();
-							SetupPage::log_info("Changing enum in DB - $iAffectedRows rows updated"); 
-			
-							// 3rd - Remove the useless value from the column definition
-							//
-							$sColumnDefinition = "ENUM(".implode(",", CMDBSource::Quote($aNewValues)).") $sNullSpec";
-							$sRepair = "ALTER TABLE `$sTableName` MODIFY `$sEnumCol` $sColumnDefinition";
-							CMDBSource::Query($sRepair);
-							SetupPage::log_info("Changing enum in DB - removed useless value '$sFrom'");
+							$sNullSpec = $oAttDef->IsNullAllowed() ? 'NULL' : 'NOT NULL';
+	
+							if (strtolower($sTo) == strtolower($sFrom))
+							{
+								SetupPage::log_info("Changing enum in DB - $sClass::$sAttCode from '$sFrom' to '$sTo' (just a change in the case)"); 
+								$aTargetValues = array();
+								foreach ($aCurrentValues as $sValue)
+								{
+									if ($sValue == $sFrom)
+									{
+										$sValue = $sTo;
+									}
+									$aTargetValues[] = $sValue;
+								}
+								$sColumnDefinition = "ENUM(".implode(",", CMDBSource::Quote($aTargetValues)).") $sNullSpec";
+								$sRepair = "ALTER TABLE `$sTableName` MODIFY `$sEnumCol` $sColumnDefinition";
+								CMDBSource::Query($sRepair);
+							}
+							else
+							{
+								// 1st - Allow both values in the column definition
+								//
+								SetupPage::log_info("Changing enum in DB - $sClass::$sAttCode from '$sFrom' to '$sTo'"); 
+								$aAllValues = $aCurrentValues;
+								$aAllValues[] = $sTo;
+								$sColumnDefinition = "ENUM(".implode(",", CMDBSource::Quote($aAllValues)).") $sNullSpec";
+								$sRepair = "ALTER TABLE `$sTableName` MODIFY `$sEnumCol` $sColumnDefinition";
+								CMDBSource::Query($sRepair);
+				
+								// 2nd - Change the old value into the new value
+								//
+								$sRepair = "UPDATE `$sTableName` SET `$sEnumCol` = '$sTo' WHERE `$sEnumCol` = BINARY '$sFrom'";
+								CMDBSource::Query($sRepair);
+								$iAffectedRows = CMDBSource::AffectedRows();
+								SetupPage::log_info("Changing enum in DB - $iAffectedRows rows updated"); 
+				
+								// 3rd - Remove the useless value from the column definition
+								//
+								$aTargetValues = array();
+								foreach ($aCurrentValues as $sValue)
+								{
+									if ($sValue == $sFrom)
+									{
+										$sValue = $sTo;
+									}
+									$aTargetValues[] = $sValue;
+								}
+								$sColumnDefinition = "ENUM(".implode(",", CMDBSource::Quote($aTargetValues)).") $sNullSpec";
+								$sRepair = "ALTER TABLE `$sTableName` MODIFY `$sEnumCol` $sColumnDefinition";
+								CMDBSource::Query($sRepair);
+								SetupPage::log_info("Changing enum in DB - removed useless value '$sFrom'");
+							}
 						}
 					}
 					else