mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-23 00:13:35 +01:00
iterator to run arbitrary callbacks on a select
This commit is contained in:
parent
1943b35303
commit
12e8a3bbcd
@ -1180,7 +1180,7 @@ class egw_db
|
|||||||
* @param string $expr column-name or expression optional prefixed with "DISTINCT"
|
* @param string $expr column-name or expression optional prefixed with "DISTINCT"
|
||||||
* @param string $order_by='' optional order
|
* @param string $order_by='' optional order
|
||||||
* @param string $separator=',' optional separator, default is comma
|
* @param string $separator=',' optional separator, default is comma
|
||||||
* @return string
|
* @return string|boolean false if not supported by dbms
|
||||||
*/
|
*/
|
||||||
function group_concat($expr, $order_by='', $separator=',')
|
function group_concat($expr, $order_by='', $separator=',')
|
||||||
{
|
{
|
||||||
@ -1194,13 +1194,17 @@ class egw_db
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'pgsql': // requires for Postgresql < 8.4 to have a custom ARRAY_AGG method installed!
|
case 'pgsql': // requires for Postgresql < 8.4 to have a custom ARRAY_AGG method installed!
|
||||||
|
if ($this->Type == 'pgsql' && $this->ServerInfo['version'] < 8.4)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$sql = 'ARRAY_TO_STRING(ARRAY_AGG('.$expr;
|
$sql = 'ARRAY_TO_STRING(ARRAY_AGG('.$expr;
|
||||||
if ($order_by) $sql .= ' ORDER BY '.$order_by;
|
if ($order_by) $sql .= ' ORDER BY '.$order_by;
|
||||||
$sql .= '), '.$this->quote($separator).')';
|
$sql .= '), '.$this->quote($separator).')';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // probably gives an sql error anyway
|
default: // probably gives an sql error anyway
|
||||||
$sql = $expr;
|
return false;
|
||||||
}
|
}
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
@ -2078,3 +2082,174 @@ class egw_db
|
|||||||
array_combine($keys,$arr) : $arr;
|
array_combine($keys,$arr) : $arr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator applying a given callback on each element retrived, eg. from a select query
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* function rows(array $where)
|
||||||
|
* {
|
||||||
|
* global $db, $table, $columns, $prefix;
|
||||||
|
*
|
||||||
|
* return new egw_db_callback_iterator($db->select($table, $columns, $where), function($row) use ($prefix)
|
||||||
|
* {
|
||||||
|
* return egw_db::strip_array_keys($row, $prefix);
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* foreach(row(array('attr' => 'value')) as $row)
|
||||||
|
* {
|
||||||
|
* // $row keys have prefix removed, or whatever you implement in callback
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Example with a key-callback:
|
||||||
|
*
|
||||||
|
* function rows(array $where)
|
||||||
|
* {
|
||||||
|
* global $db, $table, $columns, $prefix;
|
||||||
|
*
|
||||||
|
* return new egw_db_callback_iterator($db->select($table, $columns, $where), function($row) use ($prefix)
|
||||||
|
* {
|
||||||
|
* return egw_db::strip_array_keys($row, $prefix);
|
||||||
|
* }, array(), function($row)
|
||||||
|
* {
|
||||||
|
* return $row['id'];
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* foreach(rows(array('attr' => 'value')) as $key => $row)
|
||||||
|
* {
|
||||||
|
* // $key is now value of column 'id', $row as above
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class egw_db_callback_iterator implements Iterator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Reference of so_sql class to use it's db2data method
|
||||||
|
*
|
||||||
|
* @var callback
|
||||||
|
*/
|
||||||
|
private $callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Further parameter for callback
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $params = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional callback, if you want different keys
|
||||||
|
*
|
||||||
|
* @var callback
|
||||||
|
*/
|
||||||
|
private $key_callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of ADOdb record set to iterate
|
||||||
|
*
|
||||||
|
* @var Iterator
|
||||||
|
*/
|
||||||
|
private $rs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total count of entries
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $total;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param Traversable $rs
|
||||||
|
* @param callback $callback
|
||||||
|
* @param array $parms=array() additional parameters, row is always first parameter
|
||||||
|
* @param $key_callback=null optional callback, if you want different keys
|
||||||
|
*/
|
||||||
|
public function __construct(Traversable $rs, $callback, $params=array(), $key_callback=null)
|
||||||
|
{
|
||||||
|
$this->callback = $callback;
|
||||||
|
$this->params = $params;
|
||||||
|
$this->key_callback = $key_callback;
|
||||||
|
|
||||||
|
if (is_a($rs,'IteratorAggregate'))
|
||||||
|
{
|
||||||
|
$this->rs = $rs->getIterator();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->rs = $rs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current element
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
if (is_a($this->rs,'iterator'))
|
||||||
|
{
|
||||||
|
$params = $this->params;
|
||||||
|
array_unshift($params, $this->rs->current());
|
||||||
|
return call_user_func_array($this->callback, $params);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the key of the current element
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
if (is_a($this->rs,'iterator'))
|
||||||
|
{
|
||||||
|
return $this->key_callback ?
|
||||||
|
call_user_func($this->key_callback, $this->rs->current()) :
|
||||||
|
$this->rs->key();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move forward to next element (called after each foreach loop)
|
||||||
|
*/
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
if (is_a($this->rs,'iterator'))
|
||||||
|
{
|
||||||
|
return $this->rs->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rewind the Iterator to the first element (called at beginning of foreach loop)
|
||||||
|
*/
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
if (is_a($this->rs,'iterator'))
|
||||||
|
{
|
||||||
|
return $this->rs->rewind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if current position is valid
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function valid ()
|
||||||
|
{
|
||||||
|
if (is_a($this->rs,'iterator'))
|
||||||
|
{
|
||||||
|
return $this->rs->valid();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user