1
0

Optimise record taking, prepare for other record types.

This commit is contained in:
Markus Birth 2018-08-12 17:46:43 +02:00
parent e0d7a45e37
commit 6de9944236
Signed by: mbirth
GPG Key ID: A9928D7A098C3A9A
4 changed files with 142 additions and 59 deletions

View File

@ -2,6 +2,8 @@
namespace OwntracksRecorder\Database;
use \OwntracksRecorder\RecordType\AbstractRecordType;
class AbstractDatabase
{
protected $db;
@ -34,6 +36,26 @@ class AbstractDatabase
return (count($result) > 0);
}
public function addRecord(AbstractRecordType $obj)
{
$tablename = $obj->getTableName();
$fieldnames = array();
$placeholders = array();
$values = array();
foreach ($obj as $key => $value) {
if (is_null($value)) {
continue;
}
$fieldnames[] = $key;
$placeholders[] = '?';
$values[] = $value;
}
$sql = 'INSERT INTO ' . $this->prefix . $tablename . ' (' . implode(', ', $fieldnames) . ') VALUES (' . implode(', ', $placeholders) . ');';
$result = $this->execute($sql, $values);
return $result;
}
public function addLocation(
int $accuracy = null,
int $altitude = null,

View File

@ -0,0 +1,73 @@
<?php
namespace OwntracksRecorder\RecordType;
class AbstractRecordType implements \Iterator
{
protected $type;
protected $table;
protected $fields = array();
protected $data = array();
public function __construct()
{
// init empty record
foreach ($this->fields as $key => $extkey) {
$this->data[$key] = null;
}
}
public function __isset($key)
{
return !is_null($this->data[$key]);
}
public function __get($key)
{
return $this->data[$key];
}
public function rewind()
{
reset($this->data);
}
public function current()
{
return current($this->data);
}
public function key()
{
return key($this->data);
}
public function next()
{
return next($this->data);
}
public function valid()
{
return $this->current() !== false;
}
public function getTableName()
{
return $this->table;
}
public function fillFromArray($arr)
{
foreach ($this->fields as $key => $extinfo) {
if (is_null($extinfo)) {
continue;
}
if (array_key_exists($extinfo[0], $arr)) {
$val = $arr[$extinfo[0]];
settype($val, $extinfo[1]); // convert to needed type
$this->data[$key] = $val;
}
}
}
}

39
lib/RecordType/Location.php Executable file
View File

@ -0,0 +1,39 @@
<?php
namespace OwntracksRecorder\RecordType;
use \OwntracksRecorder\RecordType\AbstractRecordType;
class Location extends AbstractRecordType
{
protected $table = 'locations';
// https://owntracks.org/booklet/tech/json/
protected $type = 'location';
// Mapping of database fields => JSON field, type
protected $fields = array(
'lid' => null,
'dt' => null,
'accuracy' => array('acc', 'int'),
'altitude' => array('alt', 'int'),
'battery_level' => array('batt', 'int'),
'heading' => array('cog', 'int'),
'description' => array('desc', 'string'),
'event' => array('event', 'string'),
'latitude' => array('lat', 'float'),
'longitude' => array('lon', 'float'),
'radius' => array('rad', 'int'),
'trig' => array('t', 'string'),
'tracker_id' => array('tid', 'string'),
'epoch' => array('tst', 'int'),
'vertical_accuracy' => array('vac', 'int'),
'velocity' => array('vel', 'int'),
'pressure' => array('p', 'float'),
'connection' => array('conn', 'string'),
'topic' => array('topic', 'string'),
'place_id' => null,
'osm_id' => null,
'display_name' => null,
);
}

View File

@ -7,6 +7,7 @@ require_once 'vendor/autoload.php';
use \OwntracksRecorder\Database\MySql;
use \OwntracksRecorder\Database\SQLite;
use \OwntracksRecorder\RecordType\Location;
function _log($msg)
{
@ -30,65 +31,13 @@ header('Content-type: application/json');
$response_msg = null;
if ($data['_type'] == 'location' || in_array('debug', $_REQUEST)) {
$accuracy = null;
$altitude = null;
$battery_level = null;
$heading = null;
$description = null;
$event = null;
$latitude = null;
$longitude = null;
$radius = null;
$trig = null;
$tracker_id = null;
$epoch = null;
$vertical_accuracy = null;
$velocity = null;
$pressure = null;
$connection = null;
$topic = null;
//http://owntracks.org/booklet/tech/json/
if (array_key_exists('acc', $data)) $accuracy = intval($data['acc']);
if (array_key_exists('alt', $data)) $altitude = intval($data['alt']);
if (array_key_exists('batt', $data)) $battery_level = intval($data['batt']);
if (array_key_exists('cog', $data)) $heading = intval($data['cog']);
if (array_key_exists('desc', $data)) $description = strval($data['desc']);
if (array_key_exists('event', $data)) $event = strval($data['event']);
if (array_key_exists('lat', $data)) $latitude = floatval($data['lat']);
if (array_key_exists('lon', $data)) $longitude = floatval($data['lon']);
if (array_key_exists('rad', $data)) $radius = intval($data['rad']);
if (array_key_exists('t', $data)) $trig = strval($data['t']);
if (array_key_exists('tid', $data)) $tracker_id = strval($data['tid']);
if (array_key_exists('tst', $data)) $epoch = intval($data['tst']);
if (array_key_exists('vac', $data)) $vertical_accuracy = intval($data['vac']);
if (array_key_exists('vel', $data)) $velocity = intval($data['vel']);
if (array_key_exists('p', $data)) $pressure = floatval($data['p']);
if (array_key_exists('conn', $data)) $connection = strval($data['conn']);
if (array_key_exists('topic', $data)) $topic = strval($data['topic']);
$loc = new Location();
$loc->fillFromArray($data);
//record only if same data found at same epoch / tracker_id
if (!$sql->isEpochExisting($tracker_id, $epoch)) {
$result = $sql->addLocation(
$accuracy,
$altitude,
$battery_level,
$heading,
$description,
$event,
$latitude,
$longitude,
$radius,
$trig,
$tracker_id,
$epoch,
$vertical_accuracy,
$velocity,
$pressure,
$connection,
$topic
);
// record only if same data found at same epoch / tracker_id
if (!$sql->isEpochExisting($loc->tracker_id, $loc->epoch)) {
$result = $sql->addRecord($loc);
if ($result) {
http_response_code(200);
@ -96,10 +45,10 @@ if ($data['_type'] == 'location' || in_array('debug', $_REQUEST)) {
} else {
http_response_code(500);
$response_msg = 'Can\'t write to database';
_log('Insert KO - Can\'t write to database.');
_log('ERROR during Insert: Can\'t write to database.');
}
} else {
_log('Duplicate location found for epoc ' . $epoch . ' / tid ' . $tracker_id . ' - no insert');
_log('Duplicate location found for epoc ' . $loc->epoch . ' / tid ' . $loc->tracker_id . ' - no insert');
$response_msg = 'Duplicate location found for epoch. Ignoring.';
}
} else {