An Example

Expected output:

open your task.db file in sqlite3 like this sql [Tasks] $ sqlite3 task.db sqlite> select title from task limit 1; Publish on github Now this output should match with the one we see at localhost:8080

After running the file, go to localhost:8080 and localhost:8080/add

file ~/main/main.go

  1 package main
  2 
  3 import (
  4 	"database/sql"
  5 	"fmt"
  6 	"log"
  7 	"net/http"
  8 	"time"
  9 
 10 	_ "github.com/mattn/go-sqlite3"
 11 )
 12 
 13 var database *sql.DB
 14 var err error
 15 
 16 //Task is the struct used to identify tasks
 17 type Task struct {
 18 	Id      int
 19 	Title   string
 20 	Content string
 21 	Created string
 22 }
 23 
 24 //Context is the struct passed to templates
 25 type Context struct {
 26 	Tasks      []Task
 27 	Navigation string
 28 	Search     string
 29 	Message    string
 30 }
 31 
 32 func init() {
 33 	database, err = sql.Open("sqlite3", "./tasks.db")
 34 	if err != nil {
 35 		fmt.Println(err)
 36 	}
 37 }
 38 
 39 func main() {
 40 	http.HandleFunc("/", ShowAllTasksFunc)
 41 	http.HandleFunc("/add/", AddTaskFunc)
 42 	fmt.Println("running on 8080")
 43 	log.Fatal(http.ListenAndServe(":8080", nil))
 44 }
 45 
 46 //ShowAllTasksFunc is used to handle the "/" URL which is the default one
 47 func ShowAllTasksFunc(w http.ResponseWriter, r *http.Request) {
 48 	if r.Method == "GET" {
 49 		context := GetTasks() //true when you want non deleted notes
 50 		w.Write([]byte(context.Tasks[0].Title))
 51 	} else {
 52 		http.Redirect(w, r, "/", http.StatusFound)
 53 	}
 54 }
 55 
 56 func GetTasks() Context {
 57 	var task []Task
 58 	var context Context
 59 	var TaskID int
 60 	var TaskTitle string
 61 	var TaskContent string
 62 	var TaskCreated time.Time
 63 	var getTasksql string
 64 
 65 	getTasksql = "select id, title, content, created_date from task;"
 66 
 67 	rows, err := database.Query(getTasksql)
 68 	if err != nil {
 69 		fmt.Println(err)
 70 	}
 71 	defer rows.Close()
 72 	for rows.Next() {
 73 		err := rows.Scan(&TaskID, &TaskTitle, &TaskContent, &TaskCreated)
 74 		if err != nil {
 75 			fmt.Println(err)
 76 		}
 77 		TaskCreated = TaskCreated.Local()
 78 		a := Task{Id: TaskID, Title: TaskTitle, Content: TaskContent,
 79 			Created: TaskCreated.Format(time.UnixDate)[0:20]}
 80 		task = append(task, a)
 81 	}
 82 	context = Context{Tasks: task}
 83 	return context
 84 }
 85 
 86 //AddTaskFunc is used to handle the addition of new task, "/add" URL
 87 func AddTaskFunc(w http.ResponseWriter, r *http.Request) {
 88 	title := "random title"
 89 	content := "random content"
 90 	truth := AddTask(title, content)
 91 	if truth != nil {
 92 		log.Fatal("Error adding task")
 93 	}
 94 	w.Write([]byte("Added task"))
 95 }
 96 
 97 //AddTask is used to add the task in the database
 98 func AddTask(title, content string) error {
 99 	query:="insert into task(title, content, created_date, last_modified_at)\ 
100 	values(?,?,datetime(), datetime())"
101 	restoreSQL, err := database.Prepare(query)
102 	if err != nil {
103 		fmt.Println(err)
104 	}
105 	tx, err := database.Begin()
106 	_, err = tx.Stmt(restoreSQL).Exec(title, content)
107 	if err != nil {
108 		fmt.Println(err)
109 		tx.Rollback()
110 	} else {
111 		log.Print("insert successful")
112 		tx.Commit()
113 	}
114 	return err
115 }

Homework

The homework is to split the code into packages and get it to work, the type definition goes into the types/types.go file, the handler definition goes into the views/views.go, the database read and write methods go into the db/db.go. Make sure that after you refactor the code, that the code runs.

-Previous section -Next section