Browse Source

Upgrade/toolkit: improved the data sources update procedure (no need to create "direct" linkset attributes, remove old attributes, more verbose)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1532 a333f486-631f-4898-b8df-5754b55c2be0
romainq 13 years ago
parent
commit
cf39270e2c
1 changed files with 92 additions and 55 deletions
  1. 92 55
      synchro/synchrodatasource.class.inc.php

+ 92 - 55
synchro/synchrodatasource.class.inc.php

@@ -696,10 +696,10 @@ EOF
 		$aColumns = $this->GetSQLColumns();
 		$aResult = array();
 
-		$sTriggerInsert = "CREATE TRIGGER `{$sTable}_bi` BEFORE INSERT ON $sTable";
+		$sTriggerInsert = "CREATE TRIGGER `{$sTable}_bi` BEFORE INSERT ON `$sTable`";
 		$sTriggerInsert .= "   FOR EACH ROW";
 		$sTriggerInsert .= "   BEGIN";
-		$sTriggerInsert .= "      INSERT INTO {$sReplicaTable} (sync_source_id, status_last_seen, `status`) VALUES ({$this->GetKey()}, NOW(), 'new');";
+		$sTriggerInsert .= "      INSERT INTO `{$sReplicaTable}` (`sync_source_id`, `status_last_seen`, `status`) VALUES ({$this->GetKey()}, NOW(), 'new');";
 		$sTriggerInsert .= "      SET NEW.id = LAST_INSERT_ID();";
 		$sTriggerInsert .= "   END;";
 		$aResult['bi'] = $sTriggerInsert;
@@ -717,20 +717,20 @@ EOF
 		// status is forced to "new" if the replica was obsoleted directly from the state "new" (dest_id = null)
 		// otherwise, if status was either 'obsolete' or 'synchronized' it is turned into 'modified' or 'synchronized' depending on the changes
 		// otherwise, the status is left as is
-		$sTriggerUpdate = "CREATE TRIGGER `{$sTable}_bu` BEFORE UPDATE ON $sTable";
+		$sTriggerUpdate = "CREATE TRIGGER `{$sTable}_bu` BEFORE UPDATE ON `$sTable`";
 		$sTriggerUpdate .= "   FOR EACH ROW";
 		$sTriggerUpdate .= "   BEGIN";
 		$sTriggerUpdate .= "      IF @itopuser is null THEN";
-		$sTriggerUpdate .= "         UPDATE {$sReplicaTable} SET status_last_seen = NOW(), `status` = IF(`status` = 'obsolete', IF(`dest_id` IS NULL, 'new', 'modified'), IF(`status` IN ('synchronized') AND ($sIsModified), 'modified', `status`)) WHERE sync_source_id = {$this->GetKey()} AND id = OLD.id;";
+		$sTriggerUpdate .= "         UPDATE `{$sReplicaTable}` SET status_last_seen = NOW(), `status` = IF(`status` = 'obsolete', IF(`dest_id` IS NULL, 'new', 'modified'), IF(`status` IN ('synchronized') AND ($sIsModified), 'modified', `status`)) WHERE sync_source_id = {$this->GetKey()} AND id = OLD.id;";
 		$sTriggerUpdate .= "         SET NEW.id = OLD.id;"; // make sure this id won't change
 		$sTriggerUpdate .= "      END IF;";
 		$sTriggerUpdate .= "   END;";
 		$aResult['bu'] = $sTriggerUpdate;
 
-		$sTriggerDelete = "CREATE TRIGGER `{$sTable}_ad` AFTER DELETE ON $sTable";
+		$sTriggerDelete = "CREATE TRIGGER `{$sTable}_ad` AFTER DELETE ON `$sTable`";
 		$sTriggerDelete .= "   FOR EACH ROW";
 		$sTriggerDelete .= "   BEGIN";
-		$sTriggerDelete .= "      DELETE FROM {$sReplicaTable} WHERE id = OLD.id;";
+		$sTriggerDelete .= "      DELETE FROM `{$sReplicaTable}` WHERE id = OLD.id;";
 		$sTriggerDelete .= "   END;";
 		$aResult['ad'] = $sTriggerDelete;
 		return $aResult;
