package main import ( "database/sql" _ "github.com/mattn/go-sqlite3" "todo/models" ) type DatabaseInterface interface { GetTodos() ([]models.Todo, error) GetTodo(int) (models.Todo, error) CreateTodo(models.Todo) error DoTodo(int) error UndoTodo(int) error DeleteTodo(int) error } type DatabaseStore struct { DB *sql.DB } func MustNewDB() *DatabaseStore { db, err := sql.Open("sqlite3", "./database.sqlite") if err != nil { panic(err) } err = db.Ping() if err != nil { panic(err) } return &DatabaseStore{db} } func (store *DatabaseStore) GetTodos() ([]models.Todo, error) { selectAll := `select id, todo, done from todo` rows, err := store.DB.Query(selectAll) if err != nil { return []models.Todo{}, err } defer rows.Close() todos := []models.Todo{} for rows.Next() { todo := models.Todo{} err = rows.Scan(&todo.Id, &todo.Todo, &todo.Done) if err != nil { return []models.Todo{}, err } todos = append(todos, todo) } return todos, nil } func (store *DatabaseStore) GetTodo(id int) (models.Todo, error) { selectOne := `select id, todo, done from todo where id = ?` var todo models.Todo err := store.DB.QueryRow(selectOne, id).Scan(&todo.Id, &todo.Todo, &todo.Done) if err != nil { return models.Todo{}, err } return todo, nil } func (store *DatabaseStore) CreateTodo(todo models.Todo) error { createTodo := `insert into todo (todo, done) values (?, ?)` statement, err := store.DB.Prepare(createTodo) if err != nil { return err } defer statement.Close() _, err = statement.Exec(todo.Todo, false) if err != nil { return err } return nil } func (store *DatabaseStore) ToggleTodo(id int) error { todo, err := store.GetTodo(id) if err != nil { return err } setDone := `update todo set done = ? where id = ?` statement, err := store.DB.Prepare(setDone) if err != nil { return err } defer statement.Close() _, err = statement.Exec(!todo.Done, id) if err != nil { return err } return nil } func (store *DatabaseStore) UpdateTodo(todo models.Todo) error { updateTodo := `update todo set todo = ? where id = ?` statement, err := store.DB.Prepare(updateTodo) if err != nil { return err } defer statement.Close() _, err = statement.Exec(todo.Todo, todo.Id) if err != nil { return err } return nil } func (store *DatabaseStore) DeleteTodo(id int) error { deleteTodo := `delete from todo where id = ?` statement, err := store.DB.Prepare(deleteTodo) if err != nil { return err } defer statement.Close() _, err = statement.Exec(id) if err != nil { return err } return nil }