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

SVN:trunk[1158]
This commit is contained in:
Romain Quetiez
2011-03-31 08:29:02 +00:00
parent e3ac7067f7
commit d4321ec1ce
4 changed files with 52 additions and 58 deletions

View File

@@ -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;

View File

@@ -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...
//

View File

@@ -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;
}

View File

@@ -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()
);