@@ -762,64 +762,91 @@ EOF
 
 		while($oAttribute = $oAttributeSet->Fetch())
 		{
-			$aAttributes[$oAttribute->Get('attcode')] = $oAttribute;
+			$sAttCode = $oAttribute->Get('attcode');
+			if (MetaModel::IsValidAttCode($this->GetTargetClass(), $sAttCode))
+			{ 
+				$aAttributes[$sAttCode] = $oAttribute;
+			}
+			else
+			{
+				// Old field remaining
+				if ($bVerbose)
+				{
+					echo "Irrelevant field description for the field '$sAttCode', for the data synchro task ".$this->GetName()." (".$this->GetKey()."), will be removed.\n";
+				}
+				$bFixNeeded = true;
+				if (!$bDiagnostics)
+				{
+					if ($oChange == null)
+					{
+						$oChange = MetaModel::NewObject("CMDBChange");
+						$oChange->Set("date", time());
+						$sUserString = CMDBChange::GetCurrentUserName();
+						$oChange->Set("userinfo", $sUserString);
+						$oChange->DBInsert();	
+					}
+					// Fix the issue
+					$oAttribute->DBDeleteTracked($oChange);
+				}
+			}
+
 		}
 
-		foreach(MetaModel::ListAttributeDefs($this->GetTargetClass()) as $sAttCode=>$oAttDef)
+		foreach($this->ListTargetAttributes() as $sAttCode=>$oAttDef)
 		{
-			if ($oAttDef->IsWritable())
+			if (!isset($aAttributes[$sAttCode]))
 			{
-				if (!isset($aAttributes[$sAttCode]))
+				$bFixNeeded = true;
+				$aMissingFields[] = $sAttCode;
+				// New field missing...
+				if ($bVerbose)
+				{
+					echo "Missing field description for the field '$sAttCode', for the data synchro task ".$this->GetName()." (".$this->GetKey()."), will be created with default values.\n";
+				}
+				if (!$bDiagnostics)
 				{
-					$bFixNeeded = true;
-					$aMissingFields[] = $sAttCode;
-					// New field missing...
-					if ($bDiagnostics)
+					if ($oChange == null)
 					{
-						// Report the issue
-						if ($bVerbose)
-						{
-							echo "Missing field description for the field '$sAttCode', for the data synchro task ".$this->GetName()." (".$this->GetKey()."), will be created with default values.\n";
-						}
-					}
-					else
-					{
-						if ($oChange == null)
-						{
-							$oChange = MetaModel::NewObject("CMDBChange");
-							$oChange->Set("date", time());
-							$sUserString = CMDBChange::GetCurrentUserName();
-							$oChange->Set("userinfo", $sUserString);
-							$oChange->DBInsert();	
-						}
-						// Fix the issue
-						$oAttribute = $this->CreateSynchroAtt($sAttCode);
-						$oAttribute->DBInsertTracked($oChange);
+						$oChange = MetaModel::NewObject("CMDBChange");
+						$oChange->Set("date", time());
+						$sUserString = CMDBChange::GetCurrentUserName();
+						$oChange->Set("userinfo", $sUserString);
+						$oChange->DBInsert();	
 					}
+					// Fix the issue
+					$oAttribute = $this->CreateSynchroAtt($sAttCode);
+					$oAttribute->DBInsertTracked($oChange);
 				}
 			}
 		}
 		$sTable = $this->GetDataTable();
