planner/plan/storage/sqlite/task.go

147 lines
3.5 KiB
Go
Raw Normal View History

2024-12-24 08:00:23 +01:00
package sqlite
import (
"database/sql"
"fmt"
"time"
"go-mod.ewintr.nl/planner/item"
"go-mod.ewintr.nl/planner/plan/storage"
)
type SqliteTask struct {
db *sql.DB
}
func (t *SqliteTask) Store(tsk item.Task) error {
var recurStr string
if tsk.Recurrer != nil {
recurStr = tsk.Recurrer.String()
}
if _, err := t.db.Exec(`
INSERT INTO tasks
2024-12-31 08:37:00 +01:00
(id, title, project, date, time, duration, recurrer)
2024-12-24 08:00:23 +01:00
VALUES
2024-12-31 08:37:00 +01:00
(?, ?, ?, ?, ?, ?, ?)
2024-12-24 08:00:23 +01:00
ON CONFLICT(id) DO UPDATE
SET
title=?,
2024-12-31 08:37:00 +01:00
project=?,
2024-12-24 08:00:23 +01:00
date=?,
time=?,
duration=?,
recurrer=?
`,
2024-12-31 08:37:00 +01:00
tsk.ID, tsk.Title, tsk.Project, tsk.Date.String(), tsk.Time.String(), tsk.Duration.String(), recurStr,
tsk.Title, tsk.Project, tsk.Date.String(), tsk.Time.String(), tsk.Duration.String(), recurStr); err != nil {
2024-12-24 08:00:23 +01:00
return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
return nil
}
2024-12-29 09:32:49 +01:00
func (t *SqliteTask) FindOne(id string) (item.Task, error) {
2024-12-24 08:00:23 +01:00
var tsk item.Task
var dateStr, timeStr, recurStr, durStr string
err := t.db.QueryRow(`
2024-12-31 08:37:00 +01:00
SELECT id, title, project, date, time, duration, recurrer
2024-12-24 08:00:23 +01:00
FROM tasks
2024-12-31 08:37:00 +01:00
WHERE id = ?`, id).Scan(&tsk.ID, &tsk.Title, &tsk.Project, &dateStr, &timeStr, &durStr, &recurStr)
2024-12-24 08:00:23 +01:00
switch {
case err == sql.ErrNoRows:
return item.Task{}, fmt.Errorf("event not found: %w", err)
case err != nil:
return item.Task{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
tsk.Date = item.NewDateFromString(dateStr)
tsk.Time = item.NewTimeFromString(timeStr)
dur, err := time.ParseDuration(durStr)
if err != nil {
return item.Task{}, fmt.Errorf("could not unmarshal recurrer: %v", err)
}
tsk.Duration = dur
tsk.Recurrer = item.NewRecurrer(recurStr)
return tsk, nil
}
2024-12-29 09:32:49 +01:00
func (t *SqliteTask) FindMany(params storage.TaskListParams) ([]item.Task, error) {
2024-12-31 08:37:00 +01:00
query := `SELECT id, title, project, date, time, duration, recurrer FROM tasks`
2024-12-29 09:32:49 +01:00
args := []interface{}{}
where := make([]string, 0)
2025-01-05 09:44:26 +01:00
var dateNonEmpty bool
2025-01-04 11:03:57 +01:00
if params.HasRecurrer {
2024-12-31 09:00:35 +01:00
where[0] = `recurrer != ''`
2024-12-29 09:32:49 +01:00
}
2025-01-04 11:03:57 +01:00
if !params.From.IsZero() {
where = append(where, `date >= ?`)
args = append(args, params.From.String())
2025-01-05 09:44:26 +01:00
dateNonEmpty = true
2024-12-29 09:32:49 +01:00
}
2025-01-04 11:03:57 +01:00
if !params.To.IsZero() {
2024-12-29 09:32:49 +01:00
where = append(where, `date <= ?`)
2025-01-04 11:03:57 +01:00
args = append(args, params.To.String())
2025-01-05 09:44:26 +01:00
dateNonEmpty = true
2024-12-29 09:32:49 +01:00
}
2024-12-31 09:22:03 +01:00
if params.Project != "" {
where = append(where, `project = ?`)
args = append(args, params.Project)
}
2025-01-05 09:44:26 +01:00
if dateNonEmpty {
where = append(where, `date != ""`)
}
2024-12-29 09:32:49 +01:00
if len(where) > 0 {
query += ` WHERE ` + where[0]
for _, w := range where[1:] {
query += ` AND ` + w
}
}
rows, err := t.db.Query(query, args...)
2024-12-24 08:00:23 +01:00
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
2024-12-29 09:32:49 +01:00
tasks := make([]item.Task, 0)
2024-12-24 08:00:23 +01:00
defer rows.Close()
for rows.Next() {
var tsk item.Task
var dateStr, timeStr, recurStr, durStr string
2024-12-31 08:37:00 +01:00
if err := rows.Scan(&tsk.ID, &tsk.Title, &tsk.Project, &dateStr, &timeStr, &durStr, &recurStr); err != nil {
2024-12-24 08:00:23 +01:00
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
dur, err := time.ParseDuration(durStr)
if err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
tsk.Date = item.NewDateFromString(dateStr)
tsk.Time = item.NewTimeFromString(timeStr)
tsk.Duration = dur
tsk.Recurrer = item.NewRecurrer(recurStr)
2024-12-29 09:32:49 +01:00
tasks = append(tasks, tsk)
2024-12-24 08:00:23 +01:00
}
2024-12-29 09:32:49 +01:00
return tasks, nil
2024-12-24 08:00:23 +01:00
}
func (s *SqliteTask) Delete(id string) error {
result, err := s.db.Exec(`
DELETE FROM tasks
WHERE id = ?`, id)
if err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
if rowsAffected == 0 {
return storage.ErrNotFound
}
return nil
}