Browse Source

Drastically optimise the queries behind fetch-data and device-data.

pull/46/head
Starbeamrainbowlabs 2 years ago
parent
commit
913786ec0b
Signed by: sbrl GPG Key ID: 1BE5172E637709C2
  1. 4
      Changelog.md
  2. 6
      lib/SBRL/Generators.php
  3. 11
      logic/ApiResponseSender.php
  4. 21
      logic/Constants.php
  5. 4
      logic/Database.php
  6. 9
      logic/Repositories/MariaDBMeasurementDataRepository.php
  7. 2
      version

4
Changelog.md

@ -5,6 +5,10 @@ This is the changelog for the air quality web interface and its associated HTTP
- `[Code]` refers to internal changes to the code that have no direct impact on the web interface or the HTTP API, but are significant enough to warrant note.
- `[Docs]` refers to changes to the [documentation](https://aq.connectedhumber.org/__nightdocs/00-Welcome.html).
## v0.11.1 - 22nd June 2019
- Drastically improve the performance of the backend SQL queries that power the heatmap and device graphs by over 35x!
- For users of the HTTP API, said queries are `fetch-data` and `device-data`.
## v0.11 - 21st June 2019
- [API] Add new [`list-devices-near`](https://aq.connectedhumber.org/__nightdocs/05-API-Docs.html#list-devices-near) action.
- [API] Clarified that clients MUST ignore properties returned by the API that they do not understand.

6
lib/SBRL/Generators.php

@ -4,6 +4,12 @@ namespace SBRL;
class Generators {
/**
* Generates a cryptographically secure random id, as a hex value.
* FUTURE: Improve this to return a safe base64 to reduce length.
* @param int $length The desired length of id.
* @return string The generated id.
*/
public static function crypto_secure_id(int $length = 64) { // 64 = 32
$length = ($length < 4) ? 4 : $length;
return bin2hex(random_bytes(($length-($length%2))/2));

11
logic/ApiResponseSender.php

@ -7,11 +7,20 @@ namespace AirQuality;
*/
class ApiResponseSender
{
/**
* Creates a new ApiResponseSender.
*/
function __construct() {
}
/**
* Sends a plain-text error message.
* @param int $code The HTTP status code to send.
* @param string $message The plain-text message to send.
* @param array $extra_headers Any extra headers to return, in the format [["header", "value"], ["header", "value"], .....]
* @return void
*/
public function send_error_plain($code, $message, $extra_headers = []) {
http_response_code($code);
header("content-type: text/plain");

21
logic/Constants.php

@ -0,0 +1,21 @@
<?php
namespace AirQuality;
/**
* Holds various constant value.
*/
class Constants
{
/**
* The DateTime->format() string for passing DateTimes to MariaDB.
* Note that if you don't use thsi format and use the ISO standard instead, it will silently complain at you, taking absolutely _ages_ over doing so.
* @var string
*/
const DATETIME_FORMAT_SQL = "Y-m-d H:i:s";
/**
* You should never instantiate an instance of this class!
*/
private function __construct() { }
}

4
logic/Database.php

@ -56,8 +56,10 @@ class Database
// Replace tabs with spaces for debugging purposes
$sql = str_replace("\t", " ", $sql);
if($this->settings->get("env.mode") == "development")
if($this->settings->get("env.mode") == "development") {
// error_log("[Database/SQL]" . var_export($variables, true));
error_log("[Database/SQL] $sql");
}
// FUTURE: Optionally cache prepared statements?
$statement = $this->connection->prepare($sql);

9
logic/Repositories/MariaDBMeasurementDataRepository.php

@ -2,6 +2,7 @@
namespace AirQuality\Repositories;
use \AirQuality\Constants;
use \AirQuality\Database;
use \SBRL\TomlConfig;
@ -97,8 +98,8 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
", [
"reading_type" => $type_id,
// The database likes strings, not PHP DateTime() instances
"start_datetime" => $start_datetime->format(\DateTime::ISO8601),
"end_datetime" => $end_datetime->format(\DateTime::ISO8601),
"start_datetime" => $start_datetime->format(Constants::DATETIME_FORMAT_SQL),
"end_datetime" => $end_datetime->format(Constants::DATETIME_FORMAT_SQL),
]
)->fetchAll();
}
@ -138,8 +139,8 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
GROUP BY CEIL(UNIX_TIMESTAMP({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) / :average_seconds);", [
"device_id" => $device_id,
"reading_type" => $type_id,
"start_datetime" => $start->format(\DateTime::ISO8601),
"end_datetime" => $end->format(\DateTime::ISO8601),
"start_datetime" => $start->format(Constants::DATETIME_FORMAT_SQL),
"end_datetime" => $end->format(Constants::DATETIME_FORMAT_SQL),
"average_seconds" => $average_seconds
]
)->fetchAll();

2
version

@ -1 +1 @@
v0.11
v0.11.1

Loading…
Cancel
Save