diff --git a/lib/Controller/DataController.php b/lib/Controller/DataController.php
index a973fe6..9a2e07b 100644
--- a/lib/Controller/DataController.php
+++ b/lib/Controller/DataController.php
@@ -40,8 +40,11 @@ class DataController extends Controller {
public function get(Model\Entity $entity) {
$from = $this->view->request->getParameter('from');
$to = $this->view->request->getParameter('to');
+ $tuples = $this->view->request->getParameter('tuples');
+ $groupBy = $this->view->request->getParameter('group');
+ $class = $entity->getDefinition()->getInterpreter();
- return $entity->getInterpreter($this->em, $from, $to);
+ return new $class($entity, $this->em, $from, $to, $tuples, $groupBy);
}
/**
diff --git a/lib/Interpreter/Iterator/DataAggregationIterator.php b/lib/Interpreter/DataIterator.php
similarity index 55%
rename from lib/Interpreter/Iterator/DataAggregationIterator.php
rename to lib/Interpreter/DataIterator.php
index 6d161b1..dfd7382 100644
--- a/lib/Interpreter/Iterator/DataAggregationIterator.php
+++ b/lib/Interpreter/DataIterator.php
@@ -21,21 +21,25 @@
* along with volkszaehler.org. If not, see .
*/
-namespace Volkszaehler\Interpreter\Iterator;
+namespace Volkszaehler\Interpreter;
use Volkszaehler\Util;
-
use Doctrine\DBAL;
/**
* @author Steffen Vogel
* @package default
*/
-class DataAggregationIterator implements \Iterator, \Countable {
+class DataIterator implements \Iterator, \Countable {
+ protected $stmt; // PDO statement
+
protected $current; // the current data
protected $key; // key
- protected $size; // total readings in PDOStatement
- protected $iterator; // subiterator
+ private $rowKey; // internal key for PDO statement
+
+ protected $rowCount; // num of readings in PDOStatement
+ protected $tupleCount; // num of requested tuples
+ protected $packageSize; // num of rows we aggregate in each tuple
/**
* Constructor
@@ -44,28 +48,40 @@ class DataAggregationIterator implements \Iterator, \Countable {
* @param integer $size
* @param integer $tuples
*/
- public function __construct(\PDOStatement $stmt, $rows, $count) {
- $this->iterator = new DataIterator($stmt, $rows);
+ public function __construct(\PDOStatement $stmt, $rowCount, $tupleCount) {
+ $this->rowCount = $rowCount;
+ $this->tupleCount = $tupleCount;
+
+ $this->stmt = $stmt;
+ $this->stmt->setFetchMode(\PDO::FETCH_NUM);
- $this->packageSize = floor($rows / $count);
- $this->size = $count;
+ if ($this->rowCount > $this->tupleCount) {
+ $this->packageSize = floor($this->rowCount / $this->tupleCount);
+ $this->tupleCount = floor($this->rowCount / $this->packageSize) + $this->rowCount % $this->packageSize;
+ }
+ else {
+ $this->packageSize = 1;
+ }
}
/**
* Aggregate data
*/
public function next() {
- $this->current = array(0, 0, 0);
- for ($i = 0; $i < $this->packageSize; $i++, $this->iterator->next()) {
- $tuple = $this->iterator->current();
+ $package = array(0, 0, 0);
+ for ($i = 0; $i < $this->packageSize && $this->valid(); $i++) {
+ $tuple = $this->stmt->fetch();
- $this->current[0] = $tuple[0];
- $this->current[1] += $tuple[1];
- $this->current[2] += $tuple[2];
+ $package[0] = $tuple[0];
+ $package[1] += $tuple[1];
+ $package[2] += $tuple[2];
+
+ $this->rowKey++;
}
-
+
$this->key++;
- return $this->current;
+ Util\Debug::log('key++', $this->key);
+ return $this->current = $package;
}
/**
@@ -75,24 +91,18 @@ class DataAggregationIterator implements \Iterator, \Countable {
* PDOStatement hasn't a rewind()
*/
public function rewind() {
- $this->iterator->rewind();
- // skip first readings to get an even divisor
- $skip = count($this->iterator) - count($this) * $this->packageSize;
- for ($i = 0; $i < $skip; $i++) {
- $this->iterator->next();
- }
- return $this->next();
+ $this->key = $this->rowKey = 0;
}
public function valid() {
- return $this->key <= $this->size;
+ return $this->rowKey < $this->rowCount;
}
/**
* Getter & setter
*/
public function getPackageSize() { return $this->packageSize; }
- public function count() { return $this->size; }
+ public function count() { return $this->tupleCount; }
public function key() { return $this->key; }
public function current() { return $this->current; }
}
diff --git a/lib/Interpreter/Interpreter.php b/lib/Interpreter/Interpreter.php
index ca012d2..67b0534 100644
--- a/lib/Interpreter/Interpreter.php
+++ b/lib/Interpreter/Interpreter.php
@@ -43,6 +43,7 @@ abstract class Interpreter {
protected $from;
protected $to;
+ protected $groupBy;
protected $rowCount = NULL;
protected $tupleCount = NULL;
@@ -55,14 +56,25 @@ abstract class Interpreter {
* @param integer $from timestamp in ms since 1970
* @param integer $to timestamp in ms since 1970
*/
- public function __construct(Model\Channel $channel, ORM\EntityManager $em, $from, $to) {
+ public function __construct(Model\Channel $channel, ORM\EntityManager $em, $from, $to, $tupleCount, $groupBy) {
$this->channel = $channel;
+ $this->tupleCount = $tupleCount;
+ $this->groupBy = $groupBy;
// get dbal connection from EntityManager
$this->conn = $em->getConnection();
- $this->from = (isset($from)) ? self::parseDateTimeString($from, time() * 1000) : NULL;
- $this->to = (isset($to)) ? self::parseDateTimeString($to, (isset($this->from)) ? $this->from : time() * 1000) : NULL;
+ $this->from = $from;
+ $this->to = $to;
+
+ // parse interval
+ if (isset($from)) {
+ $this->from = self::parseDateTimeString($from, time() * 1000);
+ }
+
+ if (isset($to)) {
+ $this->to = self::parseDateTimeString($to, (isset($this->from)) ? $this->from : time() * 1000);
+ }
if (isset($this->from) && isset($this->to) && $this->from > $this->to) {
throw new \Exception('&from is larger than &to parameter');
@@ -75,13 +87,13 @@ abstract class Interpreter {
* @param string|integer $groupBy
* @return Volkszaehler\DataIterator
*/
- protected function getData($count = NULL, $groupBy = NULL) {
+ protected function getData() {
// prepare sql
$sql['from'] = ' FROM data';
$sql['where'] = ' WHERE channel_id = ?' . self::buildDateTimeFilterSQL($this->from, $this->to);
$sql['orderBy'] = ' ORDER BY timestamp ASC';
- if ($groupBy && $sql['groupFields'] = self::buildGroupBySQL($groupBy)) {
+ if ($this->groupBy && $sql['groupFields'] = self::buildGroupBySQL($this->groupBy)) {
$sql['rowCount'] = 'SELECT COUNT(DISTINCT ' . $sql['groupFields'] . ')' . $sql['from'] . $sql['where'];
$sql['fields'] = ' MAX(timestamp) AS timestamp, SUM(value) AS value, COUNT(timestamp) AS count';
$sql['groupBy'] = ' GROUP BY ' . $sql['groupFields'];
@@ -98,15 +110,10 @@ abstract class Interpreter {
// query for data
$stmt = $this->conn->executeQuery('SELECT ' . $sql['fields'] . $sql['from'] . $sql['where'] . $sql['groupBy'] . $sql['orderBy'], array($this->channel->getId()));
- // return iterators
- if ($sql['groupBy'] || is_null($count) || $this->rowCount < $count) {
- $this->tupleCount = $this->rowCount;
- return new Iterator\DataIterator($stmt, $this->rowCount);
- }
- else {
- $this->tupleCount = $count;
- return new Iterator\DataAggregationIterator($stmt, $this->rowCount, $count);
- }
+ Util\Debug::log('rowcount', $this->rowCount);
+ Util\Debug::log('tuplecount', $this->tupleCount);
+
+ return new DataIterator($stmt, $this->rowCount, $this->tupleCount);
}
/**
diff --git a/lib/Interpreter/Iterator/DataIterator.php b/lib/Interpreter/Iterator/DataIterator.php
deleted file mode 100644
index ad3f590..0000000
--- a/lib/Interpreter/Iterator/DataIterator.php
+++ /dev/null
@@ -1,100 +0,0 @@
-.
- */
-
-namespace Volkszaehler\Interpreter\Iterator;
-
-use Volkszaehler\Util;
-use Doctrine\DBAL;
-
-/**
- * @author Steffen Vogel
- * @package default
- */
-class DataIterator implements \Iterator, \Countable {
- protected $current; // the current data
- protected $key; // key
- protected $stmt; // PDOStatement
- protected $size; // total readings in PDOStatement
-
- /**
- * Constructor
- *
- * @param \PDOStatement $stmt
- * @param integer $size
- */
- public function __construct(\PDOStatement $stmt, $size) {
- $this->size = $size;
- $this->stmt = $stmt;
- $this->stmt->setFetchMode(\PDO::FETCH_NUM);
- }
-
- /**
- * @return array with data
- */
- public function current() {
- return $this->current;
- }
-
- /**
- * Fetch next row from database
- */
- public function next() {
- $this->key++;
- return $this->current = $this->stmt->fetch();
- }
-
- /**
- * @return integer the nth data row
- */
- public function key() {
- return $this->key;
- }
-
- /**
- * @return boolean do we have another row in the resultset?
- */
- public function valid() {
- return is_array($this->current);
- }
-
- /**
- * Rewind the iterator
- *
- * Should only be called once
- * PDOStatement hasn't a rewind() aquivalent
- */
- public function rewind() {
- $this->key = 0;
- return $this->current = $this->stmt->fetch();
- }
-
- /**
- * Get total num of rows
- * @return integer
- */
- public function count() {
- return $this->size;
- }
-}
-
-?>
diff --git a/lib/Interpreter/MeterInterpreter.php b/lib/Interpreter/MeterInterpreter.php
index c06ab8b..b544914 100644
--- a/lib/Interpreter/MeterInterpreter.php
+++ b/lib/Interpreter/MeterInterpreter.php
@@ -85,14 +85,15 @@ class MeterInterpreter extends Interpreter {
* @todo untested
* @return array with timestamp, values, and pulse count
*/
- public function processData($count, $groupBy, $callback) {
- $pulses = parent::getData($count, $groupBy);
+ public function processData($callback) {
+ $pulses = parent::getData();
$this->resolution = $this->channel->getProperty('resolution');
$this->pulseCount = 0;
$tuples = array();
- $last = $pulses->rewind();
+ $pulses->rewind();
+ $last = $pulses->next();
$next = $pulses->next();
while ($pulses->valid()) {
diff --git a/lib/Model/Entity.php b/lib/Model/Entity.php
index b6ac43b..6b37704 100644
--- a/lib/Model/Entity.php
+++ b/lib/Model/Entity.php
@@ -185,19 +185,6 @@ abstract class Entity {
public function getUuid() { return $this->uuid; } // read only
public function getType() { return $this->type; } // read only
public function getDefinition() { return Definition\EntityDefinition::get($this->type); }
-
- /**
- * Get interpreter to obtain data and statistical information for a given time interval
- *
- * @param Doctrine\ORM\EntityManager $em
- * @param integer $from timestamp in ms since 1970
- * @param integer $to timestamp in ms since 1970
- * @return Interpreter
- */
- public function getInterpreter(\Doctrine\ORM\EntityManager $em, $from, $to) {
- $class = $this->getDefinition()->getInterpreter();
- return new $class($this, $em, $from, $to);
- }
}
?>
diff --git a/lib/View/JSON.php b/lib/View/JSON.php
index 1b03a42..5ac087c 100644
--- a/lib/View/JSON.php
+++ b/lib/View/JSON.php
@@ -202,8 +202,6 @@ class JSON extends View {
$this->json['data']['uuid'] = $interpreter->getEntity()->getUuid();
$data = $interpreter->processData(
- $this->request->getParameter('tuples'),
- $this->request->getParameter('group'),
function($tuple) {
return array(
$tuple[0],