2013-06-07 11:44:37 +02:00
|
|
|
<?php
|
2015-02-04 10:46:36 +01:00
|
|
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
2013-06-07 11:44:37 +02:00
|
|
|
|
2013-08-20 23:21:36 +02:00
|
|
|
namespace Icinga\Data\DataArray;
|
2013-06-07 11:44:37 +02:00
|
|
|
|
2015-05-18 16:01:58 +02:00
|
|
|
use ArrayIterator;
|
2014-06-06 08:21:35 +02:00
|
|
|
use Icinga\Data\Selectable;
|
|
|
|
use Icinga\Data\SimpleQuery;
|
2013-08-20 23:21:36 +02:00
|
|
|
|
2014-06-06 08:21:35 +02:00
|
|
|
class ArrayDatasource implements Selectable
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* The array being used as data source
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2013-06-07 11:44:37 +02:00
|
|
|
protected $data;
|
2015-02-03 16:27:59 +01:00
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* The current result
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
protected $result;
|
2013-06-07 11:44:37 +02:00
|
|
|
|
2015-05-06 10:08:07 +02:00
|
|
|
/**
|
|
|
|
* The result of a counted query
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $count;
|
|
|
|
|
2015-05-06 08:40:02 +02:00
|
|
|
/**
|
|
|
|
* The name of the column to map array keys on
|
|
|
|
*
|
|
|
|
* In case the array being used as data source provides keys of type string,this name
|
|
|
|
* will be used to set such as column on each row, if the column is not set already.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $keyColumn;
|
|
|
|
|
2013-06-07 11:44:37 +02:00
|
|
|
/**
|
2015-05-06 09:12:48 +02:00
|
|
|
* Create a new data source for the given array
|
2013-06-07 11:44:37 +02:00
|
|
|
*
|
2015-05-06 09:12:48 +02:00
|
|
|
* @param array $data The array you're going to use as a data source
|
2013-06-07 11:44:37 +02:00
|
|
|
*/
|
2015-05-06 09:12:48 +02:00
|
|
|
public function __construct(array $data)
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
2015-05-06 09:12:48 +02:00
|
|
|
$this->data = $data;
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 08:40:02 +02:00
|
|
|
/**
|
|
|
|
* Set the name of the column to map array keys on
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setKeyColumn($name)
|
|
|
|
{
|
|
|
|
$this->keyColumn = $name;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the name of the column to map array keys on
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getKeyColumn()
|
|
|
|
{
|
|
|
|
return $this->keyColumn;
|
|
|
|
}
|
|
|
|
|
2013-06-07 11:44:37 +02:00
|
|
|
/**
|
2015-05-06 09:12:48 +02:00
|
|
|
* Provide a query for this data source
|
2013-06-07 11:44:37 +02:00
|
|
|
*
|
2015-05-06 09:12:48 +02:00
|
|
|
* @return SimpleQuery
|
2013-06-07 11:44:37 +02:00
|
|
|
*/
|
|
|
|
public function select()
|
|
|
|
{
|
2014-06-06 08:21:35 +02:00
|
|
|
return new SimpleQuery($this);
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
2015-05-18 16:01:58 +02:00
|
|
|
/**
|
|
|
|
* Fetch and return all rows of the given query's result set using an iterator
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return ArrayIterator
|
|
|
|
*/
|
|
|
|
public function query(SimpleQuery $query)
|
|
|
|
{
|
|
|
|
return new ArrayIterator($this->fetchAll($query));
|
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Fetch and return a column of all rows of the result set as an array
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
public function fetchColumn(SimpleQuery $query)
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
|
|
|
$result = array();
|
|
|
|
foreach ($this->getResult($query) as $row) {
|
|
|
|
$arr = (array) $row;
|
|
|
|
$result[] = array_shift($arr);
|
|
|
|
}
|
2015-05-06 10:08:07 +02:00
|
|
|
|
2013-06-07 11:44:37 +02:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Fetch and return all rows of the given query's result as a flattened key/value based array
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
public function fetchPairs(SimpleQuery $query)
|
2013-07-12 13:40:21 +02:00
|
|
|
{
|
|
|
|
$result = array();
|
|
|
|
$keys = null;
|
|
|
|
foreach ($this->getResult($query) as $row) {
|
|
|
|
if ($keys === null) {
|
|
|
|
$keys = array_keys((array) $row);
|
|
|
|
if (count($keys) < 2) {
|
|
|
|
$keys[1] = $keys[0];
|
|
|
|
}
|
|
|
|
}
|
2015-05-06 10:08:07 +02:00
|
|
|
|
2013-07-12 13:40:21 +02:00
|
|
|
$result[$row->{$keys[0]}] = $row->{$keys[1]};
|
|
|
|
}
|
2015-05-06 10:08:07 +02:00
|
|
|
|
2013-07-12 13:40:21 +02:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Fetch and return the first row of the given query's result
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return object|false The row or false in case the result is empty
|
|
|
|
*/
|
2014-06-21 02:27:27 +02:00
|
|
|
public function fetchRow(SimpleQuery $query)
|
|
|
|
{
|
|
|
|
$result = $this->getResult($query);
|
|
|
|
if (empty($result)) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-05-06 10:10:29 +02:00
|
|
|
|
|
|
|
return array_shift($result);
|
2014-06-21 02:27:27 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Fetch and return all rows of the given query's result as an array
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
public function fetchAll(SimpleQuery $query)
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
2014-03-19 16:57:11 +01:00
|
|
|
return $this->getResult($query);
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Count all rows of the given query's result
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return int
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
public function count(SimpleQuery $query)
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
2015-05-06 10:08:07 +02:00
|
|
|
if ($this->count === null) {
|
|
|
|
$this->count = count($this->createResult($query));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->count;
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
2015-05-06 10:08:07 +02:00
|
|
|
* Create and return the result for the given query
|
2015-05-06 09:12:48 +02:00
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
2015-05-06 10:08:07 +02:00
|
|
|
* @return array
|
2015-05-06 09:12:48 +02:00
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
protected function createResult(SimpleQuery $query)
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
2013-10-15 19:56:33 +02:00
|
|
|
$columns = $query->getColumns();
|
2014-06-06 08:21:35 +02:00
|
|
|
$filter = $query->getFilter();
|
2015-05-06 09:39:43 +02:00
|
|
|
$offset = $query->hasOffset() ? $query->getOffset() : 0;
|
|
|
|
$limit = $query->hasLimit() ? $query->getLimit() : 0;
|
2015-05-06 10:08:07 +02:00
|
|
|
|
2015-05-06 08:40:02 +02:00
|
|
|
$foundStringKey = false;
|
|
|
|
$result = array();
|
2015-05-06 09:39:43 +02:00
|
|
|
$skipped = 0;
|
2015-05-06 08:40:02 +02:00
|
|
|
foreach ($this->data as $key => $row) {
|
|
|
|
if (is_string($key) && $this->keyColumn !== null && !isset($row->{$this->keyColumn})) {
|
|
|
|
$row = clone $row; // Make sure that this won't affect the actual data
|
|
|
|
$row->{$this->keyColumn} = $key;
|
|
|
|
}
|
2013-06-07 11:44:37 +02:00
|
|
|
|
2014-06-06 08:21:35 +02:00
|
|
|
if (! $filter->matches($row)) {
|
|
|
|
continue;
|
2015-05-06 09:39:43 +02:00
|
|
|
} elseif ($skipped < $offset) {
|
|
|
|
$skipped++;
|
|
|
|
continue;
|
2014-06-06 08:21:35 +02:00
|
|
|
}
|
2013-06-07 11:44:37 +02:00
|
|
|
|
|
|
|
// Get only desired columns if asked so
|
2015-05-06 08:40:02 +02:00
|
|
|
if (! empty($columns)) {
|
|
|
|
$filteredRow = (object) array();
|
|
|
|
foreach ($columns as $alias => $name) {
|
|
|
|
if (! is_string($alias)) {
|
|
|
|
$alias = $name;
|
2013-07-12 13:40:21 +02:00
|
|
|
}
|
2015-05-06 08:40:02 +02:00
|
|
|
|
|
|
|
if (isset($row->$name)) {
|
|
|
|
$filteredRow->$alias = $row->$name;
|
2013-06-07 11:44:37 +02:00
|
|
|
} else {
|
2015-05-06 08:40:02 +02:00
|
|
|
$filteredRow->$alias = null;
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-06 08:40:02 +02:00
|
|
|
} else {
|
|
|
|
$filteredRow = $row;
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
2015-05-06 08:40:02 +02:00
|
|
|
|
|
|
|
$foundStringKey |= is_string($key);
|
|
|
|
$result[$key] = $filteredRow;
|
2015-05-06 09:39:43 +02:00
|
|
|
|
|
|
|
if (count($result) === $limit) {
|
|
|
|
break;
|
|
|
|
}
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Sort the result
|
|
|
|
if ($query->hasOrder()) {
|
2015-05-06 08:40:02 +02:00
|
|
|
if ($foundStringKey) {
|
|
|
|
uasort($result, array($query, 'compare'));
|
|
|
|
} else {
|
|
|
|
usort($result, array($query, 'compare'));
|
|
|
|
}
|
|
|
|
} elseif (! $foundStringKey) {
|
|
|
|
$result = array_values($result);
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 10:08:07 +02:00
|
|
|
return $result;
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Return whether a query result exists
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
protected function hasResult()
|
|
|
|
{
|
|
|
|
return $this->result !== null;
|
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Set the current result
|
|
|
|
*
|
|
|
|
* @param array $result
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
protected function setResult(array $result)
|
2014-06-06 08:21:35 +02:00
|
|
|
{
|
2015-05-06 09:12:48 +02:00
|
|
|
$this->result = $result;
|
|
|
|
return $this;
|
2014-06-06 08:21:35 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 09:12:48 +02:00
|
|
|
/**
|
|
|
|
* Return the result for the given query
|
|
|
|
*
|
|
|
|
* @param SimpleQuery $query
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2014-06-06 08:21:35 +02:00
|
|
|
protected function getResult(SimpleQuery $query)
|
2013-06-07 11:44:37 +02:00
|
|
|
{
|
2014-06-06 08:21:35 +02:00
|
|
|
if (! $this->hasResult()) {
|
2015-05-06 10:08:07 +02:00
|
|
|
$this->setResult($this->createResult($query));
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
2015-05-06 10:08:07 +02:00
|
|
|
|
2015-05-06 09:39:43 +02:00
|
|
|
return $this->result;
|
2013-06-07 11:44:37 +02:00
|
|
|
}
|
|
|
|
}
|