mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-25 16:19:00 +01:00
* All apps: improved speed when searching with (many) custom-fields
This commit is contained in:
parent
23ceb00380
commit
5086e6cca3
@ -272,10 +272,6 @@ class Storage
|
||||
|
||||
// remove some columns, absolutly not necessary to search in sql
|
||||
$this->columns_to_search = array_diff(array_values($this->somain->db_cols),$this->sql_cols_not_to_search);
|
||||
if ($this->customfields) // add custom fields, if configured
|
||||
{
|
||||
$this->columns_to_search[] = Sql::EXTRA_TABLE.'.'.Sql::EXTRA_VALUE;
|
||||
}
|
||||
}
|
||||
if ($this->user)
|
||||
{
|
||||
|
@ -406,6 +406,34 @@ class Storage extends Storage\Base
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return criteria array for a given search pattern
|
||||
*
|
||||
* Reimplemented to handle search in custom-fields by ORing with a sub-query
|
||||
* returning all auto-ids of custom-fields matching the search-criteria
|
||||
*
|
||||
* @param string $_pattern search pattern incl. * or ? as wildcard, if no wildcards used we append and prepend one!
|
||||
* @param string &$wildcard ='' on return wildcard char to use, if pattern does not already contain wildcards!
|
||||
* @param string &$op ='AND' on return boolean operation to use, if pattern does not start with ! we use OR else AND
|
||||
* @param string $extra_col =null extra column to search
|
||||
* @param array $search_cols =array() List of columns to search. If not provided, all columns in $this->db_cols will be considered
|
||||
* @return array or column => value pairs
|
||||
*/
|
||||
public function search2criteria($_pattern,&$wildcard='',&$op='AND',$extra_col=null, $search_cols = array())
|
||||
{
|
||||
$pattern = $wildcard.$_pattern.$wildcard;
|
||||
|
||||
$criteria = parent::search2criteria($_pattern, $wildcard, $op, $extra_col, $search_cols);
|
||||
|
||||
$criteria[0] = '('.$criteria[0].' OR '.
|
||||
$this->table_name.'.'.$this->autoinc_id.' IN (SELECT '.$this->autoinc_id.
|
||||
' FROM '.$this->extra_table.' WHERE '.$this->extra_value.' '.
|
||||
$this->db->capabilities[Db::CAPABILITY_CASE_INSENSITIV_LIKE].' '.
|
||||
$GLOBALS['egw']->db->quote($pattern).'))';
|
||||
|
||||
return $criteria;
|
||||
}
|
||||
|
||||
/**
|
||||
* searches db for rows matching searchcriteria
|
||||
*
|
||||
@ -440,10 +468,12 @@ class Storage extends Storage\Base
|
||||
{
|
||||
$only_keys = $this->table_name.'.*';
|
||||
}
|
||||
// if string given as criteria --> search in all (or $this->columns_to_search) columns including custom fields
|
||||
$extra_join_added = $join && strpos($join, $this->extra_join) !== false;
|
||||
if ($criteria && is_string($criteria))
|
||||
{
|
||||
$criteria = $this->search2criteria($criteria,$wildcard,$op);
|
||||
$extra_join_added = true; // we have NOT added the join, as we use a sub-query and therefore not need it
|
||||
|
||||
$criteria = $this->search2criteria($criteria, $wildcard, $op);
|
||||
}
|
||||
if ($criteria && is_array($criteria))
|
||||
{
|
||||
@ -471,7 +501,6 @@ class Storage extends Storage\Base
|
||||
unset($criteria[$this->autoinc_id]);
|
||||
}
|
||||
// replace ambiguous column with (an exact match of) table_name.column
|
||||
$extra_join_added = $join && strpos($join, $this->extra_join) !== false;
|
||||
foreach($criteria as $name => $val)
|
||||
{
|
||||
// only add extra_join, if we really need it
|
||||
@ -711,24 +740,6 @@ class Storage extends Storage\Base
|
||||
return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a default list of columns to search
|
||||
*
|
||||
* Reimplemented to search custom fields by default.
|
||||
*
|
||||
* @return array of column names
|
||||
*/
|
||||
protected function get_default_search_columns()
|
||||
{
|
||||
$cols = parent::get_default_search_columns();
|
||||
if ($this->customfields && !isset($this->columns_to_search))
|
||||
{
|
||||
$cols[] = $this->extra_table.'.'.$this->extra_value;
|
||||
}
|
||||
//error_log(__METHOD__."() this->columns_to_search=".array2string($this->columns_to_search).' returning '.array2string($cols));
|
||||
return $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to test if $field is a custom field: check for the prefix
|
||||
*
|
||||
|
@ -761,17 +761,8 @@ class calendar_so
|
||||
{
|
||||
$columns = array('cal_title','cal_description','cal_location');
|
||||
|
||||
$wildcard = $op = null;
|
||||
if(!is_null($params['cfs']))
|
||||
{
|
||||
$custom = Api\Storage\Customfields::get('calendar');
|
||||
if($custom)
|
||||
{
|
||||
$columns[] = 'cal_extra_value';
|
||||
$join .= " LEFT JOIN {$this->extra_table} ON {$this->extra_table}.cal_id = {$this->cal_table}.cal_id ";
|
||||
}
|
||||
}
|
||||
$so_sql = new Api\Storage\Base('calendar', $this->cal_table, $this->db);
|
||||
$wildcard = '%'; $op = null;
|
||||
$so_sql = new Api\Storage('calendar', $this->cal_table, $this->extra_table, '', 'cal_extra_name', 'cal_extra_value', 'cal_id', $this->db);
|
||||
$where = $so_sql->search2criteria($params['query'], $wildcard, $op, null, $columns);
|
||||
|
||||
// Searching - restrict private to own or private grant
|
||||
|
@ -904,20 +904,16 @@ class infolog_so
|
||||
if ($query['query']) $query['search'] = $query['query']; // allow both names
|
||||
if ($query['search']) // we search in _from, _subject, _des and _extra_value for $query
|
||||
{
|
||||
$columns = array('info_from','info_location','info_subject','info_extra_value');
|
||||
$columns = array('info_from','info_location','info_subject');
|
||||
// at the moment MaxDB 7.5 cant cast nor search text columns, it's suppost to change in 7.6
|
||||
if ($this->db->capabilities['like_on_text']) $columns[] = 'info_des';
|
||||
|
||||
$wildcard = $op = null;
|
||||
$so_sql = new Api\Storage\Base('infolog', $this->info_table, $this->db);
|
||||
$wildcard = '%'; $op = null;
|
||||
$so_sql = new Api\Storage('infolog', $this->info_table, $this->extra_table, '', 'info_extra_name', 'info_extra_value', 'info_id', $this->db);
|
||||
$so_sql->table_name = 'main';
|
||||
$search = $so_sql->search2criteria($query['search'], $wildcard, $op, null, $columns);
|
||||
$sql_query = 'AND ('.(is_numeric($query['search']) ? 'main.info_id='.(int)$query['search'].' OR ' : '').
|
||||
implode($op, $search) .')';
|
||||
|
||||
$join = ($cfcolfilter>0 ? '':'LEFT')." JOIN $this->extra_table ON main.info_id=$this->extra_table.info_id ";
|
||||
// mssql and others cant use DISTICT if text columns (info_des) are involved
|
||||
$distinct = $this->db->capabilities['distinct_on_text'] ? 'DISTINCT' : '';
|
||||
}
|
||||
$join .= " LEFT JOIN $this->users_table ON main.info_id=$this->users_table.info_id";
|
||||
if (strpos($query['filter'], '+deleted') === false)
|
||||
|
Loading…
Reference in New Issue
Block a user