This commit is contained in:
Erik Winter 2024-12-19 12:06:03 +01:00
parent caa1a45efb
commit 55fe158f79
3 changed files with 110 additions and 114 deletions

View File

@ -1,109 +1,68 @@
package command_test package command_test
// func TestArgSet(t *testing.T) { import (
// t.Parallel() "testing"
// as := command.ArgSet{ "github.com/google/go-cmp/cmp"
// Main: "main", "go-mod.ewintr.nl/planner/plan/command"
// Flags: map[string]string{ )
// "name 1": "value 1",
// "name 2": "value 2",
// "name 3": "value 3",
// },
// }
// t.Run("hasflag", func(t *testing.T) { func TestParseArgs(t *testing.T) {
// t.Run("true", func(t *testing.T) { t.Parallel()
// if has := as.HasFlag("name 1"); !has {
// t.Errorf("exp true, got %v", has)
// }
// })
// t.Run("false", func(t *testing.T) {
// if has := as.HasFlag("unknown"); has {
// t.Errorf("exp false, got %v", has)
// }
// })
// })
// t.Run("flag", func(t *testing.T) { for _, tc := range []struct {
// t.Run("known", func(t *testing.T) { name string
// if val := as.Flag("name 1"); val != "value 1" { args []string
// t.Errorf("exp value 1, got %v", val) expMain []string
// } expFlags map[string]string
// }) expErr bool
// t.Run("unknown", func(t *testing.T) { }{
// if val := as.Flag("unknown"); val != "" { {
// t.Errorf(`exp "", got %v`, val) name: "empty",
// } expMain: []string{},
// }) expFlags: map[string]string{},
// }) },
{
// t.Run("setflag", func(t *testing.T) { name: "just main",
// exp := "new value" args: []string{"one", "two three", "four"},
// as.SetFlag("new name", exp) expMain: []string{"one", "two three", "four"},
// if act := as.Flag("new name"); exp != act { expFlags: map[string]string{},
// t.Errorf("exp %v, got %v", exp, act) },
// } {
// }) name: "with flags",
// } args: []string{"-flag1", "value1", "one", "two", "-flag2", "value2", "-flag3", "value3"},
expMain: []string{"one", "two"},
// func TestParseArgs(t *testing.T) { expFlags: map[string]string{
// t.Parallel() "flag1": "value1",
"flag2": "value2",
// for _, tc := range []struct { "flag3": "value3",
// name string },
// args []string },
// expAS *command.ArgSet {
// expErr bool name: "flag without value",
// }{ args: []string{"one", "two", "-flag1"},
// { expErr: true,
// name: "empty", },
// expAS: &command.ArgSet{ {
// Flags: map[string]string{}, name: "split main",
// }, args: []string{"one", "-flag1", "value1", "two"},
// }, expErr: true,
// { },
// name: "just main", } {
// args: []string{"one", "two three", "four"}, t.Run(tc.name, func(t *testing.T) {
// expAS: &command.ArgSet{ actMain, actFlags, actErr := command.ParseFlags(tc.args)
// Main: "one two three four", if tc.expErr != (actErr != nil) {
// Flags: map[string]string{}, t.Errorf("exp %v, got %v", tc.expErr, actErr)
// }, }
// }, if tc.expErr {
// { return
// name: "with flags", }
// args: []string{"-flag1", "value1", "one", "two", "-flag2", "value2", "-flag3", "value3"}, if diff := cmp.Diff(tc.expMain, actMain); diff != "" {
// expAS: &command.ArgSet{ t.Errorf("(exp +, got -)\n%s", diff)
// Main: "one two", }
// Flags: map[string]string{ if diff := cmp.Diff(tc.expFlags, actFlags); diff != "" {
// "flag1": "value1", t.Errorf("(exp +, got -)\n%s", diff)
// "flag2": "value2", }
// "flag3": "value3", })
// }, }
// }, }
// },
// {
// name: "flag without value",
// args: []string{"one", "two", "-flag1"},
// expErr: true,
// },
// {
// name: "split main",
// args: []string{"one", "-flag1", "value1", "two"},
// expErr: true,
// },
// } {
// t.Run(tc.name, func(t *testing.T) {
// actAS, actErr := command.ParseArgs(tc.args)
// if tc.expErr != (actErr != nil) {
// t.Errorf("exp %v, got %v", tc.expErr, actErr)
// }
// if tc.expErr {
// return
// }
// if diff := cmp.Diff(tc.expAS, actAS); diff != "" {
// t.Errorf("(exp +, got -)\n%s", diff)
// }
// })
// }
// }

View File

@ -2,6 +2,7 @@ package sqlite
import ( import (
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"time" "time"
@ -14,18 +15,29 @@ type SqliteEvent struct {
} }
func (s *SqliteEvent) Store(event item.Event) error { func (s *SqliteEvent) Store(event item.Event) error {
var recurStr *string
if event.Recurrer != nil {
recurBytes, err := json.Marshal(event.Recurrer)
if err != nil {
return fmt.Errorf("could not marshal recurrer: %v", err)
}
rs := string(recurBytes)
recurStr = &rs
}
if _, err := s.db.Exec(` if _, err := s.db.Exec(`
INSERT INTO events INSERT INTO events
(id, title, start, duration) (id, title, start, duration, recur)
VALUES VALUES
(?, ?, ?, ?) (?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE ON CONFLICT(id) DO UPDATE
SET SET
title=?, title=?,
start=?, start=?,
duration=?`, duration=?,
event.ID, event.Title, event.Start.Format(timestampFormat), event.Duration.String(), recur=?
event.Title, event.Start.Format(timestampFormat), event.Duration.String()); err != nil { `,
event.ID, event.Title, event.Start.Format(timestampFormat), event.Duration.String(), recurStr,
event.Title, event.Start.Format(timestampFormat), event.Duration.String(), recurStr); err != nil {
return fmt.Errorf("%w: %v", ErrSqliteFailure, err) return fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
return nil return nil
@ -34,10 +46,11 @@ duration=?`,
func (s *SqliteEvent) Find(id string) (item.Event, error) { func (s *SqliteEvent) Find(id string) (item.Event, error) {
var event item.Event var event item.Event
var durStr string var durStr string
var recurStr *string
err := s.db.QueryRow(` err := s.db.QueryRow(`
SELECT id, title, start, duration SELECT id, title, start, duration, recur
FROM events FROM events
WHERE id = ?`, id).Scan(&event.ID, &event.Title, &event.Start, &durStr) WHERE id = ?`, id).Scan(&event.ID, &event.Title, &event.Start, &durStr, &recurStr)
switch { switch {
case err == sql.ErrNoRows: case err == sql.ErrNoRows:
return item.Event{}, fmt.Errorf("event not found: %w", err) return item.Event{}, fmt.Errorf("event not found: %w", err)
@ -46,16 +59,23 @@ WHERE id = ?`, id).Scan(&event.ID, &event.Title, &event.Start, &durStr)
} }
dur, err := time.ParseDuration(durStr) dur, err := time.ParseDuration(durStr)
if err != nil { if err != nil {
return item.Event{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return item.Event{}, fmt.Errorf("could not unmarshal recurrer: %v", err)
} }
event.Duration = dur event.Duration = dur
if recurStr != nil {
var rec item.Recur
if err := json.Unmarshal([]byte(*recurStr), &rec); err != nil {
return item.Event{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
event.Recurrer = &rec
}
return event, nil return event, nil
} }
func (s *SqliteEvent) FindAll() ([]item.Event, error) { func (s *SqliteEvent) FindAll() ([]item.Event, error) {
rows, err := s.db.Query(` rows, err := s.db.Query(`
SELECT id, title, start, duration SELECT id, title, start, duration, recur
FROM events`) FROM events`)
if err != nil { if err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
@ -65,7 +85,8 @@ FROM events`)
for rows.Next() { for rows.Next() {
var event item.Event var event item.Event
var durStr string var durStr string
if err := rows.Scan(&event.ID, &event.Title, &event.Start, &durStr); err != nil { var recurStr *string
if err := rows.Scan(&event.ID, &event.Title, &event.Start, &durStr, &recurStr); err != nil {
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
dur, err := time.ParseDuration(durStr) dur, err := time.ParseDuration(durStr)
@ -73,6 +94,13 @@ FROM events`)
return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err) return nil, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
} }
event.Duration = dur event.Duration = dur
if recurStr != nil {
var rec item.Recur
if err := json.Unmarshal([]byte(*recurStr), &rec); err != nil {
return nil, fmt.Errorf("could not unmarshal recurrer: %v", err)
}
event.Recurrer = &rec
}
result = append(result, event) result = append(result, event)
} }

View File

@ -25,6 +25,15 @@ var migrations = []string{
deleted BOOLEAN NOT NULL, deleted BOOLEAN NOT NULL,
body TEXT NOT NULL body TEXT NOT NULL
)`, )`,
`ALTER TABLE events ADD COLUMN recur_period TEXT`,
`ALTER TABLE events ADD COLUMN recur_count INTEGER`,
`ALTER TABLE events ADD COLUMN recur_start TIMESTAMP`,
`ALTER TABLE events ADD COLUMN recur_next TIMESTAMP`,
`ALTER TABLE events DROP COLUMN recur_period`,
`ALTER TABLE events DROP COLUMN recur_count`,
`ALTER TABLE events DROP COLUMN recur_start`,
`ALTER TABLE events DROP COLUMN recur_next`,
`ALTER TABLE events ADD COLUMN recur TEXT`,
} }
var ( var (