예제 #1
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $property = $input->getArgument('property');
     $model = null;
     // "Volkszaehler\\Model\\Channel"
     $entity_groups = array();
     echo "Reporting property usage of '" . $property . "'\n";
     foreach (Definition\EntityDefinition::get() as $entity) {
         if ($model && $entity->getModel() !== $model) {
             continue;
         }
         if (!isset($entity_groups[$entity->getInterpreter()])) {
             $entity_groups[$entity->getInterpreter()] = array();
         }
         $entity_groups[$entity->getInterpreter()][] = $entity;
     }
     foreach ($entity_groups as $group => $entities) {
         echo "\n== " . $group . " ==\n";
         foreach ($entities as $entity) {
             echo str_pad($entity->getName() . ":", 16);
             if (in_array($property, $entity->required)) {
                 echo "required\n";
             } elseif (in_array($property, $entity->optional)) {
                 echo "optional\n";
             } else {
                 echo "not allowed\n";
             }
         }
         echo "\n";
     }
 }
 /**
  * @todo
  * @param string $capabilities
  * @param string $sub
  */
 public function get($section = NULL)
 {
     $capabilities = array();
     if (is_null($section) || $section == 'configuration') {
         $configuration = array('precision' => View\View::PRECISION, 'database' => Util\Configuration::read('db.driver'), 'debug' => Util\Configuration::read('debug'), 'devmode' => Util\Configuration::read('devmode'));
         $capabilities['configuration'] = $configuration;
     }
     if (is_null($section) || $section == 'formats') {
         $capabilities['formats'] = array_keys(\Volkszaehler\Router::$viewMapping);
     }
     if (is_null($section) || $section == 'contexts') {
         $capabilities['contexts'] = array_keys(\Volkszaehler\Router::$controllerMapping);
     }
     if (is_null($section) || $section == 'definitions') {
         if (!is_null($section)) {
             // only caching when we doesn't request dynamic informations
             $this->view->setCaching('expires', time() + 2 * 7 * 24 * 60 * 60);
             // cache for 2 weeks
         }
         $capabilities['definitions']['entities'] = Definition\EntityDefinition::get();
         $capabilities['definitions']['properties'] = Definition\PropertyDefinition::get();
     }
     if (count($capabilities) == 0) {
         throw new \Exception('Invalid capability identifier: \'' . $section . '\'');
     }
     return array('capabilities' => $capabilities);
 }
예제 #3
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $property = $input->getArgument('property');
     $model = null;
     // "Volkszaehler\\Model\\Channel"
     $entity_groups = array();
     echo "Reporting property usage of '" . $property . "'\n";
     foreach (Definition\EntityDefinition::get() as $entity) {
         if ($model && $entity->getModel() !== $model) {
             continue;
         }
         if (!isset($entity_groups[$entity->getInterpreter()])) {
             $entity_groups[$entity->getInterpreter()] = array();
         }
         $entity_groups[$entity->getInterpreter()][] = $entity;
     }
     foreach ($entity_groups as $group => $entities) {
         echo "\n== " . $group . " ==\n";
         foreach ($entities as $entity) {
             $name = $entity->getName();
             echo str_pad($name . ":", 20);
             $value = isset($entity->{$property}) ? $entity->{$property} : '';
             if ($property == "optional") {
                 // meta definition
                 if (is_array($value)) {
                     $value = sprintf("[%s]", join(',', $value));
                 }
                 printf("%s\n", $value);
             } else {
                 // actual property
                 if (in_array($property, $entity->required)) {
                     $required = "required";
                 } elseif (in_array($property, $entity->optional)) {
                     $required = "optional";
                 } else {
                     $required = "not allowed";
                 }
                 printf("%s\t%s\n", $required, $value);
             }
         }
         echo "\n";
     }
 }
 /**
  * @todo
  * @param string $capabilities
  * @param string $sub
  */
 public function get($section = NULL)
 {
     $capabilities = array();
     if (is_null($section) || $section == 'configuration') {
         $configuration = array('precision' => View\View::PRECISION, 'database' => Util\Configuration::read('db.driver'), 'debug' => Util\Configuration::read('debug'), 'devmode' => Util\Configuration::read('devmode'));
         if ($commit = Util\Debug::getCurrentCommit()) {
             $configuration['commit'] = $commit;
         }
         $capabilities['configuration'] = $configuration;
     }
     // db statistics - only if specifically requested
     if ($section == 'database') {
         $conn = $this->em->getConnection();
         // get DBAL connection from EntityManager
         // estimate InnoDB tables to avoid performance penalty
         $rows = $conn->fetchAssoc('EXPLAIN SELECT COUNT(id) FROM data USE INDEX (PRIMARY)');
         if (isset($rows['rows'])) {
             $rows = $rows['rows'];
         } else {
             // get correct values for MyISAM
             $rows = $conn->fetchColumn('SELECT COUNT(1) FROM data');
         }
         // database disc space consumption
         $sql = 'SELECT SUM(data_length + index_length) ' . 'FROM information_schema.tables ' . 'WHERE table_schema = ?';
         $size = $conn->fetchColumn($sql, array(Util\Configuration::read('db.dbname')));
         $aggregation = Util\Configuration::read('aggregation');
         $database = array('data_rows' => $rows, 'data_size' => $size, 'aggregation_enabled' => $aggregation ? 1 : 0);
         // aggregation table size
         if ($aggregation) {
             $agg_rows = $conn->fetchColumn('SELECT COUNT(1) FROM aggregate');
             $database['aggregation_rows'] = $agg_rows;
             $database['aggregation_ratio'] = $agg_rows ? $rows / $agg_rows : 0;
         }
         $capabilities['database'] = $database;
     }
     if (is_null($section) || $section == 'formats') {
         $capabilities['formats'] = array_keys(Router::$viewMapping);
     }
     if (is_null($section) || $section == 'contexts') {
         $capabilities['contexts'] = array_keys(Router::$controllerMapping);
     }
     if (is_null($section) || $section == 'definitions') {
         // unresolved artifact from Symfony migration
         // if (!is_null($section)) { // only caching when we don't request dynamic informations
         // 	$this->view->setCaching('expires', time()+2*7*24*60*60); // cache for 2 weeks
         // }
         $capabilities['definitions']['entities'] = Definition\EntityDefinition::get();
         $capabilities['definitions']['properties'] = Definition\PropertyDefinition::get();
     }
     if (count($capabilities) == 0) {
         throw new \Exception('Invalid capability identifier: \'' . $section . '\'');
     }
     return array('capabilities' => $capabilities);
 }
