Files
spend-sparrow/db/workout.go
2024-12-04 22:04:32 +01:00

120 lines
2.7 KiB
Go

package db
import (
"me-fit/log"
"me-fit/types"
"database/sql"
"errors"
"time"
"github.com/google/uuid"
)
var (
ErrWorkoutNotExists = errors.New("Workout does not exist")
)
type WorkoutDb interface {
InsertWorkout(userId uuid.UUID, workout *WorkoutInsert) (*Workout, error)
GetWorkouts(userId uuid.UUID) ([]Workout, error)
DeleteWorkout(userId uuid.UUID, rowId int) error
}
type WorkoutDbSqlite struct {
db *sql.DB
}
func NewWorkoutDbSqlite(db *sql.DB) *WorkoutDbSqlite {
return &WorkoutDbSqlite{db: db}
}
type WorkoutInsert struct {
Date time.Time
Type string
Sets int
Reps int
}
type Workout struct {
RowId int
Date time.Time
Type string
Sets int
Reps int
}
func NewWorkoutInsert(date time.Time, workoutType string, sets int, reps int) *WorkoutInsert {
return &WorkoutInsert{Date: date, Type: workoutType, Sets: sets, Reps: reps}
}
func NewWorkoutFromInsert(rowId int, workoutInsert *WorkoutInsert) *Workout {
return &Workout{RowId: rowId, Date: workoutInsert.Date, Type: workoutInsert.Type, Sets: workoutInsert.Sets, Reps: workoutInsert.Reps}
}
func (db WorkoutDbSqlite) InsertWorkout(userId uuid.UUID, workout *WorkoutInsert) (*Workout, error) {
var rowId int
err := db.db.QueryRow(`
INSERT INTO workout (user_id, date, type, sets, reps)
VALUES (?, ?, ?, ?, ?)
RETURNING rowid`, userId, workout.Date, workout.Type, workout.Sets, workout.Reps).Scan(&rowId)
if err != nil {
log.Error("Error inserting workout: %v", err)
return nil, types.ErrInternal
}
return NewWorkoutFromInsert(rowId, workout), nil
}
func (db WorkoutDbSqlite) GetWorkouts(userId uuid.UUID) ([]Workout, error) {
rows, err := db.db.Query("SELECT rowid, date, type, sets, reps FROM workout WHERE user_id = ? ORDER BY date desc", userId)
if err != nil {
log.Error("Could not get workouts: %v", err)
return nil, types.ErrInternal
}
var workouts = make([]Workout, 0)
for rows.Next() {
var (
workout Workout
date string
)
err = rows.Scan(&workout.RowId, &date, &workout.Type, &workout.Sets, &workout.Reps)
if err != nil {
log.Error("Could not scan workout: %v", err)
return nil, types.ErrInternal
}
workout.Date, err = time.Parse("2006-01-02 15:04:05-07:00", date)
if err != nil {
log.Error("Could not parse date: %v", err)
return nil, types.ErrInternal
}
workouts = append(workouts, workout)
}
return workouts, nil
}
func (db WorkoutDbSqlite) DeleteWorkout(userId uuid.UUID, rowId int) error {
res, err := db.db.Exec("DELETE FROM workout WHERE user_id = ? AND rowid = ?", userId, rowId)
if err != nil {
return types.ErrInternal
}
rows, err := res.RowsAffected()
if err != nil {
return types.ErrInternal
}
if rows == 0 {
return ErrWorkoutNotExists
}
return nil
}