mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-18 16:18:47 +02:00
(retrofit from trunk) Internal: dehardcoded OqlUnionQuery::GetClass against the metamodel reflection API
SVN:2.2.0[3840]
This commit is contained in:
@@ -906,7 +906,8 @@ class DBObjectSearch extends DBSearch
|
||||
|
||||
public function InitFromOqlQuery(OqlQuery $oOqlQuery, $sQuery)
|
||||
{
|
||||
$sClass = $oOqlQuery->GetClass();
|
||||
$oModelReflection = new ModelReflectionRuntime();
|
||||
$sClass = $oOqlQuery->GetClass($oModelReflection);
|
||||
$sClassAlias = $oOqlQuery->GetClassAlias();
|
||||
|
||||
$aAliases = array($sClassAlias => $sClass);
|
||||
|
||||
@@ -288,6 +288,23 @@ abstract class OqlQuery
|
||||
* @throws OqlNormalizeException
|
||||
*/
|
||||
abstract public function Check(ModelReflection $oModelReflection, $sSourceQuery);
|
||||
|
||||
/**
|
||||
* Determine the class
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract public function GetClass(ModelReflection $oModelReflection);
|
||||
|
||||
/**
|
||||
* Determine the class alias
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
abstract public function GetClassAlias();
|
||||
}
|
||||
|
||||
class OqlObjectQuery extends OqlQuery
|
||||
@@ -313,10 +330,25 @@ class OqlObjectQuery extends OqlQuery
|
||||
{
|
||||
return $this->m_aSelect;
|
||||
}
|
||||
public function GetClass()
|
||||
|
||||
/**
|
||||
* Determine the class
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetClass(ModelReflection $oModelReflection)
|
||||
{
|
||||
return $this->m_oClass->GetValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the class alias
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetClassAlias()
|
||||
{
|
||||
return $this->m_oClassAlias->GetValue();
|
||||
@@ -349,7 +381,7 @@ class OqlObjectQuery extends OqlQuery
|
||||
*/
|
||||
public function Check(ModelReflection $oModelReflection, $sSourceQuery)
|
||||
{
|
||||
$sClass = $this->GetClass();
|
||||
$sClass = $this->GetClass($oModelReflection);
|
||||
$sClassAlias = $this->GetClassAlias();
|
||||
|
||||
if (!$oModelReflection->IsValidClass($sClass))
|
||||
@@ -500,7 +532,7 @@ class OqlObjectQuery extends OqlQuery
|
||||
*/
|
||||
public function ToDBSearch($sQuery)
|
||||
{
|
||||
$sClass = $this->GetClass();
|
||||
$sClass = $this->GetClass(new ModelReflectionRuntime());
|
||||
$sClassAlias = $this->GetClassAlias();
|
||||
|
||||
$oSearch = new DBObjectSearch($sClass, $sClassAlias);
|
||||
@@ -548,7 +580,7 @@ class OqlUnionQuery extends OqlQuery
|
||||
{
|
||||
$oQuery->Check($oModelReflection, $sSourceQuery);
|
||||
|
||||
$aAliasToClass = array($oQuery->GetClassAlias() => $oQuery->GetClass());
|
||||
$aAliasToClass = array($oQuery->GetClassAlias() => $oQuery->GetClass($oModelReflection));
|
||||
$aJoinSpecs = $oQuery->GetJoins();
|
||||
if (is_array($aJoinSpecs))
|
||||
{
|
||||
@@ -604,6 +636,100 @@ class OqlUnionQuery extends OqlQuery
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the class
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetClass(ModelReflection $oModelReflection)
|
||||
{
|
||||
$aFirstColClasses = array();
|
||||
foreach ($this->aQueries as $iQuery => $oQuery)
|
||||
{
|
||||
$aFirstColClasses[] = $oQuery->GetClass($oModelReflection);
|
||||
}
|
||||
$sClass = self::GetLowestCommonAncestor($oModelReflection, $aFirstColClasses);
|
||||
if (is_null($sClass))
|
||||
{
|
||||
throw new Exception('Could not determine the class of the union query. This issue should have been detected earlier by calling OqlQuery::Check()');
|
||||
}
|
||||
return $sClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the class alias
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function GetClassAlias()
|
||||
{
|
||||
$sAlias = $this->aQueries[0]->GetClassAlias();
|
||||
return $sAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the validity of the expression with regard to the data model
|
||||
* and the query in which it is used
|
||||
*
|
||||
* @param ModelReflection $oModelReflection MetaModel to consider
|
||||
* @param array $aClasses Flat list of classes
|
||||
* @return string the lowest common ancestor amongst classes, null if none has been found
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function GetLowestCommonAncestor(ModelReflection $oModelReflection, $aClasses)
|
||||
{
|
||||
$sAncestor = null;
|
||||
foreach($aClasses as $sClass)
|
||||
{
|
||||
if (is_null($sAncestor))
|
||||
{
|
||||
// first loop
|
||||
$sAncestor = $sClass;
|
||||
}
|
||||
elseif ($sClass == $sAncestor)
|
||||
{
|
||||
// remains the same
|
||||
}
|
||||
elseif ($oModelReflection->GetRootClass($sClass) != $oModelReflection->GetRootClass($sAncestor))
|
||||
{
|
||||
$sAncestor = null;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sAncestor = self::LowestCommonAncestor($oModelReflection, $sAncestor, $sClass);
|
||||
}
|
||||
}
|
||||
return $sAncestor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: assumes that class A and B have a common ancestor
|
||||
*/
|
||||
protected static function LowestCommonAncestor(ModelReflection $oModelReflection, $sClassA, $sClassB)
|
||||
{
|
||||
if ($sClassA == $sClassB)
|
||||
{
|
||||
$sRet = $sClassA;
|
||||
}
|
||||
elseif (in_array($sClassA, $oModelReflection->EnumChildClasses($sClassA)))
|
||||
{
|
||||
$sRet = $sClassB;
|
||||
}
|
||||
elseif (in_array($sClassB, $oModelReflection->EnumChildClasses($sClassB)))
|
||||
{
|
||||
$sRet = $sClassA;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recurse
|
||||
$sRet = self::LowestCommonAncestor($oModelReflection, $sClassA, $oModelReflection->GetParentClass($sClassB));
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
/**
|
||||
* Make the relevant DBSearch instance (FromOQL)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user