diff --git a/main.go b/main.go index 06f2b10..dfa38b0 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "github.com/jawher/mow.cli" "os" @@ -15,7 +16,7 @@ func maybe(err error) { } func startTask(task Task, prompter Prompter, db *Store) { - taskID, err := db.AddTask(task) + taskID, err := db.CreateTask(task) maybe(err) for i := 0; i < task.count; i++ { // Create a record for @@ -30,7 +31,7 @@ func startTask(task Task, prompter Prompter, db *Store) { // Record how long the user waited // until closing the notification record.End = time.Now() - maybe(db.AddRecord(taskID, *record)) + maybe(db.CreateRecord(taskID, *record)) } } @@ -71,7 +72,19 @@ func initialize(cmd *cli.Cmd) { } } -func list(cmd *cli.Cmd) {} +func list(cmd *cli.Cmd) { + var ( + path = cmd.StringOpt("p path", defaultDBPath(), "path to the pomo state directory") + ) + cmd.Action = func() { + db, err := NewStore(*path) + maybe(err) + defer db.Close() + tasks, err := db.ReadTasks() + maybe(err) + maybe(json.NewEncoder(os.Stdout).Encode(tasks)) + } +} func main() { app := cli.App("pomo", "Pomodoro CLI") diff --git a/store.go b/store.go index efaa757..e24c4bb 100644 --- a/store.go +++ b/store.go @@ -5,8 +5,12 @@ import ( _ "github.com/mattn/go-sqlite3" "os" "os/user" + "time" ) +// 2018-01-16 19:05:21.752851759+08:00 +const datetimeFmt = "2006-01-02 15:04:05.999999999-07:00" + func defaultDBPath() string { u, err := user.Current() maybe(err) @@ -26,7 +30,7 @@ func NewStore(path string) (*Store, error) { return &Store{db: db}, nil } -func (s Store) AddTask(task Task) (int, error) { +func (s Store) CreateTask(task Task) (int, error) { var taskID int tx, err := s.db.Begin() if err != nil { @@ -45,7 +49,7 @@ func (s Store) AddTask(task Task) (int, error) { return taskID, tx.Commit() } -func (s Store) AddRecord(taskID int, record Record) error { +func (s Store) CreateRecord(taskID int, record Record) error { _, err := s.db.Exec( `INSERT INTO record (task_id, start, end) VALUES ($1, $2, $3)`, taskID, @@ -55,6 +59,55 @@ func (s Store) AddRecord(taskID int, record Record) error { return err } +func (s Store) ReadTasks() ([]*Task, error) { + rows, err := s.db.Query(`SELECT rowid,name FROM task`) + if err != nil { + return nil, err + } + tasks := []*Task{} + for rows.Next() { + task := &Task{Records: []*Record{}} + err = rows.Scan(&task.ID, &task.Name) + if err != nil { + return nil, err + } + records, err := s.ReadRecords(task.ID) + if err != nil { + return nil, err + } + for _, record := range records { + task.Records = append(task.Records, record) + } + tasks = append(tasks, task) + } + return tasks, nil +} + +func (s Store) ReadRecords(taskID int) ([]*Record, error) { + rows, err := s.db.Query(`SELECT start,end FROM record WHERE task_id = $1`, &taskID) + if err != nil { + return nil, err + } + records := []*Record{} + for rows.Next() { + var ( + startStr string + endStr string + ) + record := &Record{} + err = rows.Scan(&startStr, &endStr) + if err != nil { + return nil, err + } + start, _ := time.Parse(datetimeFmt, startStr) + end, _ := time.Parse(datetimeFmt, endStr) + record.Start = start + record.End = end + records = append(records, record) + } + return records, nil +} + func (s Store) Close() error { return s.db.Close() } func initDB(db *Store) error { diff --git a/types.go b/types.go index 550c1ad..b1eaa54 100644 --- a/types.go +++ b/types.go @@ -8,8 +8,9 @@ import ( // Task describes some activity type Task struct { - ID int `json:"id"` - Name string `json:"name"` + ID int `json:"id"` + Name string `json:"name"` + Records []*Record `json:"records"` count int duration time.Duration } @@ -17,9 +18,8 @@ type Task struct { // Record is a stetch of work performed on a // specific task. type Record struct { - TaskID int `json:"task_id"` - Start time.Time `json:"start"` - End time.Time `json:"end"` + Start time.Time `json:"start"` + End time.Time `json:"end"` } // Prompter prompts a user with a message.