mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-10-15 22:39:56 +00:00
Hourly activity read raw rows only 3h back, so a longer rollup backlog left hours drawn as zero. The raw tail now starts at the newest complete rollup hour, capped at the 24h raw holdback, and the response reports rolledUntil and rawFrom so clients can show anything still uncovered.
181 lines
7.7 KiB
Go
181 lines
7.7 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: series.sql
|
|
|
|
package db
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const getEarliestCompleteRollupHour = `-- name: GetEarliestCompleteRollupHour :one
|
|
SELECT min(hour)::timestamptz FROM analytics_rollup_hours WHERE status = 'complete'
|
|
`
|
|
|
|
func (q *Queries) GetEarliestCompleteRollupHour(ctx context.Context) (pgtype.Timestamptz, error) {
|
|
row := q.db.QueryRow(ctx, getEarliestCompleteRollupHour)
|
|
var column_1 pgtype.Timestamptz
|
|
err := row.Scan(&column_1)
|
|
return column_1, err
|
|
}
|
|
|
|
const getLatestCompleteRollupHour = `-- name: GetLatestCompleteRollupHour :one
|
|
SELECT max(hour)::timestamptz FROM analytics_rollup_hours WHERE status = 'complete'
|
|
`
|
|
|
|
func (q *Queries) GetLatestCompleteRollupHour(ctx context.Context) (pgtype.Timestamptz, error) {
|
|
row := q.db.QueryRow(ctx, getLatestCompleteRollupHour)
|
|
var column_1 pgtype.Timestamptz
|
|
err := row.Scan(&column_1)
|
|
return column_1, err
|
|
}
|
|
|
|
const getStatsSeries = `-- name: GetStatsSeries :many
|
|
WITH hours AS (
|
|
SELECT g.h::timestamptz AS hour, COALESCE(r.status, 'missing')::text AS status
|
|
FROM generate_series($1::timestamptz, $2::timestamptz, INTERVAL '1 hour') g(h)
|
|
LEFT JOIN analytics_rollup_hours r ON r.hour = g.h
|
|
WHERE g.h < $2::timestamptz
|
|
), complete AS (
|
|
SELECT hour FROM hours WHERE status = 'complete'
|
|
), obs AS (
|
|
SELECT o.hour, o.iata, o.observation_count FROM analytics_hourly_iata_observations o JOIN complete c ON c.hour = o.hour
|
|
WHERE COALESCE(cardinality($3::bpchar[]), 0) = 0
|
|
UNION ALL
|
|
SELECT o.hour, o.iata, o.observation_count FROM analytics_hourly_iata_observations o JOIN complete c ON c.hour = o.hour
|
|
WHERE cardinality($3::bpchar[]) > 0 AND o.iata = ANY($3::bpchar[])
|
|
), obs_agg AS (
|
|
SELECT hour, sum(observation_count)::bigint AS observations, count(DISTINCT iata)::bigint AS active_iatas
|
|
FROM obs GROUP BY GROUPING SETS ((), (hour))
|
|
), pkt AS (
|
|
SELECT s.hour, s.packets FROM analytics_hourly_packet_sets s JOIN complete c ON c.hour = s.hour
|
|
WHERE COALESCE(cardinality($3::bpchar[]), 0) = 0
|
|
UNION ALL
|
|
SELECT s.hour, s.packets FROM analytics_hourly_packet_sets s JOIN complete c ON c.hour = s.hour
|
|
WHERE cardinality($3::bpchar[]) > 0 AND s.iatas && $3::bpchar[]
|
|
), pkt_agg AS (
|
|
SELECT hour, sum(packets)::bigint AS unique_packets FROM pkt GROUP BY GROUPING SETS ((), (hour))
|
|
), obsr AS (
|
|
SELECT i.hour, i.observer_id FROM analytics_hourly_observer_identity i JOIN complete c ON c.hour = i.hour
|
|
WHERE COALESCE(cardinality($3::bpchar[]), 0) = 0
|
|
UNION ALL
|
|
SELECT i.hour, i.observer_id FROM analytics_hourly_observer_identity i JOIN complete c ON c.hour = i.hour
|
|
WHERE cardinality($3::bpchar[]) > 0 AND i.iata = ANY($3::bpchar[])
|
|
), obsr_agg AS (
|
|
SELECT hour, count(DISTINCT observer_id)::bigint AS active_observers FROM obsr GROUP BY GROUPING SETS ((), (hour))
|
|
), scp AS (
|
|
SELECT s.hour, s.scope_id, s.packets FROM analytics_hourly_scope_sets s JOIN complete c ON c.hour = s.hour
|
|
WHERE COALESCE(cardinality($3::bpchar[]), 0) = 0
|
|
UNION ALL
|
|
SELECT s.hour, s.scope_id, s.packets FROM analytics_hourly_scope_sets s JOIN complete c ON c.hour = s.hour
|
|
WHERE cardinality($3::bpchar[]) > 0 AND s.iatas && $3::bpchar[]
|
|
), scp_agg AS (
|
|
SELECT hour, sum(packets)::bigint AS scoped_packets, count(DISTINCT scope_id)::bigint AS active_scopes
|
|
FROM scp GROUP BY GROUPING SETS ((), (hour))
|
|
), pth AS (
|
|
SELECT p.hour, p.entries FROM analytics_hourly_paths p JOIN complete c ON c.hour = p.hour
|
|
WHERE p.category = 0 AND COALESCE(cardinality($3::bpchar[]), 0) = 0
|
|
UNION ALL
|
|
SELECT p.hour, p.entries FROM analytics_hourly_paths p JOIN complete c ON c.hour = p.hour
|
|
WHERE p.category = 0 AND cardinality($3::bpchar[]) > 0 AND p.iata = ANY($3::bpchar[])
|
|
), pth_agg AS (
|
|
SELECT hour, max(entries)::integer AS max_path_entries FROM pth GROUP BY GROUPING SETS ((), (hour))
|
|
), sig AS (
|
|
SELECT s.hour, s.snr_sum, s.snr_samples, s.rssi_sum, s.rssi_samples FROM analytics_hourly_signal s JOIN complete c ON c.hour = s.hour
|
|
WHERE s.kind = 3 AND COALESCE(cardinality($3::bpchar[]), 0) = 0
|
|
UNION ALL
|
|
SELECT s.hour, s.snr_sum, s.snr_samples, s.rssi_sum, s.rssi_samples FROM analytics_hourly_signal s JOIN complete c ON c.hour = s.hour
|
|
WHERE s.kind = 3 AND cardinality($3::bpchar[]) > 0 AND s.iata = ANY($3::bpchar[])
|
|
), sig_agg AS (
|
|
SELECT hour, sum(snr_sum)::double precision AS snr_sum, sum(snr_samples)::bigint AS snr_samples,
|
|
sum(rssi_sum)::double precision AS rssi_sum, sum(rssi_samples)::bigint AS rssi_samples
|
|
FROM sig GROUP BY GROUPING SETS ((), (hour))
|
|
), keys AS (
|
|
SELECT hour, status FROM hours
|
|
UNION ALL
|
|
SELECT NULL::timestamptz, 'summary'::text
|
|
)
|
|
SELECT k.hour, k.status,
|
|
COALESCE(o.observations, 0)::bigint AS observations,
|
|
COALESCE(p.unique_packets, 0)::bigint AS unique_packets,
|
|
COALESCE(ob.active_observers, 0)::bigint AS active_observers,
|
|
COALESCE(o.active_iatas, 0)::bigint AS active_iatas,
|
|
COALESCE(s.scoped_packets, 0)::bigint AS scoped_packets,
|
|
COALESCE(s.active_scopes, 0)::bigint AS active_scopes,
|
|
COALESCE(pa.max_path_entries, 0)::integer AS max_path_entries,
|
|
COALESCE(sg.snr_sum, 0)::double precision AS snr_sum,
|
|
COALESCE(sg.snr_samples, 0)::bigint AS snr_samples,
|
|
COALESCE(sg.rssi_sum, 0)::double precision AS rssi_sum,
|
|
COALESCE(sg.rssi_samples, 0)::bigint AS rssi_samples
|
|
FROM keys k
|
|
LEFT JOIN obs_agg o ON o.hour IS NOT DISTINCT FROM k.hour
|
|
LEFT JOIN pkt_agg p ON p.hour IS NOT DISTINCT FROM k.hour
|
|
LEFT JOIN obsr_agg ob ON ob.hour IS NOT DISTINCT FROM k.hour
|
|
LEFT JOIN scp_agg s ON s.hour IS NOT DISTINCT FROM k.hour
|
|
LEFT JOIN pth_agg pa ON pa.hour IS NOT DISTINCT FROM k.hour
|
|
LEFT JOIN sig_agg sg ON sg.hour IS NOT DISTINCT FROM k.hour
|
|
ORDER BY k.hour NULLS LAST
|
|
`
|
|
|
|
type GetStatsSeriesParams struct {
|
|
Since pgtype.Timestamptz `json:"since"`
|
|
Until pgtype.Timestamptz `json:"until"`
|
|
Iatas []string `json:"iatas"`
|
|
}
|
|
|
|
type GetStatsSeriesRow struct {
|
|
Hour pgtype.Timestamptz `json:"hour"`
|
|
Status string `json:"status"`
|
|
Observations int64 `json:"observations"`
|
|
UniquePackets int64 `json:"unique_packets"`
|
|
ActiveObservers int64 `json:"active_observers"`
|
|
ActiveIatas int64 `json:"active_iatas"`
|
|
ScopedPackets int64 `json:"scoped_packets"`
|
|
ActiveScopes int64 `json:"active_scopes"`
|
|
MaxPathEntries int32 `json:"max_path_entries"`
|
|
SnrSum float64 `json:"snr_sum"`
|
|
SnrSamples int64 `json:"snr_samples"`
|
|
RssiSum float64 `json:"rssi_sum"`
|
|
RssiSamples int64 `json:"rssi_samples"`
|
|
}
|
|
|
|
// One row per hour in [since, until) plus a summary row (hour NULL) over its complete hours.
|
|
// Counts sum; observers, IATAs and scopes are distinct across the window; packets count
|
|
// once per hour heard. Each branch pair keeps "all IATAs" and "these IATAs" plans separate.
|
|
func (q *Queries) GetStatsSeries(ctx context.Context, arg GetStatsSeriesParams) ([]GetStatsSeriesRow, error) {
|
|
rows, err := q.db.Query(ctx, getStatsSeries, arg.Since, arg.Until, arg.Iatas)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []GetStatsSeriesRow{}
|
|
for rows.Next() {
|
|
var i GetStatsSeriesRow
|
|
if err := rows.Scan(
|
|
&i.Hour,
|
|
&i.Status,
|
|
&i.Observations,
|
|
&i.UniquePackets,
|
|
&i.ActiveObservers,
|
|
&i.ActiveIatas,
|
|
&i.ScopedPackets,
|
|
&i.ActiveScopes,
|
|
&i.MaxPathEntries,
|
|
&i.SnrSum,
|
|
&i.SnrSamples,
|
|
&i.RssiSum,
|
|
&i.RssiSamples,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|