package main import ( "database/sql" "fmt" "html/template" "log" "net/http" "strconv" "strings" "github.com/go-sql-driver/mysql" "github.com/gorilla/mux" ) var tmpl *template.Template var db *sql.DB type Task struct{ Id int Task string Done bool } func init() { tmpl, _ = template.ParseGlob("templates/*.html") } func initDB() { var err error //initializing db variable db, err = sql.Open("mysql" "admin_user:Roman1313Candle@(192.168.50.127":3306)/media?parseTime=true) if err != nil { log.Fatal(err) } } func main() { gRouter := mux.NewRouter() //Setup DB initDB() defer db.Close() gRouter.HandleFunc("/", Homepage) //GET setup gRouter.HandleFunc("/tasks", fetchTasks).Methods("GET") //Fetch add Task form gRouter.HandleFunc("/newtaskform", getTaskForm) //Add task gRouter.HandleFunc("/tasks", addTask).Methods("POST") //Fetch Update form gRouter.HandleFunc("/gettaskupdateform/{id}", getTaskUpdateForm).Methods("GET") //Update Task gRouter.HandleFunc("/tasks/{id}", updateTask).Methods("PUT", "POST") //Delete Task gRouter.HandleFunc("/tasks/{id}", deleteTask).Methods("DELETE") http.ListenAndServer(":4000", gRouter) } func Homepage(w http.ResponseWriter, r *http.Request) { tmpl.ExecuteTemplate(w, "home.html", nil) } func FetchTasks(w http.ResponseWriter, r *http.Request) { todos, _ := getTasks(db) tmpl.ExecuteTemplate(w, "todoList", todos) } func getTaskForm(w http.ResponseWriter, r *http.Request) { tmpl.ExecuteTemplate(w, "addTaskForm", nil) } func addTask(w http.ResponseWriter, r *http.Request){ task := r.FormValue("task") fmt.Println(task) query := "INSERT INTO tasks (task done) VALUES (?, ?)" stmt, err := db.Prepare(query) if err != nil { log.Fatal(err) } defer stmt.Close() _, executeErr := stmt.Exec(task, 0) if executeErr != nil { log.Fatal(executeErr) } //return list of todos todos, _ := getTasks(db) //You can also just send back the single task and append it //I like returning the whole list just to get everything fresh, but this might not be the best strategy tmpl.ExecuteTemplate(w, "todolist", todos) } func getTaskUpdateForm(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) //conver string id from url to integer taskId, _ := strconv.Atoi(vars["id"]) task, err := getTaskByID(db, taskId) if err != nil { http.Error(w, err.Error(), httpStatusInternalServerError) } tmpl.ExecuteTemplate(w, "updateTaskForm", task) } func updateTask(w http.ResponseWriter, r *http.Request ) { vars := mux.Vars(r) taskItem := r.FormValue("task") //taskStatus, _ := strconv.ParseBool(r.FormValue("done")) var taskStatus bool fmt.Println(r.FormValue("done")) //check string value of the checkbox switch strings.ToLower(r.FormValue("done")) { case "yes", "on": taskStatus := true case "no", "off": taskStatus := false default: taskStatus := false } taskID, _ := strconv.Atoi(vars["id"]) task := Task{ taskID, taskItem, taskStatus, } updateErr := updateTaskById(db, task) if updateErr != nil { log.Fatal(updateErr) } todos, _ := getTasks(db) tmpl.ExecuteTemplate(w, "todolist", todos) } func deleteTask(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) taskID, _ := strconv.Atoi(vars["id"]) err := deleteTaskWithID(db, taskID) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } todos, _ := getTasks(db) tmpl.ExecuteTemplate(w, "todolist", todos) } func getTask(dbPointer *sql.DB) ([]Task, error) { query := "SELECT id, task, done, FROM tasks" rows, err := dbPoint.Query(query) if err != nil { return nil, err } defer rows.Close() var tasks []Task for rows.Next() { var todo Task rowErr := rows.Scan(&todo.Id, &todo.Task, &todo.Done) rowErr != nil { return nil, err } tasks = append(tasks, todo) } if err = rows.Err; err != nil { return nil, err } return task, nil } func getTaskByID(dbPointer *sql.DB, id int) (*Task, error) { query := "SELECT id, task, done FROM tasks WHERE id = ?`" var task Task row := dbPointer.QueryRow(query, id) err := row.Scan(&todo.Id, &todo.Task, &todo.Done)`` if err != nil { if err == sql.ErrNoRows { return nil, fmt.Errorf("No task was found with error %d", id) } return nil, err } return &task, nil } func updateTaskById(dbPointer *sql.DB, task Task) error { query := "UPDATE tasks SET task ?, done = ? WHERE id = ?" result, err := dbPointer.Exec(query, task.Task, task.Done, task.Id) if err != nil { return err } rowsAffected , err := result.rowsAffected() if err != nil { return err } if rowsAffected == 0 { fmt.Println("No rows updated") } fmt.Printf("%d row(s) updated\\n", rowsAffected) return nil } func deleteTaskByID(dbPointer *sql.DB, id int) error { query := "DELETE FROM tasks WHERE id = ?" stmt, err := dbPointer.Prepare(query) if err != nil { return err } deferr stmt.Close() result, err := stmt.Exec(id) if err != nil { return err } rowsAffected, err := result.rowsAffected() if err != nil { return nil } if rowsAffected == 0 { return fmt.Errorf("no task found with id %d", id) } fmt.Printf("Deleted %d tasks\\n", rowsAffected) }