-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
130 lines (103 loc) · 2.85 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"encoding/json"
"log"
"net/http"
"time"
"gopkg.in/mgo.v2/bson"
"github.com/gorilla/context"
"gopkg.in/mgo.v2"
"fmt"
)
func main() {
// connect to the database
db, err := mgo.Dial("127.0.0.1:27017")
if err != nil {
log.Fatal("cannot dial mongo", err)
}else {
fmt.Println("dial mongo good")
}
defer db.Close() // clean up when we're done
// Adapt our handle function using withDB
h := Adapt(http.HandlerFunc(handle), withDB(db))
// add the handler
http.Handle("/comments", context.ClearHandler(h))
fmt.Println("end")
// start the server
if err := http.ListenAndServe(":27017", nil); err != nil {
log.Fatal(err)
fmt.Println("end")
}
}
type Adapter func(http.Handler) http.Handler
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
for _, adapter := range adapters {
h = adapter(h)
}
return h
}
func handle(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
handleRead(w, r)
case "POST":
handleInsert(w, r)
default:
http.Error(w, "Not supported", http.StatusMethodNotAllowed)
}
}
type comment struct {
ID bson.ObjectId `json:"id" bson:"_id"`
Author string `json:"author" bson:"author"`
Text string `json:"text" bson:"text"`
When time.Time `json:"when" bson:"when"`
}
func handleInsert(w http.ResponseWriter, r *http.Request) {
db := context.Get(r, "database").(*mgo.Session)
// decode the request body
var c comment
if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// give the comment a unique ID
c.ID = bson.NewObjectId()
c.When = time.Now()
// insert it into the database
if err := db.DB("commentsapp").C("comments").Insert(&c); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// redirect to it
http.Redirect(w, r, "/comments/"+c.ID.Hex(), http.StatusTemporaryRedirect)
}
func handleRead(w http.ResponseWriter, r *http.Request) {
db := context.Get(r, "database").(*mgo.Session)
// load the comments
var comments []*comment
if err := db.DB("commentsapp").C("comments").
Find(nil).Sort("-when").Limit(100).All(&comments); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// write it out
if err := json.NewEncoder(w).Encode(comments); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
func withDB(db *mgo.Session) Adapter {
// return the Adapter
return func(h http.Handler) http.Handler {
// the adapter (when called) should return a new handler
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// copy the database session
dbsession := db.Copy()
defer dbsession.Close() // clean up
// save it in the mux context
context.Set(r, "database", dbsession)
// pass execution to the original handler
h.ServeHTTP(w, r)
})
}
}