250 lines
5.1 KiB
Go
250 lines
5.1 KiB
Go
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)
|
|
}
|