-		if ($bFixNeeded)
+		if ($bFixNeeded && (count($aMissingFields) > 0))
 		{
+			$aRepairQueries = array();
+
 			// The structure of the table needs adjusting
 			$aColumns = $this->GetSQLColumns($aMissingFields);
 			$aFieldDefs = array();
 			foreach($aColumns as $sAttCode => $sColumnDef)
 			{
-				$aFieldDefs[] = "$sAttCode $sColumnDef";
+				if (CMDBSource::IsField($sTable, $sAttCode))
+				{
+					$aRepairQueries[] = "ALTER TABLE `$sTable` DROP COLUMN `$sAttCode`;";
+				}
+
+				$aFieldDefs[] = "`$sAttCode` $sColumnDef";
 			}
-			$sAlterTable = "ALTER TABLE `$sTable` ADD (".implode(',', $aFieldDefs).");";
+
+			$aRepairQueries[] = "ALTER TABLE `$sTable` ADD (".implode(',', $aFieldDefs).");";
 
 			// The triggers as well must be adjusted
-			$aTriggers = array();
 			$aTriggersDefs = $this->GetTriggersDefinition();
-			$aTriggers[] = "DROP TRIGGER IF EXISTS {$sTable}_bi;";
-			$aTriggers[] = $aTriggersDefs['bi'];
-			$aTriggers[] = "DROP TRIGGER IF EXISTS {$sTable}_bu;";
-			$aTriggers[] = $aTriggersDefs['bu'];
-			$aTriggers[] = "DROP TRIGGER IF EXISTS {$sTable}_ad;";
-			$aTriggers[] = $aTriggersDefs['ad'];
+			$aRepairQueries[] = "DROP TRIGGER IF EXISTS `{$sTable}_bi`;";
+			$aRepairQueries[] = $aTriggersDefs['bi'];
+			$aRepairQueries[] = "DROP TRIGGER IF EXISTS `{$sTable}_bu`;";
+			$aRepairQueries[] = $aTriggersDefs['bu'];
+			$aRepairQueries[] = "DROP TRIGGER IF EXISTS `{$sTable}_ad`;";
+			$aRepairQueries[] = $aTriggersDefs['ad'];
 			
 			if ($bDiagnostics)
 			{
@@ -827,21 +854,14 @@ EOF
 				{
 					// Report the issue
 					echo "The structure of the table $sTable for the data synchro task ".$this->GetName()." (".$this->GetKey().") must be altered (missing fields: ".implode(',', $aMissingFields).").\n";
-					echo "$sAlterTable\n";
 					echo "The trigger {$sTable}_bi, {$sTable}_bu, {$sTable}_ad for the data synchro task ".$this->GetName()." (".$this->GetKey().") must be re-created.\n";
-					echo implode("\n", $aTriggers)."\n";
+					echo implode("\n", $aRepairQueries)."\n";
 				}
 			}
 			else
 			{
 				// Fix the issue
-				CMDBSource::Query($sAlterTable);
-				if ($bVerbose)
-				{
-					echo "$sAlterTable\n";
-				}
-
-				foreach($aTriggers as $sSQL)
+				foreach($aRepairQueries as $sSQL)
 				{
 					CMDBSource::Query($sSQL);
 					if ($bVerbose)
@@ -851,7 +871,7 @@ EOF
 				}
 			}
 		}
-			
+
 		return $bFixNeeded;
 	}
 	protected function SendNotification($sSubject, $sBody)
@@ -1193,6 +1213,24 @@ EOF
 			}
 		}
 	}
+
+	/**
+	 * Get the list of attributes eligible to the synchronization	 
+	 */
+	public function ListTargetAttributes()
+	{
+		$aRet = array();
+		foreach(MetaModel::ListAttributeDefs($this->GetTargetClass()) as $sAttCode => $oAttDef)
+		{
+			if ($sAttCode == 'finalclass') continue;
+			if (!$oAttDef->IsWritable()) continue;
+			if ($oAttDef->IsLinkSet() && !$oAttDef->IsIndirect()) continue;
+
+			$aRet[$sAttCode] = $oAttDef;
+		}
+		return $aRet;
+	}
+
 	
 	/**
 	 * Get the list of SQL columns corresponding to a particular list of attribute codes
@@ -1206,9 +1244,8 @@ EOF
 		if (is_null($aAttributeCodes))
 		{
 			$aAttributeCodes = array();
-			foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
+			foreach($this->ListTargetAttributes() as $sAttCode => $oAttDef)
 			{
-				if ($sAttCode == 'finalclass') continue;
 				$aAttributeCodes[] = $sAttCode;
 			}
 		}