From 1800120762ad238d0744e2df3d147896b8b055d1 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 2 Nov 2010 16:29:41 +0000 Subject: [PATCH] #311 CSV import: Improved the reporting on external keys (and changed a little the behavior) SVN:trunk[936] --- core/bulkchange.class.inc.php | 165 ++++++++++++++++++++++++++-------- pages/csvimport.php | 9 +- webservices/import.php | 2 + 3 files changed, 138 insertions(+), 38 deletions(-) diff --git a/core/bulkchange.class.inc.php b/core/bulkchange.class.inc.php index df074ed11..813ac532a 100644 --- a/core/bulkchange.class.inc.php +++ b/core/bulkchange.class.inc.php @@ -127,6 +127,33 @@ class CellStatus_Issue extends CellStatus_Modify } } +class CellStatus_SearchIssue extends CellStatus_Issue +{ + public function __construct() + { + parent::__construct(null, null, null); + } + + public function GetDescription() + { + return 'No match'; + } +} + +class CellStatus_NullIssue extends CellStatus_Issue +{ + public function __construct() + { + parent::__construct(null, null, null); + } + + public function GetDescription() + { + return 'Missing mandatory value'; + } +} + + class CellStatus_Ambiguous extends CellStatus_Issue { protected $m_iCount; @@ -247,6 +274,21 @@ class BulkChange return array($oReconFilter->ToOql(), $aKeys); } + // Returns true if the CSV data specifies that the external key must be left undefined + protected function IsNullExternalKeySpec($aRowData, $sAttCode) + { + $oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode); + foreach ($this->m_aExtKeys[$sAttCode] as $sForeignAttCode => $iCol) + { + // The foreign attribute is one of our reconciliation key + if (strlen($aRowData[$iCol]) > 0) + { + return false; + } + } + return true; + } + protected function PrepareObject(&$oTargetObj, $aRowData, &$aErrors) { $aResults = array(); @@ -260,36 +302,49 @@ class BulkChange // if (!array_key_exists($sAttCode, $this->m_aAttList)) continue; $oExtKey = MetaModel::GetAttributeDef(get_class($oTargetObj), $sAttCode); - $oReconFilter = new CMDBSearchFilter($oExtKey->GetTargetClass()); - foreach ($aKeyConfig as $sForeignAttCode => $iCol) + + if ($this->IsNullExternalKeySpec($aRowData, $sAttCode)) { - // The foreign attribute is one of our reconciliation key - $oReconFilter->AddCondition($sForeignAttCode, $aRowData[$iCol], '='); - $aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]); - } - $oExtObjects = new CMDBObjectSet($oReconFilter); - switch($oExtObjects->Count()) - { - case 0: + foreach ($aKeyConfig as $sForeignAttCode => $iCol) + { + $aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]); + } if ($oExtKey->IsNullAllowed()) { $oTargetObj->Set($sAttCode, $oExtKey->GetNullValue()); - $aResults[$sAttCode]= new CellStatus_Issue(null, $oTargetObj->Get($sAttCode), 'Object not found'); + $aResults[$sAttCode]= new CellStatus_Void($oExtKey->GetNullValue()); } else { - $aErrors[$sAttCode] = "Object not found"; - $aResults[$sAttCode]= new CellStatus_Issue(null, $oTargetObj->Get($sAttCode), 'Object not found'); + $aErrors[$sAttCode] = "Null not allowed"; + $aResults[$sAttCode]= new CellStatus_Issue(null, $oTargetObj->Get($sAttCode), 'Null not allowed'); + } + } + else + { + $oReconFilter = new CMDBSearchFilter($oExtKey->GetTargetClass()); + foreach ($aKeyConfig as $sForeignAttCode => $iCol) + { + // The foreign attribute is one of our reconciliation key + $oReconFilter->AddCondition($sForeignAttCode, $aRowData[$iCol], '='); + $aResults[$iCol] = new CellStatus_Void($aRowData[$iCol]); + } + $oExtObjects = new CMDBObjectSet($oReconFilter); + switch($oExtObjects->Count()) + { + case 0: + $aErrors[$sAttCode] = "Object not found"; + $aResults[$sAttCode]= new CellStatus_SearchIssue(); + break; + case 1: + // Do change the external key attribute + $oForeignObj = $oExtObjects->Fetch(); + $oTargetObj->Set($sAttCode, $oForeignObj->GetKey()); + break; + default: + $aErrors[$sAttCode] = "Found ".$oExtObjects->Count()." matches"; + $aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $oExtObjects->Count(), $oReconFilter->ToOql()); } - break; - case 1: - // Do change the external key attribute - $oForeignObj = $oExtObjects->Fetch(); - $oTargetObj->Set($sAttCode, $oForeignObj->GetKey()); - break; - default: - $aErrors[$sAttCode] = "Found ".$oExtObjects->Count()." matches"; - $aResults[$sAttCode]= new CellStatus_Ambiguous($oTargetObj->Get($sAttCode), $oExtObjects->Count(), $oReconFilter->ToOql()); } // Report @@ -461,7 +516,24 @@ class BulkChange public function Process(CMDBChange $oChange = null) { // Note: $oChange can be null, in which case the aim is to check what would be done - + + // Debug... + // + if (false) + { + echo "
\n";
+			echo "Attributes:\n";
+			print_r($this->m_aAttList);
+			echo "ExtKeys:\n";
+			print_r($this->m_aExtKeys);
+			echo "Reconciliation:\n";
+			print_r($this->m_aReconcilKeys);
+			//echo "Data:\n";
+			//print_r($this->m_aData);
+			echo "
\n"; + exit; + } + // Compute the results // $aResult = array(); @@ -474,22 +546,38 @@ class BulkChange $valuecondition = null; if (array_key_exists($sAttCode, $this->m_aExtKeys)) { - // The value has to be found or verified - list($sQuery, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]); - - if (count($aMatches) == 1) + if ($this->IsNullExternalKeySpec($aRowData, $sAttCode)) { - $oRemoteObj = reset($aMatches); // first item - $valuecondition = $oRemoteObj->GetKey(); - $aResult[$iRow][$sAttCode] = new CellStatus_Void($oRemoteObj->GetKey()); - } - elseif (count($aMatches) == 0) - { - $aResult[$iRow][$sAttCode] = new CellStatus_Issue(null, null, 'object not found'); - } + $oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode); + if ($oExtKey->IsNullAllowed()) + { + $valuecondition = $oExtKey->GetNullValue(); + $aResult[$iRow][$sAttCode] = new CellStatus_Void($oExtKey->GetNullValue()); + } + else + { + $aResult[$iRow][$sAttCode] = new CellStatus_NullIssue(); + } + } else { - $aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $sQuery); + // The value has to be found or verified + list($sQuery, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]); + + if (count($aMatches) == 1) + { + $oRemoteObj = reset($aMatches); // first item + $valuecondition = $oRemoteObj->GetKey(); + $aResult[$iRow][$sAttCode] = new CellStatus_Void($oRemoteObj->GetKey()); + } + elseif (count($aMatches) == 0) + { + $aResult[$iRow][$sAttCode] = new CellStatus_SearchIssue(); + } + else + { + $aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $sQuery); + } } } else @@ -546,7 +634,10 @@ class BulkChange if (!array_key_exists($sAttCode, $aResult[$iRow])) { $aResult[$iRow][$sAttCode] = new CellStatus_Void('n/a'); - foreach ($aForeignAtts as $sForeignAttCode => $iCol) + } + foreach ($aForeignAtts as $sForeignAttCode => $iCol) + { + if (!array_key_exists($iCol, $aResult[$iRow])) { // The foreign attribute is one of our reconciliation key $aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]); diff --git a/pages/csvimport.php b/pages/csvimport.php index c924cb32d..fe9767cf2 100644 --- a/pages/csvimport.php +++ b/pages/csvimport.php @@ -337,7 +337,7 @@ try $oPage->add(''); $aRes = $oBulk->Process($oMyChange); - + $sHtml = ''; $sHtml .= ''; $sHtml .= ''; @@ -429,6 +429,8 @@ try switch(get_class($oExtKeyCellStatus)) { case 'CellStatus_Issue': + case 'CellStatus_SearchIssue': + case 'CellStatus_NullIssue': $sCellMessage .= $oPage->GetP($oExtKeyCellStatus->GetDescription()); break; @@ -447,6 +449,11 @@ try $sHtml .= ''; break; + case 'CellStatus_SearchIssue': + $sCellMessage .= $oPage->GetP($oCellStatus->GetDescription()); + $sHtml .= ''; + break; + case 'CellStatus_Ambiguous': $sCellMessage .= $oPage->GetP($oCellStatus->GetDescription()); $sHtml .= ''; diff --git a/webservices/import.php b/webservices/import.php index c95af98e2..e9aa5cf78 100644 --- a/webservices/import.php +++ b/webservices/import.php @@ -549,6 +549,8 @@ try case 'CellStatus_Modify': break; case 'CellStatus_Issue': + case 'CellStatus_SearchIssue': + case 'CellStatus_NullIssue': case 'CellStatus_Ambiguous': $iCountWarnings++; break;
LineStatusERROR: '.htmlentities($aData[$iLine][$iNumber-1], ENT_QUOTES, 'UTF-8').$sCellMessage.'ERROR: '.htmlentities($aData[$iLine][$iNumber-1], ENT_QUOTES, 'UTF-8').$sCellMessage.'AMBIGUOUS: '.htmlentities($aData[$iLine][$iNumber-1], ENT_QUOTES, 'UTF-8').$sCellMessage.'