diff --git a/api/r6/routes/data.php b/api/r6/routes/data.php index b6d5827..ac551c4 100644 --- a/api/r6/routes/data.php +++ b/api/r6/routes/data.php @@ -11,9 +11,12 @@ /** * */ -$api->put('/data/:guid', $APIkeyRequired, function($guid) use ($api) { - - $request = json_decode($api->request->getBody(), TRUE); +$api->put( + '/data/:guid', + $APIkeyRequired, + function($guid) use ($api) +{ + $request = json_decode($api->request->getBody(), true); // Check request for 'timestamp' attribute, take as is if numeric, // otherwise convert datetime to timestamp @@ -31,11 +34,10 @@ } if ($cnt) $api->stopAPI($cnt.' reading(s) added', 201); - })->name('PUT /data/:guid')->help = array( 'since' => 'r2', 'description' => 'Save a reading value', - 'apikey' => TRUE, + 'apikey' => true, 'payload' => array( '{"data":""}' => 'JSON encoded value, use server time', '{"data":"","timestamp":""}' => 'JSON encoded value, use provided timestamp', @@ -46,8 +48,12 @@ /** * */ -$api->post('/data/:guid', $APIkeyRequired, function($guid) use ($api) { - $request = json_decode($api->request->getBody(), TRUE); +$api->post( + '/data/:guid', + $APIkeyRequired, + function($guid) use ($api) +{ + $request = json_decode($api->request->getBody(), true); // Check request for 'value' attribute if (!isset($request['data'])) $api->stopAPI('Data required for data update', 400); // Check request for 'timestamp' attribute, take as is if numeric, @@ -57,7 +63,7 @@ ? $request['timestamp'] : strtotime($request['timestamp']) ) - : FALSE; + : false; if (!$timestamp) $api->stopAPI('Timestamp required for data update', 400); if (!Channel::byGUID($guid)->update($request, $timestamp)) { $api->stopAPI('Invalid data', 405); @@ -65,28 +71,35 @@ })->name('POST /data/:guid')->help = array( 'since' => 'r4', 'description' => 'Update a reading value, timestamp is required here', - 'apikey' => TRUE, + 'apikey' => true, 'payload' => array('{"data":"","timestamp":""}' => 'JSON encoded value'), ); /** * */ -$api->put('/data/raw/:guid', $APIkeyRequired, function($guid) use ($api) { +$api->put( + '/data/raw/:guid', + $APIkeyRequired, + function($guid) use ($api) +{ // Channel handles raw data $cnt = Channel::byGUID($guid)->write($api->request->getBody()); if ($cnt) $api->stopAPI($cnt.' reading(s) added', 201); })->name('PUT /data/raw/:guid')->help = array( 'since' => 'r4', 'description' => 'Save raw data, channel decide what to do with them', - 'apikey' => TRUE, + 'apikey' => true, 'payload' => array('raw data in any format' => 'Channel have to handle it'), ); /** * */ -$api->get('/data/:period/:guid', $accessibleChannel, function($period, $guid) use ($api) +$api->get( + '/data/:period/:guid', + $accessibleChannel, + function($period, $guid) use ($api) { $request = $api->request->get(); $request['period'] = $period; @@ -117,7 +130,10 @@ /** * */ -$api->get('/data/:guid(/:p1(/:p2))', $accessibleChannel, function($guid, $p1='', $p2='') use ($api) +$api->get( + '/data/:guid(/:p1(/:p2))', + $accessibleChannel, + function($guid, $p1='', $p2='') use ($api) { $request = $api->request->get(); $request['p1'] = $p1; @@ -182,7 +198,9 @@ /** * */ -$api->get('/data/actual/:guid+', function($guid) use ($api) +$api->get( + '/data/actual/:guid+', + function($guid) use ($api) { $guids = $guid; $request = $api->request->get(); @@ -230,7 +248,10 @@ /** * */ -$api->get('/data/stats', function() use ($api) { +$api->get( + '/data/stats', + function() use ($api) +{ $api->render($api->db->queryRowsArray( 'SELECT c.`guid`, c.`name`, c.`description`, c.`numeric`, c.`decimals`, t.*, IFNULL(n.`data`, s.`data`) AS `data` @@ -248,7 +269,11 @@ /** * */ -$api->delete('/data/:guid/:timestamp', $APIkeyRequired, function($guid, $timestamp) use ($api) { +$api->delete( + '/data/:guid/:timestamp', + $APIkeyRequired, + function($guid, $timestamp) use ($api) +{ $channel = Channel::byGUID($guid); $tbl = $channel->numeric ? new \ORM\ReadingNum : new \ORM\ReadingStr; if ($tbl->filterByIdTimestamp($channel->entity, $timestamp)->findOne()->getId()) { @@ -260,5 +285,34 @@ })->name('DELETE /data/:guid/:timestamp')->help = array( 'since' => 'r2', 'description' => 'Delete a reading value', - 'apikey' => TRUE, + 'apikey' => true, ); + +/** + * Undocumented + */ +$api->delete( + '/data', + $APIkeyRequired, + function() use ($api) +{ + if (!\ORM\Settings::getCoreValue(null, 'EmptyDatabaseAllowed')) { + $api->stopAPI('Delete all data is not allowed, ' + .'change the "Empty database allowed" flag first!'); + } + + $tables = array( + 'pvlng_reading_last', + 'pvlng_reading_num', 'pvlng_reading_str', + 'pvlng_reading_num_tmp', 'pvlng_reading_str_tmp', + 'pvlng_reading_num_calc', 'pvlng_reading_tmp' + ); + + foreach ($tables as $table) { + $api->db->truncate($table); + } + + \ORM\Settings::setCoreValue(null, 'EmptyDatabaseAllowed', 0); + + $api->stopAPI('All data deleted', 200); +}); diff --git a/core/ORM/Settings.php b/core/ORM/Settings.php index d62d4cc..4f88707 100644 --- a/core/ORM/Settings.php +++ b/core/ORM/Settings.php @@ -44,6 +44,14 @@ public static function getCoreValue($name, $key, $default=null) return self::getScopeValue('core', $name, $key, $default); } + /** + * + */ + public static function setCoreValue($name, $key, $value) + { + return self::setScopeValue('core', $name, $key, $value); + } + /** * */ @@ -104,4 +112,16 @@ protected static function getScopeValue($scope, $name, $key, $default=null) return $self->getKey() ? $self->getValue() : $default; } + /** + * + */ + protected static function setScopeValue($scope, $name, $key, $value) + { + $self = new self; + $self->filterByScopeNameKey($scope, $name, $key)->findOne(); + if ($self->getKey()) { + return $self->setValue($value)->update(); + } + } + } diff --git a/frontend/View/Settings/content.scope.tpl b/frontend/View/Settings/content.scope.tpl index 437802e..1ad7fb0 100644 --- a/frontend/View/Settings/content.scope.tpl +++ b/frontend/View/Settings/content.scope.tpl @@ -29,7 +29,7 @@
- Fill only to change it! +     Fill only to change it!
@@ -43,6 +43,10 @@ + + +     +
diff --git a/frontend/View/Settings/script.js.html b/frontend/View/Settings/script.js.html new file mode 100644 index 0000000..1c95586 --- /dev/null +++ b/frontend/View/Settings/script.js.html @@ -0,0 +1,66 @@ + diff --git a/frontend/View/Settings/style.css b/frontend/View/Settings/style.css index 9b476a5..7d18c79 100644 --- a/frontend/View/Settings/style.css +++ b/frontend/View/Settings/style.css @@ -21,3 +21,8 @@ margin-left: 1em; display: block; } + +#empty-database.confirm .ui-button-text { + color: red; + font-weight: bold; +} diff --git a/lib/slimMVC/MySQLi.php b/lib/slimMVC/MySQLi.php index a27f145..9ddadcb 100644 --- a/lib/slimMVC/MySQLi.php +++ b/lib/slimMVC/MySQLi.php @@ -277,6 +277,17 @@ public function queryCol( $query ) { return $rows; } + /** + * + */ + public function truncate( $table, $optimize=true ) { + $rc = $this->query('TRUNCATE `{1}`', $table); + if ($optimize) { + $rc += $this->query('OPTIMIZE `{1}`', $table); + } + return $rc; + } + /** * */ diff --git a/sql/patches/004.sql b/sql/patches/004.sql new file mode 100644 index 0000000..857a80c --- /dev/null +++ b/sql/patches/004.sql @@ -0,0 +1,11 @@ +INSERT INTO `pvlng_settings` +(`scope`, `name`, `key`, `value`, `order`, `description`, `type`, `data`) +VALUES +('core', '', 'EmptyDatabaseAllowed', '0', 100, 'Enable function for deletion of all measuring data from database.
Channels and channel hierarchy will not be deleted!
Only if this is allowed, the deletion is possible!', 'bool', ''); + +UPDATE `pvlng_type` SET `unit` = '', `icon` = '/images/ico/calculator_scientific.png' WHERE `id` = 15; + +INSERT INTO `pvlng_type` +(`id`, `name`, `description`, `model`, `unit`, `type`, `childs`, `read`, `write`, `graph`, `icon`) +VALUES +(33, 'Percentage calculator', 'model::Ratio', 'Ratio', '%', 'sensor', 2, 1, 0, 1, '/images/ico/edit_percent.png');