80 lines
2.1 KiB
Go
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
|
|
}
|