You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
2.1 KiB

2 years ago
package database
import (
"database/sql"
"log"
_ "modernc.org/sqlite"
)
type DB struct {
db *sql.DB
}
func New() *DB {
d := &DB{}
con, err := sql.Open("sqlite", "./todogo.db")
if err != nil {
log.Fatal(err)
}
d.db = con
err = d.init()
if err != nil {
log.Fatal(err)
}
return d
}
func (d *DB) init() error {
d.migrate()
return nil
}
func (d *DB) InsertTodo(title string) error {
_, err := d.db.Exec("INSERT INTO todos(title, completed) VALUES(?, ?)", title, 0)
return err
}
func (d *DB) ToggleTodo(id int) error {
_, err := d.db.Exec(`
UPDATE todos
SET completed = (CASE WHEN completed = 0 THEN 1 ELSE 0 END)
WHERE id = ?
`, id)
return err
}
func (d *DB) DeleteTodo(id int) error {
_, err := d.db.Exec("DELETE FROM todos WHERE id = ?", id)
return err
}
func (d *DB) GetAllTodos() ([]*Todo, error) {
rows, err := d.db.Query("SELECT id, title, completed FROM todos")
if err != nil {
return nil, err
}
defer rows.Close()
todos := scanTodos(rows)
return todos, nil
}
func (d *DB) GetTodosByCompleted(completed bool) ([]*Todo, error) {
completedInt := 0
if completed {
completedInt = 1
}
rows, err := d.db.Query("SELECT id, title, completed FROM todos WHERE completed = ?", completedInt)
if err != nil {
return nil, err
}
defer rows.Close()
todos := scanTodos(rows)
return todos, nil
}
func (d *DB) GetIncompleteTodosCount() int {
row := d.db.QueryRow("SELECT COUNT(*) FROM todos WHERE completed = 0")
var count int
err := row.Scan(&count)
if err != nil {
log.Printf("failed to get incomplete count")
return 0
}
return count
}
func (d *DB) DeleteCompletedTodos() error {
_, err := d.db.Exec("DELETE FROM todos WHERE completed = 1")
return err
}
func scanTodos(rows *sql.Rows) []*Todo {
var todos []*Todo
for rows.Next() {
t := scanTodo(rows)
if t != nil {
todos = append(todos, t)
}
}
return todos
}
func scanTodo(row *sql.Rows) *Todo {
t := new(Todo)
err := row.Scan(&t.Id, &t.Title, &t.Completed)
if err != nil {
log.Printf("Failed to read row %s", err)
return nil
}
return t
}
type Todo struct {
Id int
Title string
Completed bool
}