This is a creation in Article, where the information may have evolved or changed.
A Todo instance has been written before, and is implemented using the Python Tornado framework. Address: http://blog.csdn.net/luck_apple/article/details/8814091
Recently go update to 1.4 version, just also study to play.
Look for a few days Go foundation, then want to find an example practice practiced hand, think of distress wrote Tornado TODO,
Just take it with go rewrite it again, this time without using the web framework, using the Go Native API implementation.
Go language Basics can read ebook: http://download.csdn.net/detail/luck_apple/8412345 (0 resources)
Go version 1.4, and then look at my go env:
Let's look at the final effect:
OK, that's the way it is.
The last time someone complained that I did not put the database table structure, this time using SQLite database, the table structure is really simple:
CREATE TABLE todo (id integer PRIMARY KEY, titletext not null, FinishbooleannotNULLDEFAULT false)
Then look at the project directory structure:
Although we do not use the MVC Web framework, but also need to have an MVC look, Mode,view and controller should be divided clearly.
The portal is main.go (responsible for creating Web server and Routing):
Package Mainimport ("Log" "Net/http" "Todo/controllers") func main () {//Static resource service HTTP. Handle ("/public/", http. Fileserver (http. Dir ("./")))//route HTTP. Handlefunc ("/new", controllers. Newtodo) http. Handlefunc ("/edit", controllers. Edittodo) http. Handlefunc ("/finish", controllers. Finishtodo) http. Handlefunc ("/delete", controllers. Deletetodo) http. Handlefunc ("/", controllers. Index) Err: = http. Listenandserve (": +", nil) if err! = Nil {log. Fatal ("Listenandserver error:", err)}}
The route defined above will be executed to the corresponding method in the Todocontroller.go
And look at Todocontroller.go:
Package Controllersimport ("Html/template" "Net/http" "StrConv" "Todo/models") Func Index (w http. Responsewriter, R *http. Request) {if R.method! = "GET" {showerror (W, "exception", "illegal request, server not Responding")} else {if R.url. Path = = "/" {todos, err: = models. Queryall () if err! = Nil {showerror (W, "Exception", "Query Exception") return}t, err: = template. Parsefiles ("views/index.html") if err! = Nil {showerror (W, "Exception", "Page Rendering Exception") Return}data: = Make (map[string][]models. Todo) data["todolist"] = todost. Execute (w, data)} else {//404 page, will not be routed to here ShowError (w, "404", "page does not exist")}}}func Newtodo (w http. Responsewriter, R *http. Request) {if R.method! = "POST" {showerror (W, "exception", "Illegal Request")} else {title: = R.formvalue ("title") ID, err: = models. Inserttodo (title) If Err! = Nil | | ID <= 0 {showerror (w, "Exception", "Insert Data exception") return}//redirect to the main interface http. Redirect (W, R, "/", HTTP. Statusseeother)//No return, no effect, redirect not past Return}}func Finishtodo (w http. Responsewriter, R *http. Request) {if R.method! = "GET" {showerror (W, "exception", "Illegal Request")} else {//Get form parameter, can also write//R.parseform ()//id: = r.form["id"]id: = R.formvalue ("id") Finish: = R.formvalue ("Finish")//Formvalue fetch data are string type, convert ID to Int64 type// StrConv. parseint (ID, 10, 64) 10 means 10 binary, 64 means 64 bit IntID, _: = StrConv. parseint (ID, ten, max) Boolfinish, _: = StrConv. Parsebool (Finish) _, Err: = models. Finishtodo (IntId,!boolfinish) if err! = Nil {showerror (W, "Exception", "Complete Todo Failed") return}http. Redirect (W, R, "/", HTTP. Statusseeother) Return}}func Deletetodo (w http. Responsewriter, R *http. Request) {if R.method! = "GET" {showerror (W, "exception", "Illegal Request")} else {id: = R.formvalue ("id") IntId, _: = StrConv. parseint (ID, ten, max) _, Err: = models. Deletetodo (intId) if err! = Nil {showerror (W, "Exception", "Delete failed") return}http. Redirect (W, R, "/", HTTP. Statusseeother) Return}}func Edittodo (w http. Responsewriter, R *http. Request) {if R.method = = "GET" {//Display edit page//The title content can be submitted here, but the URL will be ugly, or the ID is queried by id: = R.formvalue ("id") IntId, _: = Strco Nv. parseint (ID, ten, max) title, Err: = models. Gettodotitle (intId) if err! = Nil {showerror (W, "Exception", "Query Todo content failed") Return}t, _: = Template. Parsefiles ("views/edit.html") Data: = Make (map[string]string) data["Id"] = iddata["Title"] = Titlet. Execute (w, data)} else if R.method = = "POST" {//Edit post submitted to this ID, _: = StrConv. parseint (R.formvalue ("id"), ten, +) title: = R.formvalue ("title") Res, err: = models. Edittodo (ID, title) if Err! = Nil | | Res <= 0 {showerror (w, "Exception", "Modify failed") return}http. Redirect (W, R, "/", HTTP. Statusseeother) return}}//Error handling Func showerror (w http. Responsewriter, title string, message string) {T, _: = template. Parsefiles ("views/error.html") Data: = Make (map[string]string) data["title"] = titledata["message"] = Messaget. Execute (w, data)}
The database uses the Sqlite3 database, using the Github.com/mattn/go-sqlite3 package
Mac users can try an excellent SQLite database management tool: http://download.csdn.net/detail/luck_apple/8436489 (0 resources)
Take a look at our Model,todomodel.go:
Package Modelsimport ("Database/sql" _ "Github.com/mattn/go-sqlite3")//for development convenience, use SQLite database type Todo struct {Id int64titl E stringfinish bool}func Inserttodo (title string) (Int64, error) {///database path is relative path (relative to Main.go) db, err: = SQL. Open ("Sqlite3", "./data/data.db")//function code to close the database after execution, it is a good habit, I love deferdefer db. Close () if err! = nil {return-1, err}stmt, err: = db. Prepare ("INSERT into Todo (title, finish) VALUES (?,?)") Defer stmt. Close () if err! = nil {return-1, err}res, err: = stmt. Exec (title, false) If err! = nil {return-1, Err}return Res. Lastinsertid ()}func Queryall () ([]todo, error) {db, err: = SQL. Open ("Sqlite3", "./data/data.db") defer db. Close () if err! = Nil {return nil, err}rows, err: = db. Query ("select * from Todo") defer rows. Close () if err! = Nil {return nil, err}var todos []todofor rows. Next () {var id int64var title Stringvar finish Boolerr = rows. Scan (&id, &title, &finish) if err! = Nil {return nil, Err}todo: = Todo{id, title, Finish}todos = Append (Todos, TODO)}return Todos,Nil}func Finishtodo (todoid int64, finish bool) (Int64, error) {db, err: = SQL. Open ("Sqlite3", "./data/data.db") defer db. Close () if err! = Nil {return 0, err}stmt, err: = db. Prepare ("UPDATE todo SET finish=?") WHERE id=? ") Defer stmt. Close () if err! = Nil {return 0, nil}res, err: = stmt. Exec (Finish, todoid) if err! = Nil {return 0, nil}affect, err: = Res. Rowsaffected () if err! = Nil {return 0, Nil}return affect, Nil}func Deletetodo (todoid Int64) (int64, error) {db, err: = SQL . Open ("Sqlite3", "./data/data.db") defer db. Close () if err! = Nil {return 0, err}stmt, err: = db. Prepare ("DELETE from Todo WHERE id=?") If err! = Nil {return 0, err}res, err: = stmt. Exec (todoid) if err! = Nil {return 0, nil}affect, err: = Res. Rowsaffected () if err! = Nil {return 0, Nil}return affect, Nil}func gettodotitle (todoid Int64) (string, error) {db, err: = Sql. Open ("Sqlite3", "./data/data.db") defer db. Close () if err! = Nil {return "", err}//queries only one row of data row: = db. Queryrow ("Select title from Todo WHERE id=?", Todoid) var title sTringe: = row. Scan (&title) if E! = nil {return "", E}return title, Nil}func Edittodo (id int64, title string) (Int64, error) {db, err : = SQL. Open ("Sqlite3", "./data/data.db") defer db. Close () if err! = Nil {return 0, err}stmt, err: = db. Prepare ("UPDATE todo SET title=?") WHERE id=? ") Defer stmt. Close () if err! = Nil {return 0, nil}res, err: = stmt. Exec (title, id) if err! = Nil {return 0, nil}affect, err: = Res. Rowsaffected () if err! = Nil {return 0, Nil}return affect, nil}
As for the view, the code is much more, no longer posted out.
Code Download Address: http://download.csdn.net/detail/luck_apple/8436475 (0 resource points)
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.