Explorar o código

Archive: Experimental API DBSearch::DBBulkWriteArchiveFlag, to quickly archive a huge number of objects (minimizes the number of queries needed to do the job, skips object change handlers, and DOES NOT RECORD the change in the history of object changes -that limitation could be fixed later)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@4807 a333f486-631f-4898-b8df-5754b55c2be0
romainq %!s(int64=8) %!d(string=hai) anos
pai
achega
d87bfaada7
Modificáronse 1 ficheiros con 75 adicións e 0 borrados
  1. 75 0
      core/dbsearch.class.php

+ 75 - 0
core/dbsearch.class.php

@@ -760,4 +760,79 @@ abstract class DBSearch
 			echo "$sIndent$sFunction: $value<br/>\n";
 		}
 	}
+
+	/**
+	 * Experimental!
+	 * todo: implement the change tracking
+	 *
+	 * @param $bArchive
+	 * @throws Exception
+	 */
+	function DBBulkWriteArchiveFlag($bArchive)
+	{
+		$sClass = $this->GetClass();
+		if (!MetaModel::IsArchivable($sClass))
+		{
+			throw new Exception($sClass.' is not an archivable class');
+		}
+
+		$iFlag = $bArchive ? 1 : 0;
+
+		$oSet = new DBObjectSet($this);
+		if (MetaModel::IsStandaloneClass($sClass))
+		{
+			$oSet->OptimizeColumnLoad(array($this->GetClassAlias() => array('')));
+			$aIds = array($sClass => $oSet->GetColumnAsArray('id'));
+		}
+		else
+		{
+			$oSet->OptimizeColumnLoad(array($this->GetClassAlias() => array('finalclass')));
+			$aTemp = $oSet->GetColumnAsArray('finalclass');
+			$aIds = array();
+			foreach ($aTemp as $iObjectId => $sObjectClass)
+			{
+				$aIds[$sObjectClass][$iObjectId] = $iObjectId;
+			}
+		}
+		foreach ($aIds as $sFinalClass => $aObjectIds)
+		{
+			$sIds = implode(', ', $aObjectIds);
+
+			$sArchiveRoot = MetaModel::GetAttributeOrigin($sFinalClass, 'archive_flag');
+			$sRootTable = MetaModel::DBGetTable($sArchiveRoot);
+			$sRootKey = MetaModel::DBGetKey($sArchiveRoot);
+			$aJoins = array("`$sRootTable`");
+			$aUpdates = array();
+			foreach (MetaModel::EnumParentClasses($sFinalClass, ENUM_PARENT_CLASSES_ALL) as $sParentClass)
+			{
+				if (!MetaModel::IsValidAttCode($sParentClass, 'archive_flag')) continue;
+
+				$sTable = MetaModel::DBGetTable($sParentClass);
+				$aUpdates[] = "`$sTable`.`archive_flag` = $iFlag";
+				if ($sParentClass == $sArchiveRoot)
+				{
+					if ($bArchive)
+					{
+						// Set the date (do not change it)
+						$sDate = '"'.date(AttributeDate::GetSQLFormat()).'"';
+						$aUpdates[] = "`$sTable`.`archive_date` = coalesce(`$sTable`.`archive_date`, $sDate)";
+					}
+					else
+					{
+						// Reset the date
+						$aUpdates[] = "`$sTable`.`archive_date` = null";
+					}
+				}
+				else
+				{
+					$sKey = MetaModel::DBGetKey($sParentClass);
+					$aJoins[] = "`$sTable` ON `$sTable`.`$sKey` = `$sRootTable`.`$sRootKey`";
+				}
+			}
+			$sJoins = implode(' INNER JOIN ', $aJoins);
+			$sValues = implode(', ', $aUpdates);
+			$sUpdateQuery = "UPDATE $sJoins SET $sValues WHERE `$sRootTable`.`$sRootKey` IN ($sIds)";
+			CMDBSource::Query($sUpdateQuery);
+		}
+	}
 }