All checks were successful
ci/woodpecker/push/build-image Pipeline was successful
112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
// alerts_read.go executes alert-run, alerts, and reference queries.
|
|
// Layer: adapters/outbound/postgres alerts feature.
|
|
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"gitea.maximumdirect.net/ejr/weatherfeeder/model"
|
|
)
|
|
|
|
func (r *Repository) LatestAlertRun(ctx context.Context) (*model.WeatherAlertRun, error) {
|
|
if r == nil || r.db == nil {
|
|
return nil, fmt.Errorf("postgres repository is not configured")
|
|
}
|
|
|
|
var row alertRunParentRow
|
|
err := r.db.QueryRowContext(ctx, queryLatestAlertRun).Scan(
|
|
&row.EventID,
|
|
&row.LocationID,
|
|
&row.LocationName,
|
|
&row.AsOf,
|
|
&row.Latitude,
|
|
&row.Longitude,
|
|
)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query latest alert run: %w", err)
|
|
}
|
|
|
|
run := mapAlertRunParentRow(row)
|
|
|
|
alerts, err := r.loadAlerts(ctx, row.EventID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
run.Alerts = alerts
|
|
|
|
return &run, nil
|
|
}
|
|
|
|
func (r *Repository) loadAlerts(ctx context.Context, eventID string) ([]model.WeatherAlert, error) {
|
|
alertsRows, err := r.db.QueryContext(ctx, queryAlerts, eventID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query alerts: %w", err)
|
|
}
|
|
defer alertsRows.Close()
|
|
|
|
indexedAlerts := make([]indexedAlert, 0)
|
|
for alertsRows.Next() {
|
|
var row alertRow
|
|
if err := alertsRows.Scan(
|
|
&row.AlertIndex,
|
|
&row.AlertID,
|
|
&row.Event,
|
|
&row.Headline,
|
|
&row.Severity,
|
|
&row.Urgency,
|
|
&row.Certainty,
|
|
&row.Status,
|
|
&row.MessageType,
|
|
&row.Category,
|
|
&row.Response,
|
|
&row.Description,
|
|
&row.Instruction,
|
|
&row.Sent,
|
|
&row.Effective,
|
|
&row.Onset,
|
|
&row.Ends,
|
|
&row.Expires,
|
|
&row.AreaDescription,
|
|
&row.SenderName,
|
|
); err != nil {
|
|
return nil, fmt.Errorf("scan alerts row: %w", err)
|
|
}
|
|
indexedAlerts = append(indexedAlerts, mapAlertRow(row))
|
|
}
|
|
if err := alertsRows.Err(); err != nil {
|
|
return nil, fmt.Errorf("iterate alerts rows: %w", err)
|
|
}
|
|
|
|
referenceRows, err := r.db.QueryContext(ctx, queryAlertReferences, eventID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("query alert references: %w", err)
|
|
}
|
|
defer referenceRows.Close()
|
|
|
|
indexedReferences := make([]indexedAlertReference, 0)
|
|
for referenceRows.Next() {
|
|
var row alertReferenceRow
|
|
if err := referenceRows.Scan(
|
|
&row.AlertIndex,
|
|
&row.ID,
|
|
&row.Identifier,
|
|
&row.Sender,
|
|
&row.Sent,
|
|
); err != nil {
|
|
return nil, fmt.Errorf("scan alert reference row: %w", err)
|
|
}
|
|
indexedReferences = append(indexedReferences, mapAlertReferenceRow(row))
|
|
}
|
|
if err := referenceRows.Err(); err != nil {
|
|
return nil, fmt.Errorf("iterate alert reference rows: %w", err)
|
|
}
|
|
|
|
return attachAlertReferences(indexedAlerts, indexedReferences), nil
|
|
}
|