kettlebell-tracker/internal/data/database.go

156 lines
4.3 KiB
Go

package data
import (
"database/sql"
"fmt"
"log"
"time"
_ "modernc.org/sqlite"
)
type DatabaseService struct {
DB *sql.DB
}
func NewDatabaseService(dbPath string) (*DatabaseService, error) {
db, err := sql.Open("sqlite", dbPath)
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
return nil, err
}
createTableSQL := `
CREATE TABLE IF NOT EXISTS training (
id INTEGER PRIMARY KEY AUTOINCREMENT,
date TEXT NOT NULL,
sets INTEGER,
weightLeft REAL,
weightRight REAL,
repsPerSet INTEGER,
duration INTEGER,
program TEXT,
blockDay INTEGER
);`
_, err = db.Exec(createTableSQL)
if err != nil {
log.Printf("Fehler beim Erstellen der Tabelle: %v", err)
return nil, err
}
log.Println("Datenbank erfolgreich initialisiert.")
return &DatabaseService{DB: db}, nil
}
func (s *DatabaseService) SaveTraining(session *TrainingSession) error {
dateStr := session.Date.Format(time.RFC3339)
query := `
INSERT INTO training (id, date, sets, weightLeft, weightRight, repsPerSet, duration, program, blockDay)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
date = excluded.date,
sets = excluded.sets,
weightLeft = excluded.weightLeft,
weightRight = excluded.weightRight,
repsPerSet = excluded.repsPerSet,
duration = excluded.duration,
program = excluded.program,
blockDay = excluded.blockDay;
`
var id any
if session.ID != 0 {
id = session.ID
}
_, err := s.DB.Exec(query, id, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay)
return err
}
func (s *DatabaseService) GetHistory() ([]TrainingSession, error) {
query := `SELECT id, date, sets, weightLeft, weightRight, repsPerSet, duration, program, blockDay FROM training ORDER BY date DESC LIMIT 20;`
rows, err := s.DB.Query(query)
if err != nil {
return nil, err
}
defer rows.Close()
var sessions []TrainingSession
for rows.Next() {
var sess TrainingSession
var dateStr string
err := rows.Scan(&sess.ID, &dateStr, &sess.Sets, &sess.WeightLeft, &sess.WeightRight, &sess.RepsPerSet, &sess.Duration, &sess.Program, &sess.BlockDay)
if err != nil {
return nil, err
}
sess.Date, err = time.Parse(time.RFC3339, dateStr)
if err != nil {
return nil, err
}
sessions = append(sessions, sess)
}
return sessions, nil
}
func (s *DatabaseService) GetLastTraining() (*TrainingSession, error) {
query := `SELECT id, date, sets, weightLeft, weightRight, repsPerSet, duration, program, blockDay FROM training ORDER BY date DESC LIMIT 1;`
row := s.DB.QueryRow(query)
var session TrainingSession
var dateStr string
err := row.Scan(&session.ID, &dateStr, &session.Sets, &session.WeightLeft, &session.WeightRight, &session.RepsPerSet, &session.Duration, &session.Program, &session.BlockDay)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
session.Date, err = time.Parse(time.RFC3339, dateStr)
if err != nil {
return nil, err
}
return &session, nil
}
func (s *DatabaseService) GetTrainingCount() (int, error) {
var count int
query := "SELECT COUNT(*) FROM training;"
err := s.DB.QueryRow(query).Scan(&count)
if err != nil {
if err == sql.ErrNoRows {
return 0, nil
}
return 0, err
}
return count, nil
}
func (s *DatabaseService) DeleteTraining(id int64) error {
query := "DELETE FROM training WHERE id = ?;"
_, err := s.DB.Exec(query, id)
return err
}
func (s *DatabaseService) UpdateTraining(session *TrainingSession) error {
dateStr := session.Date.Format(time.RFC3339)
query := `
UPDATE training
SET date = ?, sets = ?, weightLeft = ?, weightRight = ?, repsPerSet = ?, duration = ?, program = ?, blockDay = ?
WHERE id = ?;
`
res, err := s.DB.Exec(query, dateStr, session.Sets, session.WeightLeft, session.WeightRight, session.RepsPerSet, session.Duration, session.Program, session.BlockDay, session.ID)
if err != nil {
log.Printf("UpdateTraining Fehler: %v", err)
return err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Printf("UpdateTraining RowsAffected Fehler: %v", err)
return err
}
if rowsAffected == 0 {
log.Printf("UpdateTraining: Kein Datensatz mit ID %d gefunden", session.ID)
return fmt.Errorf("kein Datensatz mit ID %d gefunden", session.ID)
}
log.Printf("UpdateTraining erfolgreich für ID %d", session.ID)
return nil
}