mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
(Retrofit from trunk) r5051 N.689 workaround on MySQL number of joins limit (61)
* change MySQLException to store initial exception code * added a try/catch to launch query with full lazy load (no attr => only id) * load finalClass field if needed (class is nor standalone nor a final leaf) SVN:2.4[5052]
This commit is contained in:
@@ -33,13 +33,15 @@ class MySQLException extends CoreException
|
|||||||
{
|
{
|
||||||
if ($oException != null)
|
if ($oException != null)
|
||||||
{
|
{
|
||||||
$aContext['mysql_error'] = $oException->getCode();
|
$aContext['mysql_errno'] = $oException->getCode();
|
||||||
$aContext['mysql_errno'] = $oException->getMessage();
|
$this->code = $oException->getCode();
|
||||||
|
$aContext['mysql_error'] = $oException->getMessage();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aContext['mysql_error'] = CMDBSource::GetError();
|
|
||||||
$aContext['mysql_errno'] = CMDBSource::GetErrNo();
|
$aContext['mysql_errno'] = CMDBSource::GetErrNo();
|
||||||
|
$this->code = CMDBSource::GetErrNo();
|
||||||
|
$aContext['mysql_error'] = CMDBSource::GetError();
|
||||||
}
|
}
|
||||||
parent::__construct($sIssue, $aContext);
|
parent::__construct($sIssue, $aContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected $m_iCurrRow;
|
protected $m_iCurrRow;
|
||||||
/*
|
/**
|
||||||
* @var DBSearch
|
* @var DBSearch
|
||||||
*/
|
*/
|
||||||
protected $m_oFilter;
|
protected $m_oFilter;
|
||||||
@@ -626,14 +626,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
// Note: it is mandatory to set this value now, to protect against reentrance
|
// Note: it is mandatory to set this value now, to protect against reentrance
|
||||||
$this->m_bLoaded = true;
|
$this->m_bLoaded = true;
|
||||||
|
|
||||||
if ($this->m_iLimitCount > 0)
|
$sSQL = $this->_makeSelectQuery($this->m_aAttToLoad);
|
||||||
{
|
|
||||||
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec, $this->m_iLimitCount, $this->m_iLimitStart);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_object($this->m_oSQLResult))
|
if (is_object($this->m_oSQLResult))
|
||||||
{
|
{
|
||||||
@@ -642,8 +635,36 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
$this->m_oSQLResult = null;
|
$this->m_oSQLResult = null;
|
||||||
}
|
}
|
||||||
$this->m_iNumTotalDBRows = null;
|
$this->m_iNumTotalDBRows = null;
|
||||||
|
|
||||||
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
try
|
||||||
|
{
|
||||||
|
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
||||||
|
} catch (MySQLException $e)
|
||||||
|
{
|
||||||
|
// 1116 = ER_TOO_MANY_TABLES
|
||||||
|
// https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_too_many_tables
|
||||||
|
if ($e->getCode() != 1116)
|
||||||
|
{
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
// N.689 Workaround for the 61 max joins in MySQL : full lazy load !
|
||||||
|
$aAttToLoad = array();
|
||||||
|
foreach($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass)
|
||||||
|
{
|
||||||
|
$aAttToLoad[$sClassAlias] = array();
|
||||||
|
$bIsAbstractClass = MetaModel::IsAbstract($sClass);
|
||||||
|
$bIsClassWithChildren = MetaModel::HasChildrenClasses($sClass);
|
||||||
|
if ($bIsAbstractClass || $bIsClassWithChildren)
|
||||||
|
{
|
||||||
|
// we need finalClass field at least to be able to instantiate the real corresponding object !
|
||||||
|
$aAttToLoad[$sClassAlias]['finalclass'] = MetaModel::GetAttributeDef($sClass, 'finalclass');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sSQL = $this->_makeSelectQuery($aAttToLoad);
|
||||||
|
$this->m_oSQLResult = CMDBSource::Query($sSQL); // may fail again
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->m_oSQLResult === false) return;
|
if ($this->m_oSQLResult === false) return;
|
||||||
|
|
||||||
if (($this->m_iLimitCount == 0) && ($this->m_iLimitStart == 0))
|
if (($this->m_iLimitCount == 0) && ($this->m_iLimitStart == 0))
|
||||||
@@ -654,10 +675,33 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The total number of rows in this set. Independently of the SetLimit used for loading the set and taking into account the rows added in-memory.
|
* @param string[] $aAttToLoad
|
||||||
*
|
*
|
||||||
* May actually perform the SQL query SELECT COUNT... if the set was not previously loaded, or loaded with a SetLimit
|
* @return string SQL query
|
||||||
*
|
*/
|
||||||
|
private function _makeSelectQuery($aAttToLoad)
|
||||||
|
{
|
||||||
|
if ($this->m_iLimitCount > 0)
|
||||||
|
{
|
||||||
|
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $aAttToLoad,
|
||||||
|
$this->m_aExtendedDataSpec, $this->m_iLimitCount, $this->m_iLimitStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sSQL = $this->m_oFilter->MakeSelectQuery($this->GetRealSortOrder(), $this->m_aArgs, $aAttToLoad,
|
||||||
|
$this->m_aExtendedDataSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sSQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total number of rows in this set. Independently of the SetLimit used for loading the set and taking into
|
||||||
|
* account the rows added in-memory.
|
||||||
|
*
|
||||||
|
* May actually perform the SQL query SELECT COUNT... if the set was not previously loaded, or loaded with a
|
||||||
|
* SetLimit
|
||||||
|
*
|
||||||
* @return int The total number of rows for this set.
|
* @return int The total number of rows for this set.
|
||||||
*/
|
*/
|
||||||
public function Count()
|
public function Count()
|
||||||
@@ -667,11 +711,12 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
|
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
|
||||||
$resQuery = CMDBSource::Query($sSQL);
|
$resQuery = CMDBSource::Query($sSQL);
|
||||||
if (!$resQuery) return 0;
|
if (!$resQuery) return 0;
|
||||||
|
|
||||||
$aRow = CMDBSource::FetchArray($resQuery);
|
$aRow = CMDBSource::FetchArray($resQuery);
|
||||||
CMDBSource::FreeResult($resQuery);
|
CMDBSource::FreeResult($resQuery);
|
||||||
$this->m_iNumTotalDBRows = $aRow['COUNT'];
|
$this->m_iNumTotalDBRows = $aRow['COUNT'];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user