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 }