Files
weatherapi/internal/adapters/outbound/postgres/observations_read.go
2026-03-20 09:44:53 -05:00

80 lines
2.1 KiB
Go

// observations_read.go executes observation and present-weather queries.
// Layer: adapters/outbound/postgres observations feature.
package postgres
import (
"context"
"database/sql"
"errors"
"fmt"
"gitea.maximumdirect.net/ejr/weatherfeeder/model"
)
func (r *Repository) LatestObservation(ctx context.Context) (*model.WeatherObservation, error) {
if r == nil || r.db == nil {
return nil, fmt.Errorf("postgres repository is not configured")
}
var row observationParentRow
err := r.db.QueryRowContext(ctx, queryLatestObservation).Scan(
&row.EventID,
&row.StationID,
&row.StationName,
&row.ObservedAt,
&row.ConditionCode,
&row.IsDay,
&row.TextDescription,
&row.TemperatureC,
&row.DewpointC,
&row.WindDirectionDegrees,
&row.WindSpeedKmh,
&row.WindGustKmh,
&row.BarometricPressurePa,
&row.VisibilityMeters,
&row.RelativeHumidityPercent,
&row.ApparentTemperatureC,
)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("query latest observation: %w", err)
}
obs := mapObservationParentRow(row)
presentWeather, err := r.loadObservationPresentWeather(ctx, row.EventID)
if err != nil {
return nil, err
}
obs.PresentWeather = presentWeather
return &obs, nil
}
func (r *Repository) loadObservationPresentWeather(ctx context.Context, eventID string) ([]model.PresentWeather, error) {
rows, err := r.db.QueryContext(ctx, queryObservationPresentWeather, eventID)
if err != nil {
return nil, fmt.Errorf("query observation present weather: %w", err)
}
defer rows.Close()
out := make([]model.PresentWeather, 0)
for rows.Next() {
var row observationPresentWeatherRow
if err := rows.Scan(&row.WeatherIndex, &row.RawText); err != nil {
return nil, fmt.Errorf("scan observation present weather row: %w", err)
}
pw, err := mapObservationPresentWeatherRow(row)
if err != nil {
return nil, fmt.Errorf("decode observation present weather row (index=%d): %w", row.WeatherIndex, err)
}
out = append(out, pw)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate observation present weather rows: %w", err)
}
return out, nil
}