diff --git a/core/cmdbsource.class.inc.php b/core/cmdbsource.class.inc.php index 8b17a931d..4b1155dd5 100644 --- a/core/cmdbsource.class.inc.php +++ b/core/cmdbsource.class.inc.php @@ -537,6 +537,12 @@ class CMDBSource */ public static function Query($sSQLQuery) { + if (self::$sRaisesExceptionMsgWhenSqlQuery) { + $e = new \Exception(self::$sRaisesExceptionMsgWhenSqlQuery); + \IssueLog::Error(__METHOD__, null, [$e->getTraceAsString()]); + throw $e; + } + if (preg_match('/^START TRANSACTION;?$/i', $sSQLQuery)) { self::StartTransaction(); @@ -556,6 +562,13 @@ class CMDBSource return self::DBQuery($sSQLQuery); } + public static ?string $sRaisesExceptionMsgWhenSqlQuery = null; + + public static function TriggerExceptionWhenSqlQuery(?string $sMsg) + { + self::$sRaisesExceptionMsgWhenSqlQuery = $sMsg; + } + /** * Send the query directly to the DB. **Be extra cautious with this !** * diff --git a/core/dbobjectset.class.php b/core/dbobjectset.class.php index 6b10102d8..e34f54425 100644 --- a/core/dbobjectset.class.php +++ b/core/dbobjectset.class.php @@ -871,23 +871,7 @@ class DBObjectSet implements iDBObjectSetIterator */ public function CountExceeds($iLimit) { - if (is_null($this->m_iNumTotalDBRows)) { - $oKPI = new ExecutionKPI(); - $sSQL = $this->m_oFilter->MakeSelectQuery([], $this->m_aArgs, null, null, $iLimit + 2, 0, true); - $resQuery = CMDBSource::Query($sSQL); - $sOQL = $this->GetPseudoOQL($this->m_oFilter, [], $iLimit + 2, 0, true); - $oKPI->ComputeStats('OQL Query Exec', $sOQL); - if ($resQuery) { - $aRow = CMDBSource::FetchArray($resQuery); - $iCount = intval($aRow['COUNT']); - CMDBSource::FreeResult($resQuery); - } else { - $iCount = 0; - } - } else { - $iCount = $this->m_iNumTotalDBRows; - } - + $iCount = $this->CountWithLimit($iLimit); return ($iCount > $iLimit); } @@ -913,8 +897,8 @@ class DBObjectSet implements iDBObjectSetIterator $oKPI->ComputeStats('OQL Query Exec', $sOQL); if ($resQuery) { $aRow = CMDBSource::FetchArray($resQuery); - CMDBSource::FreeResult($resQuery); $iCount = intval($aRow['COUNT']); + CMDBSource::FreeResult($resQuery); } else { $iCount = 0; } @@ -1063,12 +1047,7 @@ class DBObjectSet implements iDBObjectSetIterator $this->Load(); } - if ($iRow > 0) { - $this->m_iCurrRow = min($iRow, $this->Count()); - } else { - $this->m_iCurrRow = $iRow; - } - + $this->m_iCurrRow = min($iRow, $this->Count()); if ($this->m_iCurrRow < $this->m_iNumLoadedDBRows) { $this->m_oSQLResult->data_seek($this->m_iCurrRow); } diff --git a/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectSetTest.php b/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectSetTest.php new file mode 100644 index 000000000..3a8085443 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectSetTest.php @@ -0,0 +1,65 @@ +Count(); + $oSet->Fetch(); + $this->assertEquals($iCount, $oSet->Count()); + $this->assertEquals($iCount, $oSet->CountWithLimit(0)); + $this->assertTrue($oSet->CountExceeds(0)); + + //no DB SQL query: exception will be raised after here + CMDBSource::TriggerExceptionWhenSqlQuery(__METHOD__.' :'.__LINE__); + $this->assertEquals($iCount, $oSet->Count(), 'should use cache and not call DB again'); + } + + public function testRewind() + { + $oSearch = DBObjectSearch::FromOQL_AllData("SELECT UserRequest"); + $oSet = new DBObjectSet($oSearch); + + while ($oObj = $oSet->Fetch()) { + $this->assertNotEquals(0, $oObj->GetKey()); + } + + //no DB SQL query: exception will be raised after here + CMDBSource::TriggerExceptionWhenSqlQuery(__METHOD__.' :'.__LINE__); + $oSet->Rewind(); + while ($oObj = $oSet->Fetch()) { + $this->assertNotEquals(0, $oObj->GetKey()); + } + } + + 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()); + + $sMsg = __METHOD__.' :'.__LINE__; + //no DB SQL query: exception will be raised after here + CMDBSource::TriggerExceptionWhenSqlQuery($sMsg); + $oDBObjectSetComparator = new DBObjectSetComparator($DBObjectSet1, $DBObjectSet3); + $this->assertTrue($oDBObjectSetComparator->SetsAreEquivalent()); + + + $oDBObjectSetComparator = new DBObjectSetComparator($DBObjectSet1, new DBObjectSet($oSearch)); + $this->expectExceptionMessage($sMsg, "should call DB again this time"); + $this->assertTrue($oDBObjectSetComparator->SetsAreEquivalent()); + } +} \ No newline at end of file