diff options
Diffstat (limited to 'library/Icinga/Protocol/File/FileReader.php')
-rw-r--r-- | library/Icinga/Protocol/File/FileReader.php | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/library/Icinga/Protocol/File/FileReader.php b/library/Icinga/Protocol/File/FileReader.php new file mode 100644 index 0000000..a06494c --- /dev/null +++ b/library/Icinga/Protocol/File/FileReader.php @@ -0,0 +1,208 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Protocol\File; + +use Countable; +use ArrayIterator; +use Icinga\Data\Selectable; +use Icinga\Data\ConfigObject; + +/** + * Read file line by line + */ +class FileReader implements Selectable, Countable +{ + /** + * A PCRE string with the fields to extract from the file's lines as named subpatterns + * + * @var string + */ + protected $fields; + + /** + * Name of the target file + * + * @var string + */ + protected $filename; + + /** + * Cache for static::count() + * + * @var int + */ + protected $count = null; + + /** + * Create a new reader + * + * @param ConfigObject $config + * + * @throws FileReaderException If a required $config directive (filename or fields) is missing + */ + public function __construct(ConfigObject $config) + { + foreach (array('filename', 'fields') as $key) { + if (isset($config->{$key})) { + $this->{$key} = $config->{$key}; + } else { + throw new FileReaderException('The directive `%s\' is required', $key); + } + } + } + + /** + * Instantiate a FileIterator object with the target file + * + * @return FileIterator + */ + public function iterate() + { + return new LogFileIterator($this->filename, $this->fields); + } + + /** + * Instantiate a FileQuery object + * + * @return FileQuery + */ + public function select() + { + return new FileQuery($this); + } + + /** + * Fetch and return all rows of the given query's result set using an iterator + * + * @param FileQuery $query + * + * @return ArrayIterator + */ + public function query(FileQuery $query) + { + return new ArrayIterator($this->fetchAll($query)); + } + + /** + * Return the number of available valid lines. + * + * @return int + */ + public function count(): int + { + if ($this->count === null) { + $this->count = iterator_count($this->iterate()); + } + return $this->count; + } + + /** + * Fetch result as an array of objects + * + * @param FileQuery $query + * + * @return array + */ + public function fetchAll(FileQuery $query) + { + $all = array(); + foreach ($this->fetchPairs($query) as $index => $value) { + $all[$index] = (object) $value; + } + return $all; + } + + /** + * Fetch result as a key/value pair array + * + * @param FileQuery $query + * + * @return array + */ + public function fetchPairs(FileQuery $query) + { + $skip = $query->getOffset(); + $read = $query->getLimit(); + if ($skip === null) { + $skip = 0; + } + $lines = array(); + if ($query->sortDesc()) { + $count = $this->count(); + if ($count <= $skip) { + return $lines; + } elseif ($count < ($skip + $read)) { + $read = $count - $skip; + $skip = 0; + } else { + $skip = $count - ($skip + $read); + } + } + foreach ($this->iterate() as $index => $line) { + if ($index >= $skip) { + if ($index >= $skip + $read) { + break; + } + $lines[] = $line; + } + } + if ($query->sortDesc()) { + $lines = array_reverse($lines); + } + return $lines; + } + + /** + * Fetch first result row + * + * @param FileQuery $query + * + * @return object + */ + public function fetchRow(FileQuery $query) + { + $all = $this->fetchAll($query); + if (isset($all[0])) { + return $all[0]; + } + return null; + } + + /** + * Fetch first result column + * + * @param FileQuery $query + * + * @return array + */ + public function fetchColumn(FileQuery $query) + { + $column = array(); + foreach ($this->fetchPairs($query) as $pair) { + foreach ($pair as $value) { + $column[] = $value; + break; + } + } + return $column; + } + + /** + * Fetch first column value from first result row + * + * @param FileQuery $query + * + * @return mixed + */ + public function fetchOne(FileQuery $query) + { + $pairs = $this->fetchPairs($query); + if (isset($pairs[0])) { + foreach ($pairs[0] as $value) { + return $value; + } + } + return null; + } +} |