mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-10-31 03:14:31 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			418 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			418 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| // {{{ICINGA_LICENSE_HEADER}}}
 | |
| // {{{ICINGA_LICENSE_HEADER}}}
 | |
| 
 | |
| namespace Icinga\Data;
 | |
| 
 | |
| use Icinga\Application\Icinga;
 | |
| use Icinga\Data\Filter\Filter;
 | |
| use Icinga\Web\Paginator\Adapter\QueryAdapter;
 | |
| use Zend_Paginator;
 | |
| use Exception;
 | |
| use Icinga\Exception\IcingaException;
 | |
| 
 | |
| class SimpleQuery implements QueryInterface, Queryable
 | |
| {
 | |
|     /**
 | |
|      * Query data source
 | |
|      *
 | |
|      * @var mixed
 | |
|      */
 | |
|     protected $ds;
 | |
| 
 | |
|     /**
 | |
|      * The table you are going to query
 | |
|      */
 | |
|     protected $table;
 | |
| 
 | |
|     /**
 | |
|      * The columns you asked for
 | |
|      *
 | |
|      * All columns if null, no column if empty??? Alias handling goes here!
 | |
|      *
 | |
|      * @var array
 | |
|      */
 | |
|     protected $desiredColumns = array();
 | |
| 
 | |
|     /**
 | |
|      * The columns you are interested in
 | |
|      *
 | |
|      * All columns if null, no column if empty??? Alias handling goes here!
 | |
|      *
 | |
|      * @var array
 | |
|      */
 | |
|     protected $columns = array();
 | |
| 
 | |
|     /**
 | |
|      * The columns you're using to sort the query result
 | |
|      *
 | |
|      * @var array
 | |
|      */
 | |
|     protected $order = array();
 | |
| 
 | |
|     /**
 | |
|      * Number of rows to return
 | |
|      *
 | |
|      * @var int
 | |
|      */
 | |
|     protected $limitCount;
 | |
| 
 | |
|     /**
 | |
|      * Result starts with this row
 | |
|      *
 | |
|      * @var int
 | |
|      */
 | |
|     protected $limitOffset;
 | |
| 
 | |
|     protected $filter;
 | |
| 
 | |
|     /**
 | |
|      * Constructor
 | |
|      *
 | |
|      * @param mixed $ds
 | |
|      */
 | |
|     public function __construct($ds, $columns = null)
 | |
|     {
 | |
|         $this->ds = $ds;
 | |
|         $this->filter = Filter::matchAll();
 | |
|         if ($columns !== null) {
 | |
|             $this->desiredColumns = $columns;
 | |
|         }
 | |
|         $this->init();
 | |
|         if ($this->desiredColumns !== null) {
 | |
|             $this->columns($this->desiredColumns);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Initialize query
 | |
|      *
 | |
|      * Overwrite this instead of __construct (it's called at the end of the construct) to
 | |
|      * implement custom initialization logic on construction time
 | |
|      */
 | |
|     protected function init() {}
 | |
| 
 | |
|     /**
 | |
|      * Get the data source
 | |
|      *
 | |
|      * @return mixed
 | |
|      */
 | |
|     public function getDatasource()
 | |
|     {
 | |
|         return $this->ds;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Choose a table and the colums you are interested in
 | |
|      *
 | |
|      * Query will return all available columns if none are given here
 | |
|      *
 | |
|      * @return self
 | |
|      */
 | |
|     public function from($target, array $fields = null)
 | |
|     {
 | |
|         $this->target = $target;
 | |
|         if ($fields !== null) {
 | |
|             $this->columns($fields);
 | |
|         }
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add a where condition to the query by and
 | |
|      *
 | |
|      * The syntax of the condition and valid values are defined by the concrete backend-specific query implementation.
 | |
|      *
 | |
|      * @param   string  $condition
 | |
|      * @param   mixed   $value
 | |
|      *
 | |
|      * @return  self
 | |
|      */
 | |
|     public function where($condition, $value = null)
 | |
|     {
 | |
|         // TODO: more intelligence please
 | |
|         $this->filter->addFilter(Filter::expression($condition, '=', $value));
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function getFilter()
 | |
|     {
 | |
|         return $this->filter;
 | |
|     }
 | |
| 
 | |
|     public function applyFilter(Filter $filter)
 | |
|     {
 | |
|         return $this->addFilter($filter);
 | |
|     }
 | |
| 
 | |
|     public function addFilter(Filter $filter)
 | |
|     {
 | |
|         $this->filter->addFilter($filter);
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function setFilter(Filter $filter)
 | |
|     {
 | |
|         $this->filter = $filter;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function setOrderColumns(array $orderColumns)
 | |
|     {
 | |
|         throw new IcingaException('This function does nothing and will be removed');
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sort result set by the given field (and direction)
 | |
|      *
 | |
|      * Preferred usage:
 | |
|      * <code>
 | |
|      * $query->order('field, 'ASC')
 | |
|      * </code>
 | |
|      *
 | |
|      * @param  string   $field
 | |
|      * @param  string   $direction
 | |
|      *
 | |
|      * @return self
 | |
|      */
 | |
|     public function order($field, $direction = null)
 | |
|     {
 | |
|         if ($direction === null) {
 | |
|             $fieldAndDirection = explode(' ', $field, 2);
 | |
|             if (count($fieldAndDirection) === 1) {
 | |
|                 $direction = self::SORT_ASC;
 | |
|             } else {
 | |
|                 $field = $fieldAndDirection[0];
 | |
|                 $direction = (strtoupper(trim($fieldAndDirection[1])) === 'DESC') ?
 | |
|                     Sortable::SORT_DESC : Sortable::SORT_ASC;
 | |
|             }
 | |
|         } else {
 | |
|             switch (($direction = strtoupper($direction))) {
 | |
|                 case Sortable::SORT_ASC:
 | |
|                 case Sortable::SORT_DESC:
 | |
|                     break;
 | |
|                 default:
 | |
|                     $direction = Sortable::SORT_ASC;
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|         $this->order[] = array($field, $direction);
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function compare($a, $b, $col_num = 0)
 | |
|     {
 | |
|         // Last column to sort reached, rows are considered being equal
 | |
|         if (! array_key_exists($col_num, $this->order)) {
 | |
|             return 0;
 | |
|         }
 | |
|         $col = $this->order[$col_num][0];
 | |
|         $dir = $this->order[$col_num][1];
 | |
| // TODO: throw Exception if column is missing
 | |
|         //$res = strnatcmp(strtolower($a->$col), strtolower($b->$col));
 | |
|         $res = strcmp(strtolower($a->$col), strtolower($b->$col));
 | |
|         if ($res === 0) {
 | |
| //            return $this->compare($a, $b, $col_num++);
 | |
| 
 | |
|             if (array_key_exists(++$col_num, $this->order)) {
 | |
|                 return $this->compare($a, $b, $col_num);
 | |
|             } else {
 | |
|                 return 0;
 | |
|             }
 | |
| 
 | |
|         }
 | |
| 
 | |
|         if ($dir === self::SORT_ASC) {
 | |
|             return $res;
 | |
|         } else {
 | |
|             return $res * -1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Whether an order is set
 | |
|      *
 | |
|      * @return bool
 | |
|      */
 | |
|     public function hasOrder()
 | |
|     {
 | |
|         return !empty($this->order);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get the order if any
 | |
|      *
 | |
|      * @return array|null
 | |
|      */
 | |
|     public function getOrder()
 | |
|     {
 | |
|         return $this->order;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set a limit count and offset to the query
 | |
|      *
 | |
|      * @param   int $count  Number of rows to return
 | |
|      * @param   int $offset Start returning after this many rows
 | |
|      *
 | |
|      * @return  self
 | |
|      */
 | |
|     public function limit($count = null, $offset = null)
 | |
|     {
 | |
|         $this->limitCount = $count !== null ? (int) $count : null;
 | |
|         $this->limitOffset = (int) $offset;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Whether a limit is set
 | |
|      *
 | |
|      * @return bool
 | |
|      */
 | |
|     public function hasLimit()
 | |
|     {
 | |
|         return $this->limitCount !== null;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get the limit if any
 | |
|      *
 | |
|      * @return int|null
 | |
|      */
 | |
|     public function getLimit()
 | |
|     {
 | |
|         return $this->limitCount;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Whether an offset is set
 | |
|      *
 | |
|      * @return bool
 | |
|      */
 | |
|     public function hasOffset()
 | |
|     {
 | |
|         return $this->limitOffset > 0;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Get the offset if any
 | |
|      *
 | |
|      * @return int|null
 | |
|      */
 | |
|     public function getOffset()
 | |
|     {
 | |
|         return $this->limitOffset;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Paginate data
 | |
|      *
 | |
|      * Auto-detects pagination parameters from request when unset
 | |
|      *
 | |
|      * @param   int $itemsPerPage   Number of items per page
 | |
|      * @param   int $pageNumber     Current page number
 | |
|      *
 | |
|      * @return  Zend_Paginator
 | |
|      */
 | |
|     public function paginate($itemsPerPage = null, $pageNumber = null)
 | |
|     {
 | |
|         if ($itemsPerPage === null || $pageNumber === null) {
 | |
|             // Detect parameters from request
 | |
|             $request = Icinga::app()->getFrontController()->getRequest();
 | |
|             if ($itemsPerPage === null) {
 | |
|                 $itemsPerPage = $request->getParam('limit', 20);
 | |
|             }
 | |
|             if ($pageNumber === null) {
 | |
|                 $pageNumber = $request->getParam('page', 0);
 | |
|             }
 | |
|         }
 | |
|         $this->limit($itemsPerPage, $pageNumber * $itemsPerPage);
 | |
|         $paginator = new Zend_Paginator(new QueryAdapter($this));
 | |
|         $paginator->setItemCountPerPage($itemsPerPage);
 | |
|         $paginator->setCurrentPageNumber($pageNumber);
 | |
|         return $paginator;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Retrieve an array containing all rows of the result set
 | |
|      *
 | |
|      * @return array
 | |
|      */
 | |
|     public function fetchAll()
 | |
|     {
 | |
|         return $this->ds->fetchAll($this);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Fetch the first row of the result set
 | |
|      *
 | |
|      * @return mixed
 | |
|      */
 | |
|     public function fetchRow()
 | |
|     {
 | |
|         return $this->ds->fetchRow($this);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Fetch a column of all rows of the result set as an array
 | |
|      *
 | |
|      * @param   int $columnIndex Index of the column to fetch
 | |
|      *
 | |
|      * @return  array
 | |
|      */
 | |
|     public function fetchColumn($columnIndex = 0)
 | |
|     {
 | |
|         return $this->ds->fetchColumn($this, $columnIndex);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Fetch the first column of the first row of the result set
 | |
|      *
 | |
|      * @return string
 | |
|      */
 | |
|     public function fetchOne()
 | |
|     {
 | |
|         return $this->ds->fetchOne($this);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Fetch all rows of the result set as an array of key-value pairs
 | |
|      *
 | |
|      * The first column is the key, the second column is the value.
 | |
|      *
 | |
|      * @return array
 | |
|      */
 | |
|     public function fetchPairs()
 | |
|     {
 | |
|         return $this->ds->fetchPairs($this);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Count all rows of the result set
 | |
|      *
 | |
|      * @return int
 | |
|      */
 | |
|     public function count()
 | |
|     {
 | |
|         return $this->ds->count($this);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set columns
 | |
|      *
 | |
|      * @param   array $columns
 | |
|      *
 | |
|      * @return  self
 | |
|      */
 | |
|     public function columns(array $columns)
 | |
|     {
 | |
|         $this->columns = $columns;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     public function getColumns()
 | |
|     {
 | |
|         return $this->columns;
 | |
|     }
 | |
| }
 |