diff --git a/core/coreexception.class.inc.php b/core/coreexception.class.inc.php index 310dc1c6e..cfc741012 100644 --- a/core/coreexception.class.inc.php +++ b/core/coreexception.class.inc.php @@ -183,6 +183,16 @@ class CoreCannotSaveObjectException extends CoreException } } +class CoreOqlException extends CoreException +{ + +} + +class CoreOqlMultipleResultsFoundException extends CoreOqlException +{ + +} + class CoreWarning extends CoreException { } diff --git a/core/dbsearch.class.php b/core/dbsearch.class.php index 2e65d037e..3e16ae7ae 100644 --- a/core/dbsearch.class.php +++ b/core/dbsearch.class.php @@ -1071,6 +1071,38 @@ abstract class DBSearch return $sRes; } + /** + * @param bool $bMustHaveOneResultMax if true will throw a CoreOqlMultipleResultsFound if multiple results + * @param array $aOrderBy + * @param array $aSearchParams + * + * @return null|\DBObject query result + * @throws \CoreOqlMultipleResultsFoundException if multiple results found and parameter enforce the check + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException + */ + public function GetFirstResult($bMustHaveOneResultMax = true, $aOrderBy = array(), $aSearchParams = array()) + { + $oSet = new DBObjectSet($this, array(), $aSearchParams); + $oFirstResult = $oSet->Fetch(); + if ($oFirstResult === null) + { + return null; + } + + if ($bMustHaveOneResultMax) + { + $oSecondResult = $oSet->Fetch(); + if ($oSecondResult != null) + { + throw new CoreOqlMultipleResultsFoundException('TODO'); + } + } + + return $oFirstResult; + } + /** * @internal * @return mixed diff --git a/test/core/DBSearchTest.php b/test/core/DBSearchTest.php index 2b49f116b..8c7ddb228 100644 --- a/test/core/DBSearchTest.php +++ b/test/core/DBSearchTest.php @@ -29,6 +29,7 @@ namespace Combodo\iTop\Test\UnitTest\Core; use CMDBSource; use Combodo\iTop\Test\UnitTest\ItopDataTestCase; +use CoreOqlMultipleResultsFoundException; use DBSearch; use Exception; use Expression; @@ -519,4 +520,72 @@ class DBSearchTest extends ItopDataTestCase self::assertEquals(1, count($aRes)); } + /** + * @dataProvider GetFirstResultProvider + * + * @param string $sOql query to test + * @param bool $bMustHaveOneResultMax arg passed to the tested function + * @param int $iReturn 0 if should return null, 1 if should return object, -1 if should throw + * + * @throws \CoreException + * @throws \CoreUnexpectedValue + * @throws \MySQLException + * @throws \OQLException + * + * @covers DBSearch::GetFirstResult() + */ + public function testGetFirstResult($sOql, $bMustHaveOneResultMax, $iReturn) + { + $oSearch = DBSearch::FromOQL($sOql); + + $bHasThrownException = false; + try + { + $oFirstResult = $oSearch->GetFirstResult($bMustHaveOneResultMax); + } + catch (CoreOqlMultipleResultsFoundException $e) + { + $oFirstResult = null; + $bHasThrownException = true; + } + + switch ($iReturn) + { + case -1: + self::assertEquals(true, $bHasThrownException, 'Exception raised'); + break; + case 0: + self::assertNull($oFirstResult, 'Null returned'); + break; + case 1: + self::assertInternalType('object', $oFirstResult, 'Object returned'); + break; + } + } + + public function GetFirstResultProvider() + { + return array( + 'One result' => array( + 'SELECT Person WHERE id = 1', + false, + 1, + ), + 'Multiple results, no exception' => array( + 'SELECT Person', + false, + 1, + ), + 'Multiple results, with exception' => array( + 'SELECT Person', + true, + -1, + ), + 'No result' => array( + 'SELECT Person WHERE id = -1', + true, + 0, + ), + ); + } }