From d4321ec1cedc54a5155a033a8cb5976fc6d20a16 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 31 Mar 2011 08:29:02 +0000 Subject: [PATCH] #366 Global search case sensitive or not working at all (issue with COLLATION) SVN:trunk[1158] --- core/expression.class.inc.php | 27 ++++++++++++++++++++++ core/metamodel.class.php | 35 +++++++++++++++++------------ core/sqlquery.class.inc.php | 42 +---------------------------------- test/testlist.inc.php | 6 ++--- 4 files changed, 52 insertions(+), 58 deletions(-) diff --git a/core/expression.class.inc.php b/core/expression.class.inc.php index a4b696813..13e7d9b5a 100644 --- a/core/expression.class.inc.php +++ b/core/expression.class.inc.php @@ -682,6 +682,33 @@ class CharConcatExpression extends Expression } } + +class CharConcatWSExpression extends CharConcatExpression +{ + protected $m_separator; + + public function __construct($separator, $aExpressions) + { + $this->m_separator = $separator; + parent::__construct($aExpressions); + } + + // recursive rendering + public function Render(&$aArgs = null, $bRetrofitParams = false) + { + $aRes = array(); + foreach ($this->m_aExpressions as $oExpr) + { + $sCol = $oExpr->Render($aArgs, $bRetrofitParams); + // Concat will be globally NULL if one single argument is null ! + $aRes[] = "COALESCE($sCol, '')"; + } + $sSep = CMDBSource::Quote($this->m_separator); + return "CAST(CONCAT_WS($sSep, ".implode(', ', $aRes).") AS CHAR)"; + } +} + + class QueryBuilderExpressions { protected $m_oConditionExpr; diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 9ff9b836c..b9ae19333 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -2016,6 +2016,26 @@ abstract class MetaModel $oQBExpr->AddSelect($sClassAlias.$sAttCode.$sColId, new FieldExpression($sAttCode.$sColId, $sClassAlias)); } } + + // Transform the full text condition into additional condition expression + $aFullText = $oFilter->GetCriteria_FullText(); + if (count($aFullText) > 0) + { + $aFullTextFields = array(); + foreach (self::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) + { + if (!$oAttDef->IsScalar()) continue; + if ($oAttDef->IsExternalKey()) continue; + $aFullTextFields[] = new FieldExpression($sAttCode, $sClassAlias); + } + $oTextFields = new CharConcatWSExpression(' ', $aFullTextFields); + + foreach($aFullText as $sFTNeedle) + { + $oNewCond = new BinaryExpression($oTextFields, 'LIKE', new ScalarExpression("%$sFTNeedle%")); + $oQBExpr->AddCondition($oNewCond); + } + } } $aExpectedAtts = array(); // array of (attcode => fieldexpression) @@ -2281,22 +2301,9 @@ abstract class MetaModel } } - // #@# todo - See what a full text search condition should be - // 2 - WHERE / Full text search condition - // - if ($bIsOnQueriedClass) - { - $aFullText = $oFilter->GetCriteria_FullText(); - } - else - { - // Pourquoi ??? - $aFullText = array(); - } - // 3 - The whole stuff, for this table only // - $oSelectBase = new SQLQuery($sTable, $sTableAlias, array(), $aFullText, $bIsOnQueriedClass, $aUpdateValues, $oSelectedIdField); + $oSelectBase = new SQLQuery($sTable, $sTableAlias, array(), $bIsOnQueriedClass, $aUpdateValues, $oSelectedIdField); // 4 - The external keys -> joins... // diff --git a/core/sqlquery.class.inc.php b/core/sqlquery.class.inc.php index 8a2b26051..5dbe45603 100644 --- a/core/sqlquery.class.inc.php +++ b/core/sqlquery.class.inc.php @@ -42,13 +42,12 @@ class SQLQuery private $m_sTableAlias = ''; private $m_aFields = array(); private $m_oConditionExpr = null; - private $m_aFullTextNeedles = array(); private $m_bToDelete = true; // The current table must be listed for deletion ? private $m_aValues = array(); // Values to set in case of an update query private $m_oSelectedIdField = null; private $m_aJoinSelects = array(); - public function __construct($sTable, $sTableAlias, $aFields, $aFullTextNeedles = array(), $bToDelete = true, $aValues = array(), $oSelectedIdField = null) + public function __construct($sTable, $sTableAlias, $aFields, $bToDelete = true, $aValues = array(), $oSelectedIdField = null) { // This check is not needed but for developping purposes //if (!CMDBSource::IsTable($sTable)) @@ -64,7 +63,6 @@ class SQLQuery $this->m_sTableAlias = $sTableAlias; $this->m_aFields = $aFields; $this->m_oConditionExpr = null; - $this->m_aFullTextNeedles = $aFullTextNeedles; $this->m_bToDelete = $bToDelete; $this->m_aValues = $aValues; $this->m_oSelectedIdField = $oSelectedIdField; @@ -95,16 +93,6 @@ class SQLQuery echo "$this->m_sTable$sFields
\n"; // #@# todo - display html of an expression tree //$this->m_oConditionExpr->DisplayHtml() - if (count($this->m_aFullTextNeedles) > 0) - { - echo "Full text criteria...
\n"; - echo ""; - } if (count($this->m_aJoinSelects) > 0) { echo "Joined to...
\n"; @@ -381,35 +369,7 @@ class SQLQuery private function privRender(&$aFrom, &$aFields, &$oCondition, &$aDelTables, &$aSetValues, &$aSelectedIdFields) { $sTableAlias = $this->privRenderSingleTable($aFrom, $aFields, $aDelTables, $aSetValues, $aSelectedIdFields); - - // Add the full text search condition, based on each and every requested field - // - // To be updated with a real full text search based on the mySQL settings - // (then it might move somewhere else !) - // $oCondition = $this->m_oConditionExpr; - if ((count($aFields) > 0) && (count($this->m_aFullTextNeedles) > 0)) - { - $sFields = implode(', ', $aFields); - $oFullTextExpr = Expression::FromSQL("CONCAT_WS(' ', $sFields)"); - - // The cast is necessary because the CONCAT result in a binary string: - // if any of the field is a binary string => case sensitive comparison - // - foreach($this->m_aFullTextNeedles as $sFTNeedle) - { - $oNewCond = new BinaryExpression($oFullTextExpr, 'LIKE', new ScalarExpression("%$sFTNeedle%")); - if (is_null($oCondition)) - { - $oCondition = $oNewCond; - } - else - { - $oCondition = $oCondition->LogAnd($oNewCond); - } - } - } - return $sTableAlias; } diff --git a/test/testlist.inc.php b/test/testlist.inc.php index e83ddc4de..ed3822ec4 100644 --- a/test/testlist.inc.php +++ b/test/testlist.inc.php @@ -50,7 +50,7 @@ class TestSQLQuery extends TestScenarioOnDB $sTable = 'myTable', $sTableAlias = 'myTableAlias', $aFields = array('column1'=>new FieldExpression('column1', 'myTableAlias'), 'column2'=>new FieldExpression('column2', 'myTableAlias')), - $aFullTextNeedles = array('column1'), +// $aFullTextNeedles = array('column1'), $bToDelete = false, $aValues = array() ); @@ -60,7 +60,7 @@ class TestSQLQuery extends TestScenarioOnDB $sTable = 'myTable1', $sTableAlias = 'myTable1Alias', $aFields = array('column1_1'=>new FieldExpression('column1', 'myTableAlias'), 'column1_2'=>new FieldExpression('column1', 'myTableAlias')), - $aFullTextNeedles = array(), +// $aFullTextNeedles = array(), $bToDelete = false, $aValues = array() ); @@ -69,7 +69,7 @@ class TestSQLQuery extends TestScenarioOnDB $sTable = 'myTable2', $sTableAlias = 'myTable2Alias', $aFields = array('column2_1'=>new FieldExpression('column2', 'myTableAlias'), 'column2_2'=>new FieldExpression('column2', 'myTableAlias')), - $aFullTextNeedles = array(), +// $aFullTextNeedles = array(), $bToDelete = false, $aValues = array() );