mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
cache returned objects for next round + add jeffrey test
This commit is contained in:
@@ -122,9 +122,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_object($this->m_oSQLResult)) {
|
||||
$this->m_oSQLResult->free();
|
||||
}
|
||||
$this->Free();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -711,11 +709,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
$sSQL = $this->_makeSelectQuery($this->m_aAttToLoad);
|
||||
|
||||
if (is_object($this->m_oSQLResult)) {
|
||||
// Free previous resultset if any
|
||||
$this->m_oSQLResult->free();
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
// Free previous resultset if any
|
||||
$this->Free();
|
||||
|
||||
try {
|
||||
$oKPI = new ExecutionKPI();
|
||||
@@ -919,6 +914,14 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
return $this->m_iNumLoadedDBRows + count($this->m_aAddedObjects);
|
||||
}
|
||||
|
||||
private function Free()
|
||||
{
|
||||
if (is_object($this->m_oSQLResult)) {
|
||||
CMDBSource::FreeResult($this->m_oSQLResult);
|
||||
$this->m_oSQLResult = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch an object (with the given class alias) at the current position in the set and move the cursor to the next position.
|
||||
*
|
||||
@@ -939,6 +942,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
if ($this->m_iCurrRow >= $this->CountLoaded()) {
|
||||
$this->Free();
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -946,7 +950,9 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$sRequestedClassAlias = $this->m_oFilter->GetClassAlias();
|
||||
}
|
||||
|
||||
if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows) {
|
||||
if ($this->m_iCurrRow < count($this->m_aCacheObj)) {
|
||||
$oRetObj = $this->m_aCacheObj[$this->m_iCurrRow][$sRequestedClassAlias];
|
||||
} else if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows) {
|
||||
// Pick the row from the database
|
||||
$aRow = CMDBSource::FetchArray($this->m_oSQLResult);
|
||||
foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass) {
|
||||
@@ -956,6 +962,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
} else {
|
||||
try {
|
||||
$oRetObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
$this->m_aCacheObj[$this->m_iCurrRow] = [$sRequestedClassAlias => $oRetObj];
|
||||
} catch (CoreException $e) {
|
||||
$this->m_iCurrRow++;
|
||||
$oRetObj = $this->Fetch($sRequestedClassAlias);
|
||||
@@ -972,6 +979,8 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
return $oRetObj;
|
||||
}
|
||||
|
||||
private $m_aCacheObj = [];
|
||||
|
||||
/**
|
||||
* Fetch the whole row of objects (if several classes have been specified in the query) and move the cursor to the next position
|
||||
*
|
||||
@@ -990,21 +999,29 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
}
|
||||
|
||||
if ($this->m_iCurrRow >= $this->CountLoaded()) {
|
||||
$this->Free();
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows) {
|
||||
if ($this->m_iCurrRow < count($this->m_aCacheObj)) {
|
||||
$aRetObjects = $this->m_aCacheObj[$this->m_iCurrRow];
|
||||
} else if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows) {
|
||||
// Pick the row from the database
|
||||
$aRow = CMDBSource::FetchArray($this->m_oSQLResult);
|
||||
$aRetObjects = [];
|
||||
foreach ($this->m_oFilter->GetSelectedClasses() as $sClassAlias => $sClass) {
|
||||
if (is_null($aRow[$sClassAlias.'id'])) {
|
||||
$oObj = null;
|
||||
} else {
|
||||
$oObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
$oObj = null;
|
||||
if (!is_null($aRow[$sClassAlias.'id'])) {
|
||||
try {
|
||||
$oObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
|
||||
}
|
||||
catch (CoreException $e) {
|
||||
}
|
||||
}
|
||||
$aRetObjects[$sClassAlias] = $oObj;
|
||||
}
|
||||
|
||||
$this->m_aCacheObj[$this->m_iCurrRow] = $aRetObjects;
|
||||
} else {
|
||||
// Pick the row from the objects added *in memory*
|
||||
$aRetObjects = [];
|
||||
@@ -1047,6 +1064,10 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
$this->Load();
|
||||
}
|
||||
|
||||
if (is_null($this->m_oSQLResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->m_iCurrRow = min($iRow, $this->Count());
|
||||
if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows) {
|
||||
$this->m_oSQLResult->data_seek($this->m_iCurrRow);
|
||||
@@ -1220,7 +1241,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
*
|
||||
* @throws \CoreException
|
||||
*/
|
||||
public function HasSameContents(DBObjectSet $oObjectSet, $aExcludeColumns = [])
|
||||
public function HasSameContents(DBObjectSet $oObjectSet, $aExcludeColumns = []): bool
|
||||
{
|
||||
$oComparator = new DBObjectSetComparator($this, $oObjectSet, $aExcludeColumns);
|
||||
return $oComparator->SetsAreEquivalent();
|
||||
|
||||
@@ -60,6 +60,15 @@ class DBObjectSetTest extends ItopDataTestCase
|
||||
}
|
||||
|
||||
public function testDBObjectSetComparator()
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT UserRequest");
|
||||
$DBObjectSet1 = new DBObjectSet($oSearch);
|
||||
$DBObjectSet3 = new DBObjectSet($oSearch);
|
||||
$oDBObjectSetComparator = new DBObjectSetComparator($DBObjectSet1, $DBObjectSet3);
|
||||
$this->assertTrue($oDBObjectSetComparator->SetsAreEquivalent());
|
||||
}
|
||||
|
||||
public function testDBObjectSetComparator_CheckCache()
|
||||
{
|
||||
$oSearch = DBObjectSearch::FromOQL_AllData("SELECT UserRequest");
|
||||
$DBObjectSet1 = new DBObjectSet($oSearch);
|
||||
@@ -77,4 +86,53 @@ class DBObjectSetTest extends ItopDataTestCase
|
||||
$this->expectExceptionMessage($sMsg, "should call DB again this time");
|
||||
$this->assertTrue($oDBObjectSetComparator->SetsAreEquivalent());
|
||||
}
|
||||
|
||||
public static function JeffreyProvider()
|
||||
{
|
||||
return [
|
||||
'basic' => [false],
|
||||
'opt trick' => [true],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider JeffreyProvider
|
||||
*/
|
||||
public function testJeffrey(bool $bTrick)
|
||||
{
|
||||
echo '<p>-------</p>';
|
||||
|
||||
$this->doesNotPerformAssertions();
|
||||
$iMax = 100;
|
||||
|
||||
|
||||
$oFilter = DBObjectSearch::FromOQL_AllData('SELECT UserRequest');
|
||||
$oSet = new DBObjectSet($oFilter);
|
||||
$oSet->OptimizeColumnLoad([
|
||||
'UserRequest' => ['ref', 'status', 'title'],
|
||||
]);
|
||||
|
||||
if ($bTrick) {
|
||||
$oNewSet = DBObjectSet::FromScratch($oSet->GetClass());
|
||||
while ($oObj = $oSet->Fetch()) {
|
||||
$oNewSet->AddObject($oObj);
|
||||
}
|
||||
$oSet = $oNewSet;
|
||||
}
|
||||
|
||||
echo '<p>Start: '.date('Y-m-d H:i:s').'</p>';
|
||||
$i = 0;
|
||||
while ($i < $iMax) {
|
||||
$oSet->Rewind();
|
||||
while ($oObj = $oSet->Fetch()) {
|
||||
// Do nothing
|
||||
$s = $oObj->Get('title');
|
||||
}
|
||||
|
||||
$i += 1;
|
||||
}
|
||||
|
||||
$peak = memory_get_peak_usage(true) / 1000000;
|
||||
echo '<p>End: '.date('Y-m-d H:i:s').'</p><p>Peak memory: '.$peak.'</p> \n';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user