Files
go-weather/services/database.go
T
2026-02-18 15:35:56 -08:00

106 lines
2.3 KiB
Go

package services
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"go-weather/models"
"time"
)
func ConnectDB(connStr string) (*sql.DB, error) {
db, err := sql.Open("postgres", connStr)
if err != nil {
return nil, fmt.Errorf("failed to connect to db: %v", err)
}
err = db.Ping()
if err != nil {
return nil, fmt.Errorf("failed to connect to db: %v", err)
}
fmt.Println("connected to PostgreSQL")
return db, nil
}
type DatabaseService struct {
db *sql.DB
}
func NewDatabaseService(db *sql.DB) *DatabaseService {
return &DatabaseService{db: db}
}
func (s *DatabaseService) CreateTable() error {
_, err := s.db.Exec(`
CREATE TABLE IF NOT EXISTS weather_readings (
id SERIAL PRIMARY KEY,
city TEXT NOT NULL,
temp DOUBLE PRECISION NOT NULL,
feels_like DOUBLE PRECISION NOT NULL,
humidity INTEGER NOT NULL,
conditions TEXT NOT NULL,
fetched_at TIMESTAMP WITH TIME ZONE NOT NULL
)
`)
if err != nil {
fmt.Errorf("failed to create table: %v", err)
}
fmt.Println("weather_readings table ready")
return nil
}
func (s *DatabaseService) SaveReading(weather models.WeatherResponse) (int, error) {
conditions := ""
if len(weather.Weather) > 0 {
conditions = weather.Weather[0].Description
}
var id int
err := s.db.QueryRow(
`INSERT INTO weather_readings (city, temp, feels_like, humidity, conditions, fetched_at)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id`,
weather.Name,
weather.Main.Temp,
weather.Main.FeelsLike,
weather.Main.Humidity,
conditions,
time.Now(),
).Scan(&id)
if err != nil {
return 0, fmt.Errorf("failed to save reading: %w", err)
}
return id, nil
}
func (s *DatabaseService) GetReadings(city string, limit int) ([]models.Reading, error) {
rows, err := s.db.Query(
`SELECT id, city, temp, feels_like, humidity, conditions, fetched_at
FROM weather_readings
WHERE city ILIKE $1
ORDER BY fetched_at DESC
LIMIT $2`,
city, limit,
)
if err != nil {
return nil, fmt.Errorf("Query failed: %w", err)
}
defer rows.Close()
var readings []models.Reading
for rows.Next() {
var r models.Reading
err := rows.Scan(&r.ID, &r.City, &r.Temp, &r.FeelsLike, &r.Humidity, &r.Conditions, &r.FetchedAt)
if err != nil {
return nil, fmt.Errorf("scan failed: %w", err)
}
readings = append(readings, r)
}
return readings, nil
}