package main
import (
"database/sql"
"fmt"
"html/template"
"log"
"net/http"
_ "github.com/go-sql-driver/mysql"
)
const dbHost = "mysql-service:3306"
const dbUser = "root"
const dbPassword = "password"
const dbName = "todo"
func main() {
http.HandleFunc("/", todoList)
http.HandleFunc("/save", saveItem)
log.Fatal(http.ListenAndServe(":3000", nil))
}
// Todo represents a single 'todo', or item.
type Todo struct {
ID int
Item string
}
// todoList shows the todo list along with the form to add a new item to the
// list.
func todoList(w http.ResponseWriter, r *http.Request) {
tmpl := `
List of items
Todo list:
{{range $key, $value := .TodoItems}}
- {{ $value.Item }}
{{end}}
`
t, err := template.New("todolist").Parse(tmpl)
if err != nil {
log.Fatal(err)
}
dbc := db()
rows, err := dbc.Query("SELECT * FROM items")
if err != nil {
log.Fatal(err)
}
todos := []Todo{}
for rows.Next() {
todo := Todo{}
err = rows.Scan(&todo.ID, &todo.Item)
todos = append(todos, todo)
}
data := struct {
TodoItems []Todo
}{
TodoItems: todos,
}
t.Execute(w, data)
}
// saveItem saves a new todo item and then redirects the user back to the list
func saveItem(w http.ResponseWriter, r *http.Request) {
dbc := db()
stmt, err := dbc.Prepare("INSERT items SET item=?")
if err != nil {
log.Fatal(err)
}
_, err = stmt.Exec(r.FormValue("item"))
if err != nil {
log.Fatal(err)
}
http.Redirect(w, r, "/", 301)
}
// db creates a connection to the database and creates the items table if it
// does not already exist.
func db() *sql.DB {
connStr := fmt.Sprintf(
"%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
dbUser,
dbPassword,
dbHost,
dbName,
)
db, err := sql.Open("mysql", connStr)
if err != nil {
log.Fatal(err)
}
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS items(
id integer NOT NULL AUTO_INCREMENT,
item varchar(255),
PRIMARY KEY (id)
)`)
return db
}