Refactored the application structure to better separate concerns between files and packages
Some checks failed
ci/woodpecker/push/build-image Pipeline failed
Some checks failed
ci/woodpecker/push/build-image Pipeline failed
This commit is contained in:
79
internal/adapters/outbound/postgres/observations_read.go
Normal file
79
internal/adapters/outbound/postgres/observations_read.go
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user