N°2272 - OQL performance (add finalclass on all intermediate tables)

This commit is contained in:
Eric
2019-09-06 14:56:37 +02:00
parent 0f890ad228
commit 9c52f6b949
3 changed files with 64 additions and 14 deletions

View File

@@ -3555,6 +3555,22 @@ class AttributeFinalClass extends AttributeString
return $aLocalizedValues;
}
/**
* @return bool
* @throws \CoreException
* @since 2.7
*/
public function CopyOnAllTables()
{
$sClass = self::GetHostClass();
if (MetaModel::IsLeafClass($sClass))
{
// Leaf class, no finalclass
return false;
}
return true;
}
}

View File

@@ -2550,7 +2550,7 @@ abstract class DBObject implements iDisplay
{
$sTable = MetaModel::DBGetTable($sTableClass);
// Abstract classes or classes having no specific attribute do not have an associated table
if ($sTable == '') return false;
if ($sTable == '') { return false; }
$sClass = get_class($this);
@@ -2570,7 +2570,10 @@ abstract class DBObject implements iDisplay
foreach(MetaModel::ListAttributeDefs($sTableClass) as $sAttCode=>$oAttDef)
{
// Skip this attribute if not defined in this table
if (!MetaModel::IsAttributeOrigin($sTableClass, $sAttCode)) continue;
if (!MetaModel::IsAttributeOrigin($sTableClass, $sAttCode) && !$oAttDef->CopyOnAllTables())
{
continue;
}
$aAttColumns = $oAttDef->GetSQLValues($this->m_aCurrValues[$sAttCode]);
foreach($aAttColumns as $sColumn => $sValue)
{
@@ -2583,7 +2586,7 @@ abstract class DBObject implements iDisplay
}
}
if (count($aValuesToWrite) == 0) return false;
if (count($aValuesToWrite) == 0) { return false; }
if (MetaModel::DBIsReadOnly())
{

View File

@@ -1083,17 +1083,30 @@ abstract class MetaModel
}
/**
* Get "finalclass" DB field name
* @param string $sClass
*
* @return mixed
* @return string
* @throws \CoreException
*/
final static public function DBGetClassField($sClass)
{
self::_check_subclass($sClass);
// Leaf classes have no "finalclass" field.
// Non Leaf classes have the same field as the root class
if (!self::IsLeafClass($sClass))
{
$sClass = MetaModel::GetRootClass($sClass);
}
return self::$m_aClassParams[$sClass]["db_finalclass_field"];
}
final public static function IsLeafClass($sClass)
{
return empty(self::$m_aChildClasses[$sClass]);
}
/**
* @param string $sClass
*
@@ -1103,16 +1116,7 @@ abstract class MetaModel
final static public function IsStandaloneClass($sClass)
{
self::_check_subclass($sClass);
if (count(self::$m_aChildClasses[$sClass]) == 0)
{
if (count(self::$m_aParentClasses[$sClass]) == 0)
{
return true;
}
}
return false;
return (empty(self::$m_aChildClasses[$sClass]) && empty(self::$m_aParentClasses[$sClass]));
}
/**
@@ -5402,6 +5406,14 @@ abstract class MetaModel
else
{
$aAlterTableItems[$sTable][$sField] = "ADD $sFieldDefinition";
$aAdditionalRequests = self::GetAdditionalRequestAfterAlter($sClass, $sTable, $sField);
if (!empty($aAdditionalRequests))
{
foreach ($aAdditionalRequests as $sAdditionalRequest)
{
$aPostTableAlteration[$sTable][] = $sAdditionalRequest;
}
}
}
if ($bIndexNeeded)
@@ -7470,6 +7482,25 @@ abstract class MetaModel
return $sRet;
}
private static function GetAdditionalRequestAfterAlter($sClass, $sTable, $sField)
{
$aRequests = array();
// Copy finalclass fields from root class to intermediate classes
if ($sField == self::DBGetClassField($sClass))
{
$sRootClass = MetaModel::GetRootClass($sClass);
$sRootTable = self::DBGetTable($sRootClass);
$sKey = self::DBGetKey($sClass);
$sRootKey = self::DBGetKey($sRootClass);
$sRootField = self::DBGetClassField($sRootClass);
// Copy the finalclass of the root table
$sRequest = "UPDATE `$sTable`,`$sRootTable` SET `$sTable`.`$sField` = `$sRootTable`.`$sRootField` WHERE `$sTable`.`$sKey` = `$sRootTable`.`$sRootKey`";
$aRequests[] = $sRequest;
}
return $aRequests;
}
}