todo/cmd/todo.go

121 lines
2.4 KiB
Go

package cmd
import (
"log"
"time"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Todo struct {
ID uint64
Desc string
DueDate time.Time
CreatedAt time.Time
IsDone bool
}
// errPanic exits program with msg and error details if there is an error.
func errPanic(err error, msg string) {
if err != nil {
log.Fatalf(msg, err)
}
}
// parseDateString returns parsed time from string or time.Time{}.
func parseDateString(date string) time.Time {
var (
t time.Time
err error
layouts = []string{
"02/01/2006",
"02/01/2006T15:04",
}
)
for _, layout := range layouts {
t, err = time.Parse(layout, date)
if err == nil {
return t
}
}
return time.Time{}
}
// openDB returns gorm database.
func openDB() *gorm.DB {
db, err := gorm.Open(sqlite.Open("/home/user/.todo.db"), &gorm.Config{})
errPanic(err, "failed to connect database")
return db
}
// createTodo creates todo entry in the database.
func createTodo(desc string, date string, comp bool) {
db := openDB()
err := db.AutoMigrate(&Todo{})
errPanic(err, "failed to migrate database")
d := parseDateString(date)
t := Todo{Desc: desc, DueDate: d, CreatedAt: time.Now(), IsDone: comp}
db.Create(&t)
}
// updateTodo updates an entry of id todo in the database.
func updateTodo(id uint64, desc string, date string, comp bool) {
db := openDB()
var t Todo
res := db.First(&t, id)
errPanic(res.Error, "failed to find id")
if desc != "" {
t.Desc = desc
}
if date != "" {
d := parseDateString(date)
t.DueDate = d
}
if comp {
t.IsDone = !t.IsDone
}
db.Model(&t).Updates(t)
}
// deleteTodo deletes an entry of id todo in the database.
func deleteTodo(ids []uint64) {
db := openDB()
for _, id := range ids {
db.Delete(&Todo{}, id)
}
}
// getAllTodos return all todos from the database.
func getAllTodos() []Todo {
db := openDB()
var todos []Todo
res := db.Find(&todos)
errPanic(res.Error, "failed to get all todos")
return todos
}
// getDoneTodos returns all completed todos.
func getDoneTodos() []Todo {
db := openDB()
var todos []Todo
res := db.Where(&Todo{IsDone: true}).Find(&todos)
errPanic(res.Error, "failed to get all todos")
return todos
}
// getDoneTodos returns all uncompleted todos.
func getUnDoneTodos() []Todo {
db := openDB()
var todos []Todo
res := db.Where("is_done = ?", false).Find(&todos)
errPanic(res.Error, "failed to get all todos")
return todos
}