New tg ID schema and initial importer #35
7 changed files with 59 additions and 30 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
||||||
config.yaml
|
config.yaml
|
||||||
config.test.yaml
|
config.test.yaml
|
||||||
mydb.sql
|
/*.sql
|
||||||
client/calls/
|
client/calls/
|
||||||
!client/calls/.gitkeep
|
!client/calls/.gitkeep
|
||||||
/gordio
|
/gordio
|
||||||
|
|
|
@ -47,13 +47,13 @@ func (as *alerter) tgStatsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tgMap := make(map[talkgroups.ID]database.GetTalkgroupsWithLearnedByPackedIDsRow, len(tgs))
|
tgMap := make(map[talkgroups.ID]database.GetTalkgroupsRow, len(tgs))
|
||||||
for _, t := range tgs {
|
for _, t := range tgs {
|
||||||
tgMap[talkgroups.ID{System: uint32(t.System.ID), Talkgroup: uint32(t.Talkgroup.Tgid)}] = t
|
tgMap[talkgroups.ID{System: uint32(t.System.ID), Talkgroup: uint32(t.Talkgroup.Tgid)}] = t
|
||||||
}
|
}
|
||||||
|
|
||||||
renderData := struct {
|
renderData := struct {
|
||||||
TGs map[talkgroups.ID]database.GetTalkgroupsWithLearnedByPackedIDsRow
|
TGs map[talkgroups.ID]database.GetTalkgroupsRow
|
||||||
Scores trending.Scores[talkgroups.ID]
|
Scores trending.Scores[talkgroups.ID]
|
||||||
LastScore time.Time
|
LastScore time.Time
|
||||||
Simulation *Simulation
|
Simulation *Simulation
|
||||||
|
|
|
@ -11,6 +11,8 @@ import (
|
||||||
_ "github.com/golang-migrate/migrate/v4/database/pgx/v5"
|
_ "github.com/golang-migrate/migrate/v4/database/pgx/v5"
|
||||||
"github.com/golang-migrate/migrate/v4/source/iofs"
|
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
|
"github.com/jackc/pgx/v5/tracelog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DB is a database handle.
|
// DB is a database handle.
|
||||||
|
@ -19,6 +21,12 @@ type DB struct {
|
||||||
*Queries
|
*Queries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type myLogger struct{}
|
||||||
|
|
||||||
|
func (m myLogger) Log(ctx context.Context, level tracelog.LogLevel, msg string, data map[string]any) {
|
||||||
|
log.Debug().Fields(data).Msg(msg)
|
||||||
|
}
|
||||||
|
|
||||||
// NewClient creates a new DB using the provided config.
|
// NewClient creates a new DB using the provided config.
|
||||||
func NewClient(ctx context.Context, conf config.DB) (*DB, error) {
|
func NewClient(ctx context.Context, conf config.DB) (*DB, error) {
|
||||||
dir, err := iofs.New(sqlembed.Migrations, "postgres/migrations")
|
dir, err := iofs.New(sqlembed.Migrations, "postgres/migrations")
|
||||||
|
@ -43,6 +51,12 @@ func NewClient(ctx context.Context, conf config.DB) (*DB, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger := myLogger{}
|
||||||
|
tracer := &tracelog.TraceLog{
|
||||||
|
Logger: logger,
|
||||||
|
LogLevel: tracelog.LogLevelTrace,
|
||||||
|
}
|
||||||
|
pgConf.ConnConfig.Tracer = tracer
|
||||||
pool, err := pgxpool.NewWithConfig(ctx, pgConf)
|
pool, err := pgxpool.NewWithConfig(ctx, pgConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
func (d GetTalkgroupsWithLearnedByPackedIDsRow) GetTalkgroup() Talkgroup { return d.Talkgroup }
|
func (d GetTalkgroupsRow) GetTalkgroup() Talkgroup { return d.Talkgroup }
|
||||||
func (d GetTalkgroupsWithLearnedByPackedIDsRow) GetSystem() System { return d.System }
|
func (d GetTalkgroupsRow) GetSystem() System { return d.System }
|
||||||
func (d GetTalkgroupsWithLearnedByPackedIDsRow) GetLearned() bool { return d.Learned }
|
func (d GetTalkgroupsRow) GetLearned() bool { return d.Learned }
|
||||||
func (g GetTalkgroupsWithLearnedRow) GetTalkgroup() Talkgroup { return g.Talkgroup }
|
func (g GetTalkgroupsWithLearnedRow) GetTalkgroup() Talkgroup { return g.Talkgroup }
|
||||||
func (g GetTalkgroupsWithLearnedRow) GetSystem() System { return g.System }
|
func (g GetTalkgroupsWithLearnedRow) GetSystem() System { return g.System }
|
||||||
func (g GetTalkgroupsWithLearnedRow) GetLearned() bool { return g.Learned }
|
func (g GetTalkgroupsWithLearnedRow) GetLearned() bool { return g.Learned }
|
||||||
|
|
|
@ -3,24 +3,45 @@ package database
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TalkgroupT struct {
|
type TalkgroupT struct {
|
||||||
System uint32 `json:"sys"`
|
System uint32 `json:"system_id"`
|
||||||
Talkgroup uint32 `json:"tg"`
|
Talkgroup uint32 `json:"tgid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TalkgroupTs []TalkgroupT
|
||||||
|
|
||||||
|
func (t TalkgroupTs) Nest() (sys []uint32, tg []uint32) {
|
||||||
|
sys = make([]uint32, len(t))
|
||||||
|
tg = make([]uint32, len(t))
|
||||||
|
|
||||||
|
for i := range t {
|
||||||
|
sys[i] = t[i].System
|
||||||
|
tg[i] = t[i].Talkgroup
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TalkgroupT) Value() (driver.Value, error) {
|
func (t TalkgroupT) Value() (driver.Value, error) {
|
||||||
return [2]uint32{t.System, t.Talkgroup}, nil
|
return [2]uint32{t.System, t.Talkgroup}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t TalkgroupT) TextValue() (pgtype.Text, error) {
|
||||||
|
return pgtype.Text{String: fmt.Sprintf("%d:%d", t.System, t.Talkgroup)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
const getTalkgroupsWithLearnedByPackedIDs = `-- name: GetTalkgroupsWithLearnedByPackedIDs :many
|
const getTalkgroupsWithLearnedByPackedIDs = `-- name: GetTalkgroupsWithLearnedByPackedIDs :many
|
||||||
SELECT
|
SELECT
|
||||||
tg.id, tg.system_id, tg.tgid, tg.name, tg.alpha_tag, tg.tg_group, tg.frequency, tg.metadata, tg.tags, tg.alert, tg.alert_config, tg.weight, sys.id, sys.name,
|
tg.id, tg.system_id, tg.tgid, tg.name, tg.alpha_tag, tg.tg_group, tg.frequency, tg.metadata, tg.tags, tg.alert, tg.alert_config, tg.weight, sys.id, sys.name,
|
||||||
FALSE learned
|
FALSE learned
|
||||||
FROM talkgroups tg
|
FROM talkgroups tg
|
||||||
JOIN systems sys ON tg.system_id = sys.id
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
WHERE (tg.system_id, tg.tgid) = ANY($1)
|
JOIN UNNEST($1::INT4[], $2::INT4[]) AS tgt(sys, tg) ON (tg.system_id = tgt.sys AND tg.tgid = tgt.tg)
|
||||||
UNION
|
UNION
|
||||||
SELECT
|
SELECT
|
||||||
NULL::UUID, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
NULL::UUID, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
@ -30,24 +51,24 @@ TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
TRUE learned
|
TRUE learned
|
||||||
FROM talkgroups_learned tgl
|
FROM talkgroups_learned tgl
|
||||||
JOIN systems sys ON tgl.system_id = sys.id
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
WHERE (tgl.system_id, tgl.tgid) = ANY($1);
|
JOIN UNNEST($1::INT4[], $2::INT4[]) AS tgt(sys, tg) ON (tgl.system_id = tgt.sys AND tgl.tgid = tgt.tg);`
|
||||||
`
|
|
||||||
|
|
||||||
type GetTalkgroupsWithLearnedByPackedIDsRow struct {
|
type GetTalkgroupsRow struct {
|
||||||
Talkgroup Talkgroup `json:"talkgroup"`
|
Talkgroup Talkgroup `json:"talkgroup"`
|
||||||
System System `json:"system"`
|
System System `json:"system"`
|
||||||
Learned bool `json:"learned"`
|
Learned bool `json:"learned"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) GetTalkgroupsWithLearnedByPackedIDs(ctx context.Context, ids []TalkgroupT) ([]GetTalkgroupsWithLearnedByPackedIDsRow, error) {
|
func (q *Queries) GetTalkgroupsWithLearnedByPackedIDs(ctx context.Context, ids TalkgroupTs) ([]GetTalkgroupsRow, error) {
|
||||||
rows, err := q.db.Query(ctx, getTalkgroupsWithLearnedByPackedIDs, ids)
|
sysAr, tgAr := ids.Nest()
|
||||||
|
rows, err := q.db.Query(ctx, getTalkgroupsWithLearnedByPackedIDs, sysAr, tgAr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []GetTalkgroupsWithLearnedByPackedIDsRow
|
var items []GetTalkgroupsRow
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i GetTalkgroupsWithLearnedByPackedIDsRow
|
var i GetTalkgroupsRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.Talkgroup.ID,
|
&i.Talkgroup.ID,
|
||||||
&i.Talkgroup.SystemID,
|
&i.Talkgroup.SystemID,
|
||||||
|
@ -78,23 +99,19 @@ func (q *Queries) GetTalkgroupsWithLearnedByPackedIDs(ctx context.Context, ids [
|
||||||
const getTalkgroupsByPackedIDs = `-- name: GetTalkgroupsByPackedIDs :many
|
const getTalkgroupsByPackedIDs = `-- name: GetTalkgroupsByPackedIDs :many
|
||||||
SELECT tg.id, tg.system_id, tg.tgid, tg.name, tg.alpha_tag, tg.tg_group, tg.frequency, tg.metadata, tg.tags, tg.alert, tg.alert_config, tg.weight, sys.id, sys.name FROM talkgroups tg
|
SELECT tg.id, tg.system_id, tg.tgid, tg.name, tg.alpha_tag, tg.tg_group, tg.frequency, tg.metadata, tg.tags, tg.alert, tg.alert_config, tg.weight, sys.id, sys.name FROM talkgroups tg
|
||||||
JOIN systems sys ON tg.system_id = sys.id
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
WHERE (tg.system_id, tg.tgid) = ANY($1)
|
JOIN UNNEST($1::INT4[], $2::INT4[]) AS tgt(sys, tg) ON (tg.system_id = tgt.sys AND tg.tgid = tgt.tg)
|
||||||
`
|
`
|
||||||
|
|
||||||
type GetTalkgroupsByPackedIDsRow struct {
|
func (q *Queries) GetTalkgroupsByPackedIDs(ctx context.Context, ids TalkgroupTs) ([]GetTalkgroupsRow, error) {
|
||||||
Talkgroup Talkgroup `json:"talkgroup"`
|
sysAr, tgAr := ids.Nest()
|
||||||
System System `json:"system"`
|
rows, err := q.db.Query(ctx, getTalkgroupsByPackedIDs, sysAr, tgAr)
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetTalkgroupsByPackedIDs(ctx context.Context, idtuple []TalkgroupT) ([]GetTalkgroupsByPackedIDsRow, error) {
|
|
||||||
rows, err := q.db.Query(ctx, getTalkgroupsByPackedIDs, idtuple)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
var items []GetTalkgroupsByPackedIDsRow
|
var items []GetTalkgroupsRow
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var i GetTalkgroupsByPackedIDsRow
|
var i GetTalkgroupsRow
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&i.Talkgroup.ID,
|
&i.Talkgroup.ID,
|
||||||
&i.Talkgroup.SystemID,
|
&i.Talkgroup.SystemID,
|
||||||
|
@ -120,5 +137,3 @@ func (q *Queries) GetTalkgroupsByPackedIDs(ctx context.Context, idtuple []Talkgr
|
||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ func (t *cache) add(rec *Talkgroup) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type row interface {
|
type row interface {
|
||||||
database.GetTalkgroupsWithLearnedByPackedIDsRow | database.GetTalkgroupsWithLearnedRow |
|
database.GetTalkgroupsRow | database.GetTalkgroupsWithLearnedRow |
|
||||||
database.GetTalkgroupsWithLearnedBySystemRow
|
database.GetTalkgroupsWithLearnedBySystemRow
|
||||||
GetTalkgroup() database.Talkgroup
|
GetTalkgroup() database.Talkgroup
|
||||||
GetSystem() database.System
|
GetSystem() database.System
|
||||||
|
|
|
@ -48,7 +48,7 @@ func TG[T intId, U intId](sys T, tgid U) ID {
|
||||||
|
|
||||||
func (t ID) Tuple() database.TalkgroupT {
|
func (t ID) Tuple() database.TalkgroupT {
|
||||||
return database.TalkgroupT{
|
return database.TalkgroupT{
|
||||||
System: t.System,
|
System: t.System,
|
||||||
Talkgroup: t.Talkgroup,
|
Talkgroup: t.Talkgroup,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue