feat(stats): add bounded path and hash-width analytics (#159)

This commit is contained in:
n30nex
2026-09-23 20:18:41 -04:00
committed by GitHub
parent 6107578c25
commit 8a3fa7e6bf
25 changed files with 1205 additions and 4 deletions
+83
View File
@@ -0,0 +1,83 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: paths.sql
package db
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const getPathStats = `-- name: GetPathStats :many
WITH readings AS (
SELECT iata, hour, category, hash_bytes, entries, receptions FROM mv_path_stats_hourly
WHERE hour >= $1::timestamptz AND hour < $2::timestamptz
AND COALESCE(cardinality($3::bpchar[]), 0) = 0
UNION ALL
SELECT iata, hour, category, hash_bytes, entries, receptions FROM mv_path_stats_hourly
WHERE hour >= $1::timestamptz AND hour < $2::timestamptz
AND cardinality($3::bpchar[]) > 0 AND iata = ANY($3::bpchar[])
)
SELECT (grouping(hour) = 0)::boolean AS is_hourly,
COALESCE(hour, 'epoch'::timestamptz)::timestamptz AS hour,
category, hash_bytes, COALESCE(entries, 0)::integer AS entries,
sum(receptions)::bigint AS receptions
FROM readings
GROUP BY GROUPING SETS ((category, hash_bytes, entries), (hour, category, hash_bytes))
ORDER BY is_hourly, hour, category, hash_bytes, entries
`
type GetPathStatsParams struct {
Since pgtype.Timestamptz `json:"since"`
Until pgtype.Timestamptz `json:"until"`
Iatas []string `json:"iatas"`
}
type GetPathStatsRow struct {
IsHourly bool `json:"is_hourly"`
Hour pgtype.Timestamptz `json:"hour"`
Category int32 `json:"category"`
HashBytes int32 `json:"hash_bytes"`
Entries int32 `json:"entries"`
Receptions int64 `json:"receptions"`
}
// All HTTP aggregates read the compact classification snapshot.
func (q *Queries) GetPathStats(ctx context.Context, arg GetPathStatsParams) ([]GetPathStatsRow, error) {
rows, err := q.db.Query(ctx, getPathStats, arg.Since, arg.Until, arg.Iatas)
if err != nil {
return nil, err
}
defer rows.Close()
items := []GetPathStatsRow{}
for rows.Next() {
var i GetPathStatsRow
if err := rows.Scan(
&i.IsHourly,
&i.Hour,
&i.Category,
&i.HashBytes,
&i.Entries,
&i.Receptions,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const refreshPathStats = `-- name: RefreshPathStats :exec
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_path_stats_hourly
`
func (q *Queries) RefreshPathStats(ctx context.Context) error {
_, err := q.db.Exec(ctx, refreshPathStats)
return err
}