From 099e3268ea40eafcfbe227bbd31f916816200b86 Mon Sep 17 00:00:00 2001 From: Kevin Schoon Date: Tue, 16 Jan 2018 19:06:20 +0800 Subject: [PATCH] implement state --- main.go | 28 +++++++++++++++------- store.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- types.go | 4 ++-- 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index dfdfa46..06f2b10 100644 --- a/main.go +++ b/main.go @@ -9,7 +9,7 @@ import ( func maybe(err error) { if err != nil { - fmt.Printf("Error: %s", err) + fmt.Printf("Error:\n%s\n", err) os.Exit(1) } } @@ -18,19 +18,19 @@ func startTask(task Task, prompter Prompter, db *Store) { taskID, err := db.AddTask(task) maybe(err) for i := 0; i < task.count; i++ { - // Create a new "Pomo" to represent + // Create a record for // this particular stent of work - pomo := &Pomo{TaskID: taskID} + record := &Record{} // Prompt the client maybe(prompter.Prompt("Begin Working!")) - pomo.Start = time.Now() + record.Start = time.Now() // Wait the specified interval time.Sleep(task.duration) maybe(prompter.Prompt("Take a Break!")) // Record how long the user waited // until closing the notification - pomo.End = time.Now() - maybe(db.AddPomo(*pomo)) + record.End = time.Now() + maybe(db.AddRecord(taskID, *record)) } } @@ -41,13 +41,14 @@ func start(cmd *cli.Cmd) { duration = cmd.StringOpt("d duration", "25m", "duration of each stent") count = cmd.IntOpt("c count", 4, "number of working stents") name = cmd.StringArg("NAME", "", "descriptive name of the given task") - path = cmd.StringOpt("d db", "~/.pomo/state.db", "path to the pomo sqlite database") + path = cmd.StringOpt("p path", defaultDBPath(), "path to the pomo state directory") ) cmd.Action = func() { parsed, err := time.ParseDuration(*duration) maybe(err) db, err := NewStore(*path) maybe(err) + defer db.Close() task := Task{ Name: *name, count: *count, @@ -57,7 +58,18 @@ func start(cmd *cli.Cmd) { } } -func initialize(cmd *cli.Cmd) {} +func initialize(cmd *cli.Cmd) { + cmd.Spec = "[OPTIONS]" + 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() + maybe(initDB(db)) + } +} func list(cmd *cli.Cmd) {} diff --git a/store.go b/store.go index 48c0ae1..efaa757 100644 --- a/store.go +++ b/store.go @@ -1,11 +1,73 @@ package main -type Store struct{} +import ( + "database/sql" + _ "github.com/mattn/go-sqlite3" + "os" + "os/user" +) -func NewStore(path string) (*Store, error) { - return &Store{}, nil +func defaultDBPath() string { + u, err := user.Current() + maybe(err) + return u.HomeDir + "/.pomo" } -func (s Store) AddTask(task Task) (int, error) { return 0, nil } +type Store struct { + db *sql.DB +} -func (s Store) AddPomo(pomo Pomo) error { return nil } +func NewStore(path string) (*Store, error) { + os.Mkdir(path, 0755) + db, err := sql.Open("sqlite3", path+"/pomo.db") + if err != nil { + return nil, err + } + return &Store{db: db}, nil +} + +func (s Store) AddTask(task Task) (int, error) { + var taskID int + tx, err := s.db.Begin() + if err != nil { + return -1, err + } + _, err = tx.Exec("INSERT INTO task (name) VALUES ($1)", task.Name) + if err != nil { + tx.Rollback() + return -1, err + } + err = tx.QueryRow("SELECT last_insert_rowid() FROM task").Scan(&taskID) + if err != nil { + tx.Rollback() + return -1, err + } + return taskID, tx.Commit() +} + +func (s Store) AddRecord(taskID int, record Record) error { + _, err := s.db.Exec( + `INSERT INTO record (task_id, start, end) VALUES ($1, $2, $3)`, + taskID, + record.Start, + record.End, + ) + return err +} + +func (s Store) Close() error { return s.db.Close() } + +func initDB(db *Store) error { + stmt := ` + CREATE TABLE task ( + name TEXT + ); + CREATE TABLE record ( + task_id INTEGER, + start DATETTIME, + end DATETTIME + ); + ` + _, err := db.db.Exec(stmt) + return err +} diff --git a/types.go b/types.go index 2054ede..550c1ad 100644 --- a/types.go +++ b/types.go @@ -14,9 +14,9 @@ type Task struct { duration time.Duration } -// Pomo is a stetch of work performed on a +// Record is a stetch of work performed on a // specific task. -type Pomo struct { +type Record struct { TaskID int `json:"task_id"` Start time.Time `json:"start"` End time.Time `json:"end"`