view src/db.rs @ 34:9966460e2930

Encapsulate GeoJSON and parse_flexible_timestamp
author Lewin Bormann <lbo@spheniscida.de>
date Thu, 03 Dec 2020 07:51:38 +0100
parents 7559c75bb43c
children 097f1c1c5f2b
line wrap: on
line source

use crate::types;

/// Queries for at most `limit` rows since entry ID `last`.
pub fn check_for_new_rows(
    db: &postgres::Connection,
    name: &str,
    secret: Option<&str>,
    last: &Option<i32>,
    limit: &Option<i64>,
) -> Option<(types::GeoJSON, i32)> {
    let mut returnable = types::GeoJSON::new();
    let check_for_new = db.prepare_cached(
        r"SELECT id, t, lat, long, spd, ele FROM geohub.geodata
        WHERE (client = $1) and (id > $2) AND (secret = public.digest($3, 'sha256') or secret is null)
        ORDER BY id DESC
        LIMIT $4").unwrap(); // Must succeed.

    let last = last.unwrap_or(0);
    let limit = limit.unwrap_or(256);

    let rows = check_for_new.query(&[&name, &last, &secret, &limit]);
    if let Ok(rows) = rows {
        // If there are unknown entries, return those.
        if rows.len() > 0 {
            returnable.reserve_features(rows.len());
            let mut last = 0;

            for row in rows.iter() {
                let (id, ts, lat, long, spd, ele) = (
                    row.get(0),
                    row.get(1),
                    row.get(2),
                    row.get(3),
                    row.get(4),
                    row.get(5),
                );
                returnable.push_feature(types::geofeature_from_row(ts, lat, long, spd, ele));
                if id > last {
                    last = id;
                }
            }

            return Some((returnable, last));
        }
        return None;
    } else {
        // For debugging.
        rows.unwrap();
    }
    return None;
}