예제 #5
0
 public function getDefinition()
 {
     return Definition\EntityDefinition::get($this->type);
 }
예제 #6
0
 /**
  * Core data aggregation wrapper
  *
  * @param  string $uuid   channel UUID
  * @param  string $level  aggregation level (e.g. 'day')
  * @param  string $mode   'full' or 'delta' aggretation
  * @param  int    $period number of prior periods to aggregate in delta mode
  * @return int         	  number of affected rows
  */
 public function aggregate($uuid = null, $level = 'day', $mode = 'full', $period = null)
 {
     // validate settings
     if (!in_array($mode, array('full', 'delta'))) {
         throw new \RuntimeException('Unsupported aggregation mode ' . $mode);
     }
     if (!$this->isValidAggregationLevel($level)) {
         throw new \RuntimeException('Unsupported aggregation level ' . $level);
     }
     // get channel definition to select correct aggregation function
     $sqlParameters = array('channel');
     $sql = 'SELECT id, uuid, type FROM entities WHERE class = ?';
     if ($uuid) {
         $sqlParameters[] = $uuid;
         $sql .= ' AND uuid = ?';
     }
     $rows = 0;
     // aggregate each channel
     foreach ($this->conn->fetchAll($sql, $sqlParameters) as $row) {
         $entity = Definition\EntityDefinition::get($row['type']);
         $interpreter = $entity->getInterpreter();
         $rows += $this->aggregateChannel($row['id'], $interpreter, $mode, $level, $period);
     }
     return $rows;
 }
예제 #7
0
 private function compressChannel($channel)
 {
     if (null == ($definition = Definition\EntityDefinition::get($channel['type']))) {
         trigger_error('Could not find definition for type ' . $channel['type'], E_USER_WARNING);
         return false;
     }
     // interpreter class - provides grouping function
     $interpreter = $definition->interpreter;
     // Detect compressscheme
     if (isset($this->config['compressscheme'][$channel['uuid']])) {
         $cs = $this->config['compressscheme'][$channel['uuid']];
     } else {
         $cs = $this->config['compressscheme']['default'];
     }
     // Prepare compressscheme
     ksort($cs);
     $times = array_keys($cs);
     $times[] = 0;
     $timestamp = time();
     // Local timestamp should be consistent during our transactions
     // Run compression passes
     for ($i = 0; $i < count($times) - 1; $i++) {
         if ($cs[$times[$i]] == 0) {
             continue;
         }
         // Step 1: Detect oldest and newest dataset
         $datatimes = $this->sql_query("SELECT MIN(timestamp) AS min, MAX(timestamp) AS max FROM data WHERE channel_id = ? AND timestamp <= ? AND timestamp > ?", array($channel['id'], ($timestamp - $times[$i]) * 1000, $times[$i + 1] > 0 ? ($timestamp - $times[$i + 1]) * 1000 : 0));
         if ((double) $datatimes[0]['max'] == 0) {
             $this->out('  Skipping compression pass for data points between ' . $this->strftime($timestamp - $times[$i + 1]) . ' and ' . $this->strftime($timestamp - $times[$i]) . ' using a ' . $cs[$times[$i]] . ' seconds window: No data points found');
             continue;
         }
         // Caching
         $from = (double) $datatimes[0]['min'];
         $lastrun = (double) $this->cache_read($channel['id'], $times[$i]);
         if ($lastrun && (double) $lastrun >= $from) {
             $this->out('  Skipping data points between ' . $this->strftime($from / 1000) . ' and ' . $this->strftime((double) $lastrun / 1000) . ' (Cached)');
             (double) ($datatimes[0]['min'] = $lastrun);
         }
         $this->out('  Compressing data points between ' . $this->strftime($from / 1000) . ' and ' . $this->strftime((double) $datatimes[0]['max'] / 1000) . ' using a ' . $cs[$times[$i]] . ' seconds window');
         // Step 2: Loop new possible timeframes
         $curtime = (double) $datatimes[0]['min'];
         $lastpurgecount = $this->purgecounter;
         $steps = ((double) $datatimes[0]['max'] / 1000 - $from / 1000) / $cs[$times[$i]];
         if ($steps == 0) {
             continue;
         }
         $step = 0;
         $passstart = time();
         do {
             // Step 2.1: Increase timestamps
             $lastcurtime = $curtime;
             $curtime += $cs[$times[$i]] * 1000;
             $step++;
             // Print status
             if ($this->config['verbose']) {
                 $this->out('    Processing: ' . $this->strftime($lastcurtime / 1000) . ' - ' . $this->strftime($curtime / 1000) . ' (' . round(100 / $steps * $step) . '%)...', "\r");
             }
             // Step 2.1: Get new Value for timeframe
             $newset = $this->sql_query("SELECT " . $interpreter::groupExprSQL("value") . " AS newval, COUNT(value) AS datapoints, MAX(id) AS updateid " . "FROM data WHERE channel_id = ? AND timestamp > ? AND timestamp <= ?", array($channel['id'], $lastcurtime, $curtime));
             // Step 2.2: Skip if current timeframe has no or already just one datapoint
             if (count($newset) == 0 || $newset[0]['datapoints'] < 2) {
                 continue;
             }
             // wrap inside transaction
             $this->conn->transactional(function () use($channel, $newset, $curtime, $lastcurtime) {
                 // Step 2.3: Delete old data points
                 $this->sql_exec('DELETE FROM data WHERE channel_id = ? AND timestamp > ? AND timestamp <= ? AND id != ?', array($channel['id'], $lastcurtime, $curtime, $newset[0]['updateid']));
                 $this->purgecounter += $newset[0]['datapoints'] - 1;
                 // Step 2.4: Update oldest Datapoint
                 //           Note: Use UPDATE instead of INSERT to avoid filling up our id-pool
                 $this->sql_exec('UPDATE data SET timestamp = ?, value = ? WHERE channel_id = ? AND id = ?', array($curtime - 1, $newset[0]['newval'], $channel['id'], $newset[0]['updateid']));
             });
         } while ($curtime <= (double) $datatimes[0]['max']);
         $this->out('    Removed ' . ($this->purgecounter - $lastpurgecount) . ' data points in ' . (time() - $passstart) . ' seconds.', "\r");
         $this->cache_write($channel['id'], $times[$i], (double) $datatimes[0]['max']);
     }
 }
 /**
  * @param string $section select specific sub section for output
  */
 public function get($section = NULL)
 {
     $capabilities = array();
     if (is_null($section) || $section == 'configuration') {
         $configuration = array('precision' => View\View::PRECISION, 'database' => Util\Configuration::read('db.driver'), 'debug' => Util\Configuration::read('debug'), 'devmode' => Util\Configuration::read('devmode'));
         if ($commit = Util\Debug::getCurrentCommit()) {
             $configuration['commit'] = $commit;
         }
         $capabilities['configuration'] = $configuration;
     }
     // db statistics - only if specifically requested
     if ($section == 'database') {
         $conn = $this->em->getConnection();
         // get DBAL connection from EntityManager
         // estimate InnoDB tables to avoid performance penalty
         $rows = $this->sqlCount($conn, 'data');
         $size = $this->dbSize($conn, 'data');
         $aggregation = Util\Configuration::read('aggregation');
         $database = array('data_rows' => $rows, 'data_size' => $size, 'aggregation_enabled' => $aggregation ? 1 : 0);
         // aggregation table size
         if ($aggregation) {
             $agg_rows = $this->sqlCount($conn, 'aggregate');
             $agg_size = $this->dbSize($conn, 'aggregate');
             $database['aggregation_rows'] = $agg_rows;
             $database['aggregation_size'] = $agg_size;
             $database['aggregation_ratio'] = $agg_rows ? $rows / $agg_rows : 0;
         }
         $capabilities['database'] = $database;
     }
     if (is_null($section) || $section == 'formats') {
         $capabilities['formats'] = array_keys(Router::$viewMapping);
     }
     if (is_null($section) || $section == 'contexts') {
         $capabilities['contexts'] = array_keys(Router::$controllerMapping);
     }
     if (is_null($section) || $section == 'definitions') {
         // unresolved artifact from Symfony migration
         if (!is_null($section)) {
             // only caching when we don't request dynamic informations
             $this->view->setCaching('expires', time() + 2 * 7 * 24 * 60 * 60);
             // cache for 2 weeks
         }
         $capabilities['definitions']['entities'] = Definition\EntityDefinition::get();
         $capabilities['definitions']['properties'] = Definition\PropertyDefinition::get();
     }
     if (count($capabilities) == 0) {
         throw new \Exception('Invalid capability identifier: \'' . $section . '\'');
     }
     return array('capabilities' => $capabilities);
 }