Bladeren bron

#366 Global search case sensitive or not working at all (issue with COLLATION)

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1158 a333f486-631f-4898-b8df-5754b55c2be0
romainq 14 jaren geleden
bovenliggende
commit
46e8156942
4 gewijzigde bestanden met toevoegingen van 52 en 58 verwijderingen
  1. 27 0
      core/expression.class.inc.php
  2. 21 14
      core/metamodel.class.php
  3. 1 41
      core/sqlquery.class.inc.php
  4. 3 3
      test/testlist.inc.php

+ 27 - 0
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;

+ 21 - 14
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...
 		//

+ 1 - 41
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 "<b>$this->m_sTable</b>$sFields<br/>\n";
 		// #@# todo - display html of an expression tree
 		//$this->m_oConditionExpr->DisplayHtml()
-		if (count($this->m_aFullTextNeedles) > 0)
-		{
-			echo "Full text criteria...<br/>\n";
-			echo "<ul class=\"treeview\">\n";
-			foreach ($this->m_aFullTextNeedles as $sFTNeedle)
-			{
-				echo "<li>$sFTNeedle</li>\n";
-			}
-			echo "</ul>";
-		}
 		if (count($this->m_aJoinSelects) > 0)
 		{
 			echo "Joined to...<br/>\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; 
 	}
 

+ 3 - 3
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()
 		);