API begin
This commit is contained in:
parent
58c1376146
commit
08f1bd4ff0
11 changed files with 351 additions and 102 deletions
|
@ -31,7 +31,7 @@ func newItem[K comparable](id K, options *options[K]) *item[K] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *item[K]) score(id K) Score[K] {
|
func (i *item[K]) score() Score[K] {
|
||||||
recentCount, count := i.computeCounts()
|
recentCount, count := i.computeCounts()
|
||||||
if recentCount < i.options.countThreshold {
|
if recentCount < i.options.countThreshold {
|
||||||
return Score[K]{}
|
return Score[K]{}
|
||||||
|
|
|
@ -192,7 +192,7 @@ func (s *Scorer[K]) addToItem(item *item[K], tm time.Time) {
|
||||||
func (s *Scorer[K]) Score() Scores[K] {
|
func (s *Scorer[K]) Score() Scores[K] {
|
||||||
var scores Scores[K]
|
var scores Scores[K]
|
||||||
for id, item := range s.items {
|
for id, item := range s.items {
|
||||||
score := item.score(id)
|
score := item.score()
|
||||||
score.ID = id
|
score.ID = id
|
||||||
scores = append(scores, score)
|
scores = append(scores, score)
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,20 +69,20 @@ func (as *alerter) tgStatsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
db := database.FromCtx(ctx)
|
db := database.FromCtx(ctx)
|
||||||
|
|
||||||
tgs, err := db.GetTalkgroupsByPackedIDs(ctx, as.packedScoredTGs())
|
tgs, err := db.GetTalkgroupsWithLearnedByPackedIDs(ctx, as.packedScoredTGs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("stats TG get failed")
|
log.Error().Err(err).Msg("stats TG get failed")
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tgMap := make(map[talkgroups.ID]database.GetTalkgroupsByPackedIDsRow, len(tgs))
|
tgMap := make(map[talkgroups.ID]database.GetTalkgroupsWithLearnedByPackedIDsRow, len(tgs))
|
||||||
for _, t := range tgs {
|
for _, t := range tgs {
|
||||||
tgMap[talkgroups.ID{System: uint32(t.System.ID), Talkgroup: uint32(t.Talkgroup.ID)}] = t
|
tgMap[talkgroups.ID{System: uint32(t.System.ID), Talkgroup: uint32(t.Talkgroup.Tgid)}] = t
|
||||||
}
|
}
|
||||||
|
|
||||||
renderData := struct {
|
renderData := struct {
|
||||||
TGs map[talkgroups.ID]database.GetTalkgroupsByPackedIDsRow
|
TGs map[talkgroups.ID]database.GetTalkgroupsWithLearnedByPackedIDsRow
|
||||||
Scores trending.Scores[talkgroups.ID]
|
Scores trending.Scores[talkgroups.ID]
|
||||||
LastScore time.Time
|
LastScore time.Time
|
||||||
Simulation *Simulation
|
Simulation *Simulation
|
||||||
|
|
|
@ -58,13 +58,14 @@ func httpCode(err error) int {
|
||||||
return http.StatusInternalServerError
|
return http.StatusInternalServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *api) writeJSON(w http.ResponseWriter, r *http.Request, data interface{}, err error) {
|
func (a *api) writeResponse(w http.ResponseWriter, r *http.Request, data interface{}, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Str("path", r.URL.Path).Err(err).Msg("request failed")
|
log.Error().Str("path", r.URL.Path).Err(err).Msg("request failed")
|
||||||
http.Error(w, err.Error(), httpCode(err))
|
http.Error(w, err.Error(), httpCode(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
err = enc.Encode(data)
|
err = enc.Encode(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -83,9 +84,9 @@ func decodeParams(d interface{}, r *http.Request) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
Metadata: nil,
|
Metadata: nil,
|
||||||
Result: d,
|
Result: d,
|
||||||
TagName: "param",
|
TagName: "param",
|
||||||
WeaklyTypedInput: true,
|
WeaklyTypedInput: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,6 +101,7 @@ func (a *api) badReq(w http.ResponseWriter, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *api) talkgroup(w http.ResponseWriter, r *http.Request) {
|
func (a *api) talkgroup(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
p := struct {
|
p := struct {
|
||||||
System *int `param:"system"`
|
System *int `param:"system"`
|
||||||
ID *int `param:"id"`
|
ID *int `param:"id"`
|
||||||
|
@ -114,9 +116,12 @@ func (a *api) talkgroup(w http.ResponseWriter, r *http.Request) {
|
||||||
var res interface{}
|
var res interface{}
|
||||||
switch {
|
switch {
|
||||||
case p.System != nil && p.ID != nil:
|
case p.System != nil && p.ID != nil:
|
||||||
res, err = a.tgs.TG(r.Context(), talkgroups.TG(*p.System, *p.ID))
|
res, err = a.tgs.TG(ctx, talkgroups.TG(*p.System, *p.ID))
|
||||||
case p.System != nil:
|
case p.System != nil:
|
||||||
|
res, err = a.tgs.SystemTGs(ctx, int32(*p.System))
|
||||||
default:
|
default:
|
||||||
|
res, err = a.tgs.TGs(ctx, nil)
|
||||||
}
|
}
|
||||||
a.writeJSON(w, r, res, err)
|
|
||||||
|
a.writeResponse(w, r, res, err)
|
||||||
}
|
}
|
||||||
|
|
11
pkg/database/extend.go
Normal file
11
pkg/database/extend.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package database
|
||||||
|
|
||||||
|
func (d GetTalkgroupsWithLearnedByPackedIDsRow) GetTalkgroup() Talkgroup { return d.Talkgroup }
|
||||||
|
func (d GetTalkgroupsWithLearnedByPackedIDsRow) GetSystem() System { return d.System }
|
||||||
|
func (d GetTalkgroupsWithLearnedByPackedIDsRow) GetLearned() bool { return d.Learned }
|
||||||
|
func (g GetTalkgroupsWithLearnedRow) GetTalkgroup() Talkgroup { return g.Talkgroup }
|
||||||
|
func (g GetTalkgroupsWithLearnedRow) GetSystem() System { return g.System }
|
||||||
|
func (g GetTalkgroupsWithLearnedRow) GetLearned() bool { return g.Learned }
|
||||||
|
func (g GetTalkgroupsWithLearnedBySystemRow) GetTalkgroup() Talkgroup { return g.Talkgroup }
|
||||||
|
func (g GetTalkgroupsWithLearnedBySystemRow) GetSystem() System { return g.System }
|
||||||
|
func (g GetTalkgroupsWithLearnedBySystemRow) GetLearned() bool { return g.Learned }
|
|
@ -26,10 +26,12 @@ type Querier interface {
|
||||||
GetTalkgroupIDsByTags(ctx context.Context, anytags []string, alltags []string, nottags []string) ([]GetTalkgroupIDsByTagsRow, error)
|
GetTalkgroupIDsByTags(ctx context.Context, anytags []string, alltags []string, nottags []string) ([]GetTalkgroupIDsByTagsRow, error)
|
||||||
GetTalkgroupTags(ctx context.Context, sys int, tg int) ([]string, error)
|
GetTalkgroupTags(ctx context.Context, sys int, tg int) ([]string, error)
|
||||||
GetTalkgroupWithLearned(ctx context.Context, systemID int, tgid int) (GetTalkgroupWithLearnedRow, error)
|
GetTalkgroupWithLearned(ctx context.Context, systemID int, tgid int) (GetTalkgroupWithLearnedRow, error)
|
||||||
GetTalkgroupWithLearnedByPackedIDs(ctx context.Context, dollar_1 []int64) ([]GetTalkgroupWithLearnedByPackedIDsRow, error)
|
|
||||||
GetTalkgroupsByPackedIDs(ctx context.Context, dollar_1 []int64) ([]GetTalkgroupsByPackedIDsRow, error)
|
GetTalkgroupsByPackedIDs(ctx context.Context, dollar_1 []int64) ([]GetTalkgroupsByPackedIDsRow, error)
|
||||||
GetTalkgroupsWithAllTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAllTagsRow, error)
|
GetTalkgroupsWithAllTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAllTagsRow, error)
|
||||||
GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAnyTagsRow, error)
|
GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAnyTagsRow, error)
|
||||||
|
GetTalkgroupsWithLearned(ctx context.Context) ([]GetTalkgroupsWithLearnedRow, error)
|
||||||
|
GetTalkgroupsWithLearnedByPackedIDs(ctx context.Context, dollar_1 []int64) ([]GetTalkgroupsWithLearnedByPackedIDsRow, error)
|
||||||
|
GetTalkgroupsWithLearnedBySystem(ctx context.Context, system int32) ([]GetTalkgroupsWithLearnedBySystemRow, error)
|
||||||
GetUserByID(ctx context.Context, id int32) (User, error)
|
GetUserByID(ctx context.Context, id int32) (User, error)
|
||||||
GetUserByUID(ctx context.Context, id int32) (User, error)
|
GetUserByUID(ctx context.Context, id int32) (User, error)
|
||||||
GetUserByUsername(ctx context.Context, username string) (User, error)
|
GetUserByUsername(ctx context.Context, username string) (User, error)
|
||||||
|
|
|
@ -151,67 +151,6 @@ func (q *Queries) GetTalkgroupWithLearned(ctx context.Context, systemID int, tgi
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTalkgroupWithLearnedByPackedIDs = `-- name: GetTalkgroupWithLearnedByPackedIDs :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,
|
|
||||||
FALSE learned
|
|
||||||
FROM talkgroups tg
|
|
||||||
JOIN systems sys ON tg.system_id = sys.id
|
|
||||||
WHERE tg.id = ANY($1::INT8[])
|
|
||||||
UNION
|
|
||||||
SELECT
|
|
||||||
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
|
||||||
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
|
||||||
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
|
||||||
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
|
||||||
TRUE learned
|
|
||||||
FROM talkgroups_learned tgl
|
|
||||||
JOIN systems sys ON tgl.system_id = sys.id
|
|
||||||
WHERE systg2id(tgl.system_id, tgl.tgid) = ANY($1::INT8[]) AND ignored IS NOT TRUE
|
|
||||||
`
|
|
||||||
|
|
||||||
type GetTalkgroupWithLearnedByPackedIDsRow struct {
|
|
||||||
Talkgroup Talkgroup `json:"talkgroup"`
|
|
||||||
System System `json:"system"`
|
|
||||||
Learned bool `json:"learned"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetTalkgroupWithLearnedByPackedIDs(ctx context.Context, dollar_1 []int64) ([]GetTalkgroupWithLearnedByPackedIDsRow, error) {
|
|
||||||
rows, err := q.db.Query(ctx, getTalkgroupWithLearnedByPackedIDs, dollar_1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
var items []GetTalkgroupWithLearnedByPackedIDsRow
|
|
||||||
for rows.Next() {
|
|
||||||
var i GetTalkgroupWithLearnedByPackedIDsRow
|
|
||||||
if err := rows.Scan(
|
|
||||||
&i.Talkgroup.ID,
|
|
||||||
&i.Talkgroup.SystemID,
|
|
||||||
&i.Talkgroup.Tgid,
|
|
||||||
&i.Talkgroup.Name,
|
|
||||||
&i.Talkgroup.AlphaTag,
|
|
||||||
&i.Talkgroup.TgGroup,
|
|
||||||
&i.Talkgroup.Frequency,
|
|
||||||
&i.Talkgroup.Metadata,
|
|
||||||
&i.Talkgroup.Tags,
|
|
||||||
&i.Talkgroup.Alert,
|
|
||||||
&i.Talkgroup.AlertConfig,
|
|
||||||
&i.Talkgroup.Weight,
|
|
||||||
&i.System.ID,
|
|
||||||
&i.System.Name,
|
|
||||||
&i.Learned,
|
|
||||||
); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
items = append(items, i)
|
|
||||||
}
|
|
||||||
if err := rows.Err(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return items, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -342,6 +281,188 @@ func (q *Queries) GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) (
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getTalkgroupsWithLearned = `-- name: GetTalkgroupsWithLearned :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,
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE ignored IS NOT TRUE
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetTalkgroupsWithLearnedRow struct {
|
||||||
|
Talkgroup Talkgroup `json:"talkgroup"`
|
||||||
|
System System `json:"system"`
|
||||||
|
Learned bool `json:"learned"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetTalkgroupsWithLearned(ctx context.Context) ([]GetTalkgroupsWithLearnedRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, getTalkgroupsWithLearned)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetTalkgroupsWithLearnedRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetTalkgroupsWithLearnedRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.Talkgroup.ID,
|
||||||
|
&i.Talkgroup.SystemID,
|
||||||
|
&i.Talkgroup.Tgid,
|
||||||
|
&i.Talkgroup.Name,
|
||||||
|
&i.Talkgroup.AlphaTag,
|
||||||
|
&i.Talkgroup.TgGroup,
|
||||||
|
&i.Talkgroup.Frequency,
|
||||||
|
&i.Talkgroup.Metadata,
|
||||||
|
&i.Talkgroup.Tags,
|
||||||
|
&i.Talkgroup.Alert,
|
||||||
|
&i.Talkgroup.AlertConfig,
|
||||||
|
&i.Talkgroup.Weight,
|
||||||
|
&i.System.ID,
|
||||||
|
&i.System.Name,
|
||||||
|
&i.Learned,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTalkgroupsWithLearnedByPackedIDs = `-- name: GetTalkgroupsWithLearnedByPackedIDs :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,
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
WHERE tg.id = ANY($1::INT8[])
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE systg2id(tgl.system_id, tgl.tgid) = ANY($1::INT8[]) AND ignored IS NOT TRUE
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetTalkgroupsWithLearnedByPackedIDsRow struct {
|
||||||
|
Talkgroup Talkgroup `json:"talkgroup"`
|
||||||
|
System System `json:"system"`
|
||||||
|
Learned bool `json:"learned"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetTalkgroupsWithLearnedByPackedIDs(ctx context.Context, dollar_1 []int64) ([]GetTalkgroupsWithLearnedByPackedIDsRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, getTalkgroupsWithLearnedByPackedIDs, dollar_1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetTalkgroupsWithLearnedByPackedIDsRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetTalkgroupsWithLearnedByPackedIDsRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.Talkgroup.ID,
|
||||||
|
&i.Talkgroup.SystemID,
|
||||||
|
&i.Talkgroup.Tgid,
|
||||||
|
&i.Talkgroup.Name,
|
||||||
|
&i.Talkgroup.AlphaTag,
|
||||||
|
&i.Talkgroup.TgGroup,
|
||||||
|
&i.Talkgroup.Frequency,
|
||||||
|
&i.Talkgroup.Metadata,
|
||||||
|
&i.Talkgroup.Tags,
|
||||||
|
&i.Talkgroup.Alert,
|
||||||
|
&i.Talkgroup.AlertConfig,
|
||||||
|
&i.Talkgroup.Weight,
|
||||||
|
&i.System.ID,
|
||||||
|
&i.System.Name,
|
||||||
|
&i.Learned,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTalkgroupsWithLearnedBySystem = `-- name: GetTalkgroupsWithLearnedBySystem :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,
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
WHERE tg.system_id = $1
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE tgl.system_id = $1 AND ignored IS NOT TRUE
|
||||||
|
`
|
||||||
|
|
||||||
|
type GetTalkgroupsWithLearnedBySystemRow struct {
|
||||||
|
Talkgroup Talkgroup `json:"talkgroup"`
|
||||||
|
System System `json:"system"`
|
||||||
|
Learned bool `json:"learned"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) GetTalkgroupsWithLearnedBySystem(ctx context.Context, system int32) ([]GetTalkgroupsWithLearnedBySystemRow, error) {
|
||||||
|
rows, err := q.db.Query(ctx, getTalkgroupsWithLearnedBySystem, system)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []GetTalkgroupsWithLearnedBySystemRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i GetTalkgroupsWithLearnedBySystemRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.Talkgroup.ID,
|
||||||
|
&i.Talkgroup.SystemID,
|
||||||
|
&i.Talkgroup.Tgid,
|
||||||
|
&i.Talkgroup.Name,
|
||||||
|
&i.Talkgroup.AlphaTag,
|
||||||
|
&i.Talkgroup.TgGroup,
|
||||||
|
&i.Talkgroup.Frequency,
|
||||||
|
&i.Talkgroup.Metadata,
|
||||||
|
&i.Talkgroup.Tags,
|
||||||
|
&i.Talkgroup.Alert,
|
||||||
|
&i.Talkgroup.AlertConfig,
|
||||||
|
&i.Talkgroup.Weight,
|
||||||
|
&i.System.ID,
|
||||||
|
&i.System.Name,
|
||||||
|
&i.Learned,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
const setTalkgroupTags = `-- name: SetTalkgroupTags :exec
|
const setTalkgroupTags = `-- name: SetTalkgroupTags :exec
|
||||||
UPDATE talkgroups SET tags = $3
|
UPDATE talkgroups SET tags = $3
|
||||||
WHERE id = systg2id($1, $2)
|
WHERE id = systg2id($1, $2)
|
||||||
|
|
|
@ -43,7 +43,46 @@ JOIN systems sys ON tgl.system_id = sys.id
|
||||||
WHERE tgl.system_id = $1 AND tgl.tgid = $2 AND ignored IS NOT TRUE
|
WHERE tgl.system_id = $1 AND tgl.tgid = $2 AND ignored IS NOT TRUE
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const getTalkgroupsWithLearnedBySystemTest = `-- name: GetTalkgroupsWithLearnedBySystem :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,
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
WHERE tg.system_id = $1
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE tg.system_id = $1 AND ignored IS NOT TRUE
|
||||||
|
`
|
||||||
|
|
||||||
|
const getTalkgroupsWithLearnedTest = `-- name: GetTalkgroupsWithLearned :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,
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE ignored IS NOT TRUE
|
||||||
|
`
|
||||||
|
|
||||||
func TestQueryColumnsMatch(t *testing.T) {
|
func TestQueryColumnsMatch(t *testing.T) {
|
||||||
require.Equal(t, getTalkgroupWithLearnedByPackedIDsTest, getTalkgroupWithLearnedByPackedIDs)
|
require.Equal(t, getTalkgroupsWithLearnedByPackedIDsTest, getTalkgroupWithLearnedByPackedIDs)
|
||||||
require.Equal(t, getTalkgroupWithLearnedTest, getTalkgroupWithLearned)
|
require.Equal(t, getTalkgroupWithLearnedTest, getTalkgroupWithLearned)
|
||||||
|
require.Equal(t, getTalkgroupsWithLearnedBySystemTest, getTalkgroupsWithLearnedBySystem)
|
||||||
|
require.Equal(t, getTalkgroupsWithLearnedTest, getTalkgroupsWithLearned)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.33.0
|
// protoc-gen-go v1.33.0
|
||||||
// protoc v5.28.2
|
// protoc v5.28.3
|
||||||
// source: stillbox.proto
|
// source: stillbox.proto
|
||||||
|
|
||||||
package pb
|
package pb
|
||||||
|
|
|
@ -24,6 +24,9 @@ type Store interface {
|
||||||
// TGs retrieves many talkgroups from the Store.
|
// TGs retrieves many talkgroups from the Store.
|
||||||
TGs(ctx context.Context, tgs IDs) ([]*Talkgroup, error)
|
TGs(ctx context.Context, tgs IDs) ([]*Talkgroup, error)
|
||||||
|
|
||||||
|
// SystemTGs retrieves all Talkgroups associated with a System.
|
||||||
|
SystemTGs(ctx context.Context, systemID int32) ([]*Talkgroup, error)
|
||||||
|
|
||||||
// SystemName retrieves a system name from the store. It returns the record and whether one was found.
|
// SystemName retrieves a system name from the store. It returns the record and whether one was found.
|
||||||
SystemName(ctx context.Context, id int) (string, bool)
|
SystemName(ctx context.Context, id int) (string, bool)
|
||||||
|
|
||||||
|
@ -131,33 +134,23 @@ func (t *cache) add(rec *Talkgroup) error {
|
||||||
return t.AlertConfig.UnmarshalTGRules(tg, rec.Talkgroup.AlertConfig)
|
return t.AlertConfig.UnmarshalTGRules(tg, rec.Talkgroup.AlertConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rowToTalkgroup(r database.GetTalkgroupWithLearnedByPackedIDsRow) *Talkgroup {
|
type row interface {
|
||||||
|
database.GetTalkgroupsWithLearnedByPackedIDsRow | database.GetTalkgroupsWithLearnedRow |
|
||||||
|
database.GetTalkgroupsWithLearnedBySystemRow
|
||||||
|
GetTalkgroup() database.Talkgroup
|
||||||
|
GetSystem() database.System
|
||||||
|
GetLearned() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func rowToTalkgroup[T row](r T) *Talkgroup {
|
||||||
return &Talkgroup{
|
return &Talkgroup{
|
||||||
Talkgroup: r.Talkgroup,
|
Talkgroup: r.GetTalkgroup(),
|
||||||
System: r.System,
|
System: r.GetSystem(),
|
||||||
Learned: r.Learned,
|
Learned: r.GetLearned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *cache) TGs(ctx context.Context, tgs IDs) ([]*Talkgroup, error) {
|
func addToRowList[T row](t *cache, r []*Talkgroup, tgRecords []T) ([]*Talkgroup, error) {
|
||||||
r := make([]*Talkgroup, 0, len(tgs))
|
|
||||||
toGet := make(IDs, 0, len(tgs))
|
|
||||||
t.RLock()
|
|
||||||
for _, id := range tgs {
|
|
||||||
rec, has := t.tgs[id]
|
|
||||||
if has {
|
|
||||||
r = append(r, rec)
|
|
||||||
} else {
|
|
||||||
toGet = append(toGet, id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t.RUnlock()
|
|
||||||
|
|
||||||
tgRecords, err := database.FromCtx(ctx).GetTalkgroupWithLearnedByPackedIDs(ctx, toGet.Packed())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rec := range tgRecords {
|
for _, rec := range tgRecords {
|
||||||
tg := rowToTalkgroup(rec)
|
tg := rowToTalkgroup(rec)
|
||||||
err := t.add(tg)
|
err := t.add(tg)
|
||||||
|
@ -171,8 +164,40 @@ func (t *cache) TGs(ctx context.Context, tgs IDs) ([]*Talkgroup, error) {
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *cache) TGs(ctx context.Context, tgs IDs) ([]*Talkgroup, error) {
|
||||||
|
r := make([]*Talkgroup, 0, len(tgs))
|
||||||
|
var err error
|
||||||
|
if tgs != nil {
|
||||||
|
toGet := make(IDs, 0, len(tgs))
|
||||||
|
t.RLock()
|
||||||
|
for _, id := range tgs {
|
||||||
|
rec, has := t.tgs[id]
|
||||||
|
if has {
|
||||||
|
r = append(r, rec)
|
||||||
|
} else {
|
||||||
|
toGet = append(toGet, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.RUnlock()
|
||||||
|
|
||||||
|
tgRecords, err := database.FromCtx(ctx).GetTalkgroupsWithLearnedByPackedIDs(ctx, toGet.Packed())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return addToRowList(t, r, tgRecords)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all talkgroups
|
||||||
|
|
||||||
|
tgRecords, err := database.FromCtx(ctx).GetTalkgroupsWithLearned(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return addToRowList(t, r, tgRecords)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *cache) Load(ctx context.Context, tgs []int64) error {
|
func (t *cache) Load(ctx context.Context, tgs []int64) error {
|
||||||
tgRecords, err := database.FromCtx(ctx).GetTalkgroupWithLearnedByPackedIDs(ctx, tgs)
|
tgRecords, err := database.FromCtx(ctx).GetTalkgroupsWithLearnedByPackedIDs(ctx, tgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -203,6 +228,16 @@ func (t *cache) Weight(ctx context.Context, id ID, tm time.Time) float64 {
|
||||||
return float64(m)
|
return float64(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *cache) SystemTGs(ctx context.Context, systemID int32) ([]*Talkgroup, error) {
|
||||||
|
recs, err := database.FromCtx(ctx).GetTalkgroupsWithLearnedBySystem(ctx, systemID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := make([]*Talkgroup, 0, len(recs))
|
||||||
|
return addToRowList(t, r, recs)
|
||||||
|
}
|
||||||
|
|
||||||
func (t *cache) TG(ctx context.Context, tg ID) (*Talkgroup, error) {
|
func (t *cache) TG(ctx context.Context, tg ID) (*Talkgroup, error) {
|
||||||
t.RLock()
|
t.RLock()
|
||||||
rec, has := t.tgs[tg]
|
rec, has := t.tgs[tg]
|
||||||
|
@ -212,7 +247,7 @@ func (t *cache) TG(ctx context.Context, tg ID) (*Talkgroup, error) {
|
||||||
return rec, nil
|
return rec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
recs, err := database.FromCtx(ctx).GetTalkgroupWithLearnedByPackedIDs(ctx, []int64{tg.Pack()})
|
recs, err := database.FromCtx(ctx).GetTalkgroupsWithLearnedByPackedIDs(ctx, []int64{tg.Pack()})
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
case pgx.ErrNoRows:
|
case pgx.ErrNoRows:
|
||||||
|
|
|
@ -51,7 +51,7 @@ 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 = sqlc.arg(system_id) AND tgl.tgid = sqlc.arg(tgid) AND ignored IS NOT TRUE;
|
WHERE tgl.system_id = sqlc.arg(system_id) AND tgl.tgid = sqlc.arg(tgid) AND ignored IS NOT TRUE;
|
||||||
|
|
||||||
-- name: GetTalkgroupWithLearnedByPackedIDs :many
|
-- name: GetTalkgroupsWithLearnedByPackedIDs :many
|
||||||
SELECT
|
SELECT
|
||||||
sqlc.embed(tg), sqlc.embed(sys),
|
sqlc.embed(tg), sqlc.embed(sys),
|
||||||
FALSE learned
|
FALSE learned
|
||||||
|
@ -69,5 +69,41 @@ FROM talkgroups_learned tgl
|
||||||
JOIN systems sys ON tgl.system_id = sys.id
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
WHERE systg2id(tgl.system_id, tgl.tgid) = ANY($1::INT8[]) AND ignored IS NOT TRUE;
|
WHERE systg2id(tgl.system_id, tgl.tgid) = ANY($1::INT8[]) AND ignored IS NOT TRUE;
|
||||||
|
|
||||||
|
-- name: GetTalkgroupsWithLearnedBySystem :many
|
||||||
|
SELECT
|
||||||
|
sqlc.embed(tg), sqlc.embed(sys),
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
WHERE tg.system_id = @system
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE tgl.system_id = @system AND ignored IS NOT TRUE;
|
||||||
|
|
||||||
|
-- name: GetTalkgroupsWithLearned :many
|
||||||
|
SELECT
|
||||||
|
sqlc.embed(tg), sqlc.embed(sys),
|
||||||
|
FALSE learned
|
||||||
|
FROM talkgroups tg
|
||||||
|
JOIN systems sys ON tg.system_id = sys.id
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
tgl.id::INT8, tgl.system_id::INT4, tgl.tgid::INT4, tgl.name,
|
||||||
|
tgl.alpha_tag, tgl.alpha_tag, NULL::INTEGER, NULL::JSONB,
|
||||||
|
CASE WHEN tgl.alpha_tag IS NULL THEN NULL ELSE ARRAY[tgl.alpha_tag] END,
|
||||||
|
TRUE, NULL::JSONB, 1.0, sys.id, sys.name,
|
||||||
|
TRUE learned
|
||||||
|
FROM talkgroups_learned tgl
|
||||||
|
JOIN systems sys ON tgl.system_id = sys.id
|
||||||
|
WHERE ignored IS NOT TRUE;
|
||||||
|
|
||||||
|
|
||||||
-- name: GetSystemName :one
|
-- name: GetSystemName :one
|
||||||
SELECT name FROM systems WHERE id = sqlc.arg(system_id);
|
SELECT name FROM systems WHERE id = sqlc.arg(system_id);
|
||||||
|
|
Loading…
Reference in a new issue