Enhancing the search (Trac #147): now allows to pass some "magic patterns" when doing a standard search without any operator. Specially useful for searching on ranges of dates/datetimes

SVN:trunk[638]
This commit is contained in:
Denis Flaven
2010-07-28 15:18:52 +00:00
parent 0938baefb6
commit 9974457971
10 changed files with 124 additions and 17 deletions

View File

@@ -112,7 +112,7 @@ abstract class cmdbAbstractObject extends CMDBObject
// action menu
$oSingletonFilter = new DBObjectSearch(get_class($this));
$oSingletonFilter->AddCondition('id', array($this->GetKey()));
$oSingletonFilter->AddCondition('id', $this->GetKey(), '=');
$oBlock = new MenuBlock($oSingletonFilter, 'popup', false);
$oBlock->Display($oPage, -1);
$oPage->add("<div class=\"page_header\"><h1><img src=\"".$this->GetIcon()."\" style=\"margin-right:10px;margin-top: -16px;vertical-align:middle;\">\n");
@@ -124,8 +124,8 @@ abstract class cmdbAbstractObject extends CMDBObject
{
// history block (with as a tab)
$oHistoryFilter = new DBObjectSearch('CMDBChangeOp');
$oHistoryFilter->AddCondition('objkey', $this->GetKey());
$oHistoryFilter->AddCondition('objclass', get_class($this));
$oHistoryFilter->AddCondition('objkey', $this->GetKey(), '=');
$oHistoryFilter->AddCondition('objclass', get_class($this), '=');
$oBlock = new HistoryBlock($oHistoryFilter, 'table', false);
$oBlock->Display($oPage, -1);
}
@@ -163,7 +163,7 @@ abstract class cmdbAbstractObject extends CMDBObject
$oPage->p("<img src=\"".MetaModel::GetClassIcon($sTargetClass)."\" style=\"vertical-align:middle;\">&nbsp;".$oAttDef->GetDescription());
$oFilter = new DBObjectSearch($sTargetClass);
$oFilter->AddCondition($oAttDef->GetExtKeyToMe(), $this->GetKey());
$oFilter->AddCondition($oAttDef->GetExtKeyToMe(), $this->GetKey(),'=');
$oBlock = new DisplayBlock($oFilter, 'list', false);
$oBlock->Display($oPage, 0);

View File

@@ -125,7 +125,7 @@ class appUserPreferences extends DBObject
{
if (self::$oUserPrefs != null) return;
$oSearch = new DBObjectSearch('appUserPreferences');
$oSearch->AddCondition('userid', UserRights::GetUser());
$oSearch->AddCondition('userid', UserRights::GetUser(), '=');
$oSet = new DBObjectSet($oSearch);
$oObj = $oSet->Fetch();
if ($oObj == null)

View File

@@ -260,6 +260,35 @@ abstract class AttributeDefinition
if (!$oValSetDef) return null;
return $oValSetDef->GetValues($aArgs, $sBeginsWith);
}
/**
* Parses a string to find some smart search patterns and build the corresponding search/OQL condition
* Each derived class is reponsible for defining and processing their own smart patterns, the base class
* does nothing special, and just calls the default (loose) operator
* @param string $sSearchText The search string to analyze for smart patterns
* @param FieldExpression The FieldExpression representing the atttribute code in this OQL query
* @param Hash $aParams Values of the query parameters
* @return Expression The search condition to be added (AND) to the current search
*/
public function GetSmartConditionExpression($sSearchText, FieldExpression $oField, &$aParams)
{
$sParamName = $oField->GetParent().'_'.$oField->GetName();
$oRightExpr = new VariableExpression($sParamName);
$sOperator = $this->GetBasicFilterLooseOperator();
switch ($sOperator)
{
case 'Contains':
$aParams[$sParamName] = "%$sSearchText%";
$sSQLOperator = 'LIKE';
break;
default:
$sSQLOperator = $sOperator;
$aParams[$sParamName] = $sSearchText;
}
$oNewCondition = new BinaryExpression($oField, $sSQLOperator, $oRightExpr);
return $oNewCondition;
}
}
/**
@@ -1189,6 +1218,74 @@ class AttributeDateTime extends AttributeDBField
$sEscaped = str_replace($sFrom, $sTo, (string)$sValue);
return '"'.$sEscaped.'"';
}
/**
* Parses a string to find some smart search patterns and build the corresponding search/OQL condition
* Each derived class is reponsible for defining and processing their own smart patterns, the base class
* does nothing special, and just calls the default (loose) operator
* @param string $sSearchText The search string to analyze for smart patterns
* @param FieldExpression The FieldExpression representing the atttribute code in this OQL query
* @param Hash $aParams Values of the query parameters
* @return Expression The search condition to be added (AND) to the current search
*/
public function GetSmartConditionExpression($sSearchText, FieldExpression $oField, &$aParams)
{
// Possible smart patterns
$aPatterns = array(
'between' => array('pattern' => '/^\[(.*),(.*)\]$/', 'operator' => 'n/a'),
'greater than or equal' => array('pattern' => '/^>=(.*)$/', 'operator' => '>='),
'greater than' => array('pattern' => '/^>(.*)$/', 'operator' => '>'),
'less than or equal' => array('pattern' => '/^<=(.*)$/', 'operator' => '<='),
'less than' => array('pattern' => '/^<(.*)$/', 'operator' => '<'),
);
$sPatternFound = '';
$aMatches = array();
foreach($aPatterns as $sPatName => $sPattern)
{
if (preg_match($sPattern['pattern'], $sSearchText, $aMatches))
{
$sPatternFound = $sPatName;
break;
}
}
switch($sPatternFound)
{
case 'between':
$sParamName1 = $oField->GetParent().'_'.$oField->GetName().'_1';
$oRightExpr = new VariableExpression($sParamName1);
$aParams[$sParamName1] = $aMatches[1];
$oCondition1 = new BinaryExpression($oField, '>=', $oRightExpr);
$sParamName2 = $oField->GetParent().'_'.$oField->GetName().'_2';
$oRightExpr = new VariableExpression($sParamName2);
$sOperator = $this->GetBasicFilterLooseOperator();
$aParams[$sParamName2] = $aMatches[2];
$oCondition2 = new BinaryExpression($oField, '<=', $oRightExpr);
$oNewCondition = new BinaryExpression($oCondition1, 'AND', $oCondition2);
break;
case 'greater than':
case 'greater than or equal':
case 'less than':
case 'less than or equal':
$sSQLOperator = $aPatterns[$sPatternFound]['operator'];
$sParamName = $oField->GetParent().'_'.$oField->GetName();
$oRightExpr = new VariableExpression($sParamName);
$aParams[$sParamName] = $aMatches[1];
$oNewCondition = new BinaryExpression($oField, $sSQLOperator, $oRightExpr);
break;
default:
$oNewCondition = parent::GetSmartConditionExpression($sSearchText, $oField, &$aParams);
}
return $oNewCondition;
}
}
/**

View File

@@ -212,7 +212,7 @@ class CMDBChangeOpSetAttributeScalar extends CMDBChangeOpSetAttribute
$oTargetObjectClass = $this->Get('objclass');
$oTargetObjectKey = $this->Get('objkey');
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
@@ -301,7 +301,7 @@ class CMDBChangeOpSetAttributeBlob extends CMDBChangeOpSetAttribute
$oTargetObjectClass = $this->Get('objclass');
$oTargetObjectKey = $this->Get('objkey');
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)
@@ -360,7 +360,7 @@ class CMDBChangeOpSetAttributeText extends CMDBChangeOpSetAttribute
$oTargetObjectClass = $this->Get('objclass');
$oTargetObjectKey = $this->Get('objkey');
$oTargetSearch = new DBObjectSearch($oTargetObjectClass);
$oTargetSearch->AddCondition('id', $oTargetObjectKey);
$oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
$oMonoObjectSet = new DBObjectSet($oTargetSearch);
if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES)

View File

@@ -1101,7 +1101,7 @@ abstract class DBObject
if (!$oExtKeyAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) continue;
$oSearch = new DBObjectSearch($sRemoteClass);
$oSearch->AddCondition($sExtKeyAttCode, $this->GetKey());
$oSearch->AddCondition($sExtKeyAttCode, $this->GetKey(), '=');
$oSet = new CMDBObjectSet($oSearch);
if ($oSet->Count() > 0)
{

View File

@@ -224,15 +224,25 @@ class DBObjectSearch
MyHelpers::CheckKeyInArray('filter code', $sFilterCode, MetaModel::GetClassFilterDefs($this->GetClass()));
$oFilterDef = MetaModel::GetClassFilterDef($this->GetClass(), $sFilterCode);
$oField = new FieldExpression($sFilterCode, $this->GetClassAlias());
if (empty($sOpCode))
{
$sOpCode = $oFilterDef->GetLooseOperator();
if ($sFilterCode == 'id')
{
$sOpCode = '=';
}
else
{
$oAttDef = MetaModel::GetAttributeDef($this->GetClass(), $sFilterCode);
$oNewCondition = $oAttDef->GetSmartConditionExpression($value, $oField, $this->m_aParams);
$this->AddConditionExpression($oNewCondition);
return;
}
}
MyHelpers::CheckKeyInArray('operator', $sOpCode, $oFilterDef->GetOperators());
// Preserve backward compatibility - quick n'dirty way to change that API semantic
//
$oField = new FieldExpression($sFilterCode, $this->GetClassAlias());
switch($sOpCode)
{
case 'SameDay':

View File

@@ -330,7 +330,7 @@ EOF
case 'get_csv_template':
$sClassName = utils::ReadParam('class_name');
$oSearch = new DBObjectSearch($sClassName);
$oSearch->AddCondition('id', 0); // Make sure we create an empty set
$oSearch->AddCondition('id', 0, '='); // Make sure we create an empty set
$oSet = new CMDBObjectSet($oSearch);
$sResult = cmdbAbstractObject::GetSetAsCSV($oSet);
//$aCSV = explode("\n", $sCSV);

View File

@@ -280,7 +280,7 @@ switch($operation)
$iCount = 0;
$oFilter = $oContext->NewFilter($sClass);
$oFilter->AddCondition($sAttCode, $sName, 'Begins with');
//$oFilter->AddCondition('org_id', $sOrg);
//$oFilter->AddCondition('org_id', $sOrg, '=');
$oSet = new CMDBObjectSet($oFilter, array($sAttCode => true));
while( ($iCount < $iMaxCount) && ($oObj = $oSet->fetch()) )
{

View File

@@ -92,7 +92,7 @@ switch($operation)
$oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
if (!empty($currentOrganization))
{
$oDefinitionFilter->AddCondition('org_id', $currentOrganization);
$oDefinitionFilter->AddCondition('org_id', $currentOrganization, '=');
}
$oDefinitionSet = new CMDBObjectSet($oDefinitionFilter);
$oErrorObjectSet = GetRuleResultSet($iRuleIndex, $oDefinitionFilter);
@@ -124,14 +124,14 @@ switch($operation)
{
if (MetaModel::IsValidFilterCode($oDefinitionFilter->GetClass(), 'org_id'))
{
$oDefinitionFilter->AddCondition('org_id', $currentOrganization);
$oDefinitionFilter->AddCondition('org_id', $currentOrganization, '=');
}
}
$aResults = array();
$oDefinitionSet = new CMDBObjectSet($oDefinitionFilter);
$iCount = $oDefinitionSet->Count();
$oRulesFilter = new CMDBSearchFilter('AuditRule');
$oRulesFilter->AddCondition('category_id', $oAuditCategory->GetKey());
$oRulesFilter->AddCondition('category_id', $oAuditCategory->GetKey(), '=');
$oRulesSet = new DBObjectSet($oRulesFilter);
while($oAuditRule = $oRulesSet->fetch() )
{

View File

@@ -252,7 +252,7 @@ class XMLDataLoader
{
if ($oTargetObj->Get($sAttCode) != '')
{
$oSearch->AddCondition($sAttCode, $oTargetObj->Get($sAttCode));
$oSearch->AddCondition($sAttCode, $oTargetObj->Get($sAttCode), '=');
$iConditionsCount++;
}
}