From ace676dc24111a3621b4cef7312f29fca149f50e Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 23 Jul 2020 16:41:57 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B02585=20-=20Fix=20alias=20problem=20in=20?= =?UTF-8?q?portal=20scopes=20The=20re-aliasing=20map=20structure=20now=20a?= =?UTF-8?q?llows=20multiple=20mapping=20for=20the=20same=20alias=20(used?= =?UTF-8?q?=20for=20the=20translations=20of=20UNIONS)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/dbobjectsearch.class.php | 33 +++++-- core/dbunionsearch.class.php | 4 +- .../src/Controller/BrowseBrickController.php | 23 ++--- test/core/DBSearchJoinTest.php | 59 ++++++++++++- test/core/DBSearchUpdateRealiasingMapTest.php | 88 +++++++++++++++++++ 5 files changed, 184 insertions(+), 23 deletions(-) create mode 100644 test/core/DBSearchUpdateRealiasingMapTest.php diff --git a/core/dbobjectsearch.class.php b/core/dbobjectsearch.class.php index 198445e9b..48675754b 100644 --- a/core/dbobjectsearch.class.php +++ b/core/dbobjectsearch.class.php @@ -792,10 +792,11 @@ class DBObjectSearch extends DBSearch * Helper to * - convert a translation table (format optimized for the translation in an expression tree) into simple hash * - compile over an eventually existing map + * - accept multiple translations for the same alias for unions * * @param array $aRealiasingMap Map to update * @param array $aAliasTranslation Translation table resulting from calls to MergeWith_InNamespace - * @return void of => + * @return void of [old-alias][] => new-alias (@since 2.7.2) */ protected function UpdateRealiasingMap(&$aRealiasingMap, $aAliasTranslation) { @@ -803,17 +804,33 @@ class DBObjectSearch extends DBSearch { foreach ($aAliasTranslation as $sPrevAlias => $aRules) { - if (isset($aRules['*'])) + if (!isset($aRules['*'])) { - $sNewAlias = $aRules['*']; - $sOriginalAlias = array_search($sPrevAlias, $aRealiasingMap); - if ($sOriginalAlias !== false) + continue; + } + + $sNewAlias = $aRules['*']; + $bOriginalFound = false; + $iIndex = 0; + foreach ($aRealiasingMap as $sOriginalAlias => $aAliases) + { + $iIndex = array_search($sPrevAlias, $aAliases); + if ($iIndex !== false) { - $aRealiasingMap[$sOriginalAlias] = $sNewAlias; + $bOriginalFound = true; + break; } - else + + } + if ($bOriginalFound) + { + $aRealiasingMap[$sOriginalAlias][$iIndex] = $sNewAlias; + } + else + { + if (!isset($aRealiasingMap[$sPrevAlias]) || !in_array($sNewAlias, $aRealiasingMap[$sPrevAlias])) { - $aRealiasingMap[$sPrevAlias] = $sNewAlias; + $aRealiasingMap[$sPrevAlias][] = $sNewAlias; } } } diff --git a/core/dbunionsearch.class.php b/core/dbunionsearch.class.php index 53525347c..28347a580 100644 --- a/core/dbunionsearch.class.php +++ b/core/dbunionsearch.class.php @@ -380,7 +380,7 @@ class DBUnionSearch extends DBSearch * @param DBObjectSearch $oFilter * @param $sExtKeyAttCode * @param int $iOperatorCode - * @param null $aRealiasingMap array of => , for each alias that has changed + * @param null $aRealiasingMap array of [old-alias][] => , for each alias that has changed (@since 2.7.2) */ public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null) { @@ -395,7 +395,7 @@ class DBUnionSearch extends DBSearch * @param DBObjectSearch $oFilter * @param $sForeignExtKeyAttCode * @param int $iOperatorCode - * @param null $aRealiasingMap array of => , for each alias that has changed + * @param null $aRealiasingMap array of [old-alias][] => , for each alias that has changed (@since 2.7.2) */ public function AddCondition_ReferencedBy(DBObjectSearch $oFilter, $sForeignExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null) { diff --git a/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php b/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php index ae8956c65..8498486f8 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php +++ b/datamodels/2.x/itop-portal-base/portal/src/Controller/BrowseBrickController.php @@ -20,22 +20,22 @@ namespace Combodo\iTop\Portal\Controller; +use AttributeExternalKey; use AttributeLinkedSetIndirect; +use BinaryExpression; +use Combodo\iTop\Portal\Brick\AbstractBrick; +use Combodo\iTop\Portal\Brick\BrowseBrick; use Combodo\iTop\Portal\Helper\BrowseBrickHelper; use DBObjectSearch; +use DBObjectSet; +use DBSearch; +use FieldExpression; +use MetaModel; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; -use MetaModel; -use DBSearch; -use DBObjectSet; -use BinaryExpression; -use FieldExpression; use VariableExpression; -use AttributeExternalKey; -use Combodo\iTop\Portal\Brick\AbstractBrick; -use Combodo\iTop\Portal\Brick\BrowseBrick; /** * Class BrowseBrickController @@ -156,8 +156,11 @@ class BrowseBrickController extends BrickController { if (array_key_exists($sLevelAlias, $aRealiasingMap)) { - $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($aRealiasingMap[$sLevelAlias], - $sLevelAlias); + /** @since 2.7.2 */ + foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToChange) + { + $aLevelsProperties[$aLevelsPropertiesKeys[$i]]['search']->RenameAlias($sAliasToChange, $sLevelAlias); + } } } } diff --git a/test/core/DBSearchJoinTest.php b/test/core/DBSearchJoinTest.php index bdb4c2f7d..e71c9ee92 100644 --- a/test/core/DBSearchJoinTest.php +++ b/test/core/DBSearchJoinTest.php @@ -44,12 +44,35 @@ class DBSearchJoinTest extends ItopDataTestCase { $oLeftSearch = DBSearch::FromOQL($sLeftSelect); $oRightSearch = DBSearch::FromOQL($sRightSelect); + $aRealiasingMap = []; + $oResultSearch = $oLeftSearch->Join($oRightSearch, DBSearch::JOIN_REFERENCED_BY, $sParentAtt, TREE_OPERATOR_EQUALS, $aRealiasingMap); + $this->debug("\nRealiasing Map"); + $this->debug($aRealiasingMap); + CMDBSource::TestQuery($oResultSearch->MakeSelectQuery()); $this->assertEquals($sResult, $oResultSearch->ToOQL()); + + // rename alias test + $this->debug("\nBefore renaming"); + $this->debug($oResultSearch->ToOQL()); + $aLevelsPropertiesKeys = ['L-1', 'L-1-1', 'L-1-1-1']; + foreach ($aLevelsPropertiesKeys as $sLevelAlias) + { + if (array_key_exists($sLevelAlias, $aRealiasingMap)) + { + foreach ($aRealiasingMap[$sLevelAlias] as $sAliasToRename) + { + $oResultSearch->RenameAlias($sAliasToRename, $sLevelAlias); + } + } + } + $this->debug("\nAfter renaming"); + $this->debug($oResultSearch->ToOQL()); + } public function JoinProvider() @@ -71,6 +94,30 @@ class DBSearchJoinTest extends ItopDataTestCase { 'parent_att' => 'service_id', 'result' => "SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE (((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete')))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id JOIN lnkCustomerContractToService AS `l11` ON `l11`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc1` ON `l11`.customercontract_id = `cc1`.id WHERE ((`L-1-1`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc1`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete')))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE (((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`L-1-1`.`id` = 8))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE ((`L-1-1`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`L-1-1`.`id` = 8)))", ], + 'Bug 2585' => [ + 'left' => "SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id WHERE ((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) UNION SELECT `L-1-1` FROM Service AS `L-1-1` WHERE (`L-1-1`.`id` = 8)", + 'right' => "SELECT `L-1-1-1` FROM ServiceSubcategory AS `L-1-1-1` JOIN Service AS `s` ON `L-1-1-1`.service_id = `s`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `s`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id WHERE ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete'))) UNION SELECT `L-1-1-1` FROM ServiceSubcategory AS `L-1-1-1` JOIN Service AS `s1` ON `L-1-1-1`.service_id = `s1`.id WHERE ((`L-1-1-1`.`status` != 'obsolete') AND (`s1`.`id` = 8))", + 'parent_att' => 'service_id', + 'result' => "SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE (((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete')))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id JOIN lnkCustomerContractToService AS `l11` ON `l11`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc1` ON `l11`.customercontract_id = `cc1`.id WHERE ((`L-1-1`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc1`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete')))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE (((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`L-1-1`.`id` = 8))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE ((`L-1-1`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`L-1-1`.`id` = 8)))", + ], + 'Bug 2585 K' => [ + 'left' => "SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_BE_TRANSLATED` ON `SHOULD_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id WHERE (`cc`.`org_id` = 2) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_ALSO_BE_TRANSLATED` ON `SHOULD_ALSO_BE_TRANSLATED`.servicefamily_id = `L-1`.id WHERE (`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8)", + 'right' => "SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE (((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete')))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id JOIN lnkCustomerContractToService AS `l11` ON `l11`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc1` ON `l11`.customercontract_id = `cc1`.id WHERE ((`L-1-1`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc1`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete')))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `L-1-1`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE (((`cc`.`org_id` = 2) AND (`L-1-1`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`L-1-1`.`id` = 8))) UNION SELECT `L-1-1` FROM Service AS `L-1-1` JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `L-1-1`.id WHERE ((`L-1-1`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`L-1-1`.`id` = 8)))", + 'parent_att' => 'servicefamily_id', + 'result' => "SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_BE_TRANSLATED` ON `SHOULD_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_BE_TRANSLATED`.id WHERE ((`cc`.`org_id` = 2) AND (((`cc`.`org_id` = 2) AND (`SHOULD_BE_TRANSLATED`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete'))))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_ALSO_BE_TRANSLATED` ON `SHOULD_ALSO_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id WHERE ((`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8) AND (((`cc`.`org_id` = 2) AND (`SHOULD_ALSO_BE_TRANSLATED`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete'))))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_BE_TRANSLATED` ON `SHOULD_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_BE_TRANSLATED`.id WHERE ((`cc`.`org_id` = 2) AND ((`SHOULD_BE_TRANSLATED`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete'))))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_ALSO_BE_TRANSLATED` ON `SHOULD_ALSO_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id JOIN lnkCustomerContractToService AS `l11` ON `l11`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id JOIN CustomerContract AS `cc1` ON `l11`.customercontract_id = `cc1`.id WHERE ((`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8) AND ((`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND ((`cc1`.`org_id` = 2) AND (`L-1-1-1`.`status` != 'obsolete'))))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_BE_TRANSLATED` ON `SHOULD_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_BE_TRANSLATED`.id WHERE ((`cc`.`org_id` = 2) AND (((`cc`.`org_id` = 2) AND (`SHOULD_BE_TRANSLATED`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`SHOULD_BE_TRANSLATED`.`id` = 8)))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_ALSO_BE_TRANSLATED` ON `SHOULD_ALSO_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id WHERE ((`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8) AND (((`cc`.`org_id` = 2) AND (`SHOULD_ALSO_BE_TRANSLATED`.`status` != 'obsolete')) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8)))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_BE_TRANSLATED` ON `SHOULD_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `SHOULD_BE_TRANSLATED`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_BE_TRANSLATED`.id WHERE ((`cc`.`org_id` = 2) AND ((`SHOULD_BE_TRANSLATED`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`SHOULD_BE_TRANSLATED`.`id` = 8)))) UNION SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `SHOULD_ALSO_BE_TRANSLATED` ON `SHOULD_ALSO_BE_TRANSLATED`.servicefamily_id = `L-1`.id JOIN ServiceSubcategory AS `L-1-1-1` ON `L-1-1-1`.service_id = `SHOULD_ALSO_BE_TRANSLATED`.id WHERE ((`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8) AND ((`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8) AND ((`L-1-1-1`.`status` != 'obsolete') AND (`SHOULD_ALSO_BE_TRANSLATED`.`id` = 8))))", + ], + 'test 2585 K2' => [ + 'left' => "SELECT Service AS s JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = 2 AND s.status != 'obsolete' UNION SELECT Service WHERE id = 8", + 'right' => "SELECT ServiceSubcategory AS ssc JOIN Service AS s ON ssc.service_id=s.id JOIN lnkCustomerContractToService AS l1 ON l1.service_id=s.id JOIN CustomerContract AS cc ON l1.customercontract_id=cc.id WHERE cc.org_id = 2 AND ssc.status != 'obsolete' UNION SELECT ServiceSubcategory AS ssc JOIN Service AS s ON ssc.service_id=s.id WHERE s.id = 8", + 'parent_att' => 'service_id', + 'result' => "SELECT `s` FROM Service AS `s` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `s`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `ssc` ON `ssc`.service_id = `s`.id WHERE (((`cc`.`org_id` = 2) AND (`s`.`status` != 'obsolete')) AND ((`cc`.`org_id` = 2) AND (`ssc`.`status` != 'obsolete'))) UNION SELECT `Service` FROM Service AS `Service` JOIN ServiceSubcategory AS `ssc` ON `ssc`.service_id = `Service`.id JOIN lnkCustomerContractToService AS `l11` ON `l11`.service_id = `Service`.id JOIN CustomerContract AS `cc1` ON `l11`.customercontract_id = `cc1`.id WHERE ((`Service`.`id` = 8) AND ((`cc1`.`org_id` = 2) AND (`ssc`.`status` != 'obsolete'))) UNION SELECT `s` FROM Service AS `s` JOIN lnkCustomerContractToService AS `l1` ON `l1`.service_id = `s`.id JOIN CustomerContract AS `cc` ON `l1`.customercontract_id = `cc`.id JOIN ServiceSubcategory AS `ssc` ON `ssc`.service_id = `s`.id WHERE (((`cc`.`org_id` = 2) AND (`s`.`status` != 'obsolete')) AND (`s`.`id` = 8)) UNION SELECT `Service` FROM Service AS `Service` JOIN ServiceSubcategory AS `ssc` ON `ssc`.service_id = `Service`.id WHERE ((`Service`.`id` = 8) AND (`Service`.`id` = 8))", + ], + 'Bug 2585 K3' => [ + 'left' => "SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `s` ON `s`.servicefamily_id = `L-1`.id WHERE 1", + 'right' => "SELECT `L-1-1` FROM Service AS `L-1-1` WHERE 1", + 'parent_att' => 'servicefamily_id', + 'result' => "SELECT `L-1` FROM ServiceFamily AS `L-1` JOIN Service AS `s` ON `s`.servicefamily_id = `L-1`.id WHERE 1", + ], // 'test' => [ // 'left' => "", // 'right' => "", @@ -89,7 +136,7 @@ class DBSearchJoinTest extends ItopDataTestCase { public function testFilterOnJoin() { $sReq1 = "SELECT `L-1` FROM Organization AS `L-1` WHERE (`L-1`.`id` = 2)"; - $sReq2 = "SELECT `L-1-1` FROM CustomerContract AS `L-1-1` JOIN Organization AS `O` ON `L-1-1`.org_id = `O`.id WHERE (((`L-1-1`.`status` = 'active') OR (`L-1-1`.`status` = 'standby')) AND (`O`.`id` = 2))"; + $sReq2 = "SELECT `L-1-1` FROM CustomerContract AS `L-1-1` JOIN Organization AS `SHOULD_BE_TRANSLATED` ON `L-1-1`.org_id = `SHOULD_BE_TRANSLATED`.id WHERE (((`L-1-1`.`status` = 'active') OR (`L-1-1`.`status` = 'standby')) AND (`SHOULD_BE_TRANSLATED`.`id` = 2))"; $oFilter1 = DBSearch::FromOQL($sReq1); $oFilter2 = DBSearch::FromOQL($sReq2); @@ -99,7 +146,11 @@ class DBSearchJoinTest extends ItopDataTestCase { 'org_id', TREE_OPERATOR_EQUALS, $aRealiasingMap); + $this->debug("\nRealiasing Map"); + $this->debug($aRealiasingMap); + $sRes1 = $oFilter1->ToOQL(); + $this->debug("\nJoined"); $this->debug($sRes1); foreach($oFilter1->GetCriteria_ReferencedBy() as $sForeignClass => $aReferences) @@ -110,13 +161,14 @@ class DBSearchJoinTest extends ItopDataTestCase { { foreach ($aFilters as $index => $oForeignFilter) { + $this->debug("\nReferencedBy"); $this->debug($oForeignFilter->ToOQL()); } } } } - $this->assertFalse(strpos($sRes1, '`O`.')); + $this->assertFalse(strpos($sRes1, '`SHOULD_BE_TRANSLATED`.')); $sReq3 = "SELECT `CustomerContract` FROM CustomerContract AS `CustomerContract` WHERE (`CustomerContract`.`org_id` IN ('2'))"; $oFilter3 = DBSearch::FromOQL($sReq3); @@ -124,8 +176,9 @@ class DBSearchJoinTest extends ItopDataTestCase { $oFilter1 = $oFilter1->Filter('L-1-1', $oFilter3); $sRes1 = $oFilter1->ToOQL(); + $this->debug("\nFiltered"); $this->debug($sRes1); - $this->assertFalse(strpos($sRes1, '`O`.')); + $this->assertFalse(strpos($sRes1, '`SHOULD_BE_TRANSLATED`.')); } } diff --git a/test/core/DBSearchUpdateRealiasingMapTest.php b/test/core/DBSearchUpdateRealiasingMapTest.php new file mode 100644 index 000000000..ece5dd312 --- /dev/null +++ b/test/core/DBSearchUpdateRealiasingMapTest.php @@ -0,0 +1,88 @@ +UpdateRealiasingMap($aRealiasingMap, $aAliasTranslation); + $this->assertEquals($aExpectedRealiasingMap, $aRealiasingMap); + } + + public function UpdateRealiasingMapProvider() + { + return [ + 'empty' => [ + 'OriginalMap' => null, + 'AliasTranslation' => [], + 'ExpectedMap' => null + ], + 'Add 1 alias' => [ + 'OriginalMap' => [], + 'AliasTranslation' => ['a' => ['*' => 'b']], + 'ExpectedMap' => ['a' => ['b']] + ], + 'Add 2 aliases' => [ + 'OriginalMap' => [], + 'AliasTranslation' => ['a' => ['*' => 'b'], 'c' => ['*' => 'd']], + 'ExpectedMap' => ['a' => ['b'], 'c' => ['d']] + ], + 'Append 1 alias' => [ + 'OriginalMap' => ['a' => ['b']], + 'AliasTranslation' => ['c' => ['*' => 'd']], + 'ExpectedMap' => ['a' => ['b'], 'c' => ['d']] + ], + 'Merge 1 alias' => [ + 'OriginalMap' => ['a' => ['b']], + 'AliasTranslation' => ['a' => ['*' => 'd']], + 'ExpectedMap' => ['a' => ['b', 'd']] + ], + 'Merge same alias' => [ + 'OriginalMap' => ['a' => ['b']], + 'AliasTranslation' => ['a' => ['*' => 'b']], + 'ExpectedMap' => ['a' => ['b']] + ], + 'Transitivity a->b + b->f = a->f' => [ + 'OriginalMap' => ['a' => ['b', 'd'], 'c' => ['e']], + 'AliasTranslation' => ['b' => ['*' => 'f']], + 'ExpectedMap' => ['a' => ['f', 'd'], 'c' => ['e']] + ], + ]; + } + + private function UpdateRealiasingMap(&$aRealiasingMap, $aAliasTranslation) + { + $class = new \ReflectionClass(DBObjectSearch::class); + $method = $class->getMethod('UpdateRealiasingMap'); + $method->setAccessible(true); + $method->invokeArgs(new DBObjectSearch('Organization'), [&$aRealiasingMap, $aAliasTranslation]); + } +}