Skip to content

Instantly share code, notes, and snippets.

@leehambley
Created August 13, 2014 15:49
Show Gist options
  • Save leehambley/759550c626e1f7fc035c to your computer and use it in GitHub Desktop.
Save leehambley/759550c626e1f7fc035c to your computer and use it in GitHub Desktop.
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"strconv"
_ "github.com/lib/pq"
)
const pgSqlDsn = "user=leehambley dbname=tt sslmode=disable"
func main() {
db, err := sql.Open("postgres", pgSqlDsn)
if err != nil {
log.Fatalf("Error opening database handle: %s\n", err)
}
mux := http.NewServeMux()
mux.HandleFunc("/foo", func(w http.ResponseWriter, req *http.Request) {
tx, _ := db.Begin()
defer tx.Commit()
FooHandler{tx: tx}.ServeHTTP(w, req)
})
err = http.ListenAndServe(":3000", mux)
if err != nil {
log.Fatalf("Couldn't start server: %v\n", err)
} else {
log.Println("Listening...")
}
}
type FooHandler struct {
tx *sql.Tx
}
func (self FooHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var widgetName string
widgetIdStr := req.FormValue("id")
widgetId, err := strconv.ParseInt(widgetIdStr, 10, 0)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if len(widgetIdStr) == 0 {
widgetIdStr = "(empty)"
}
fmt.Fprintf(w, "`%s' is not a valid widget ID\n", widgetIdStr)
return
}
// ...
err = self.tx.QueryRow("SELECT name FROM widgets WHERE id = $1", widgetId).Scan(&widgetName)
switch {
case err == sql.ErrNoRows:
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "No widget with ID %d\n", widgetId)
case err != nil:
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, http.StatusText(http.StatusInternalServerError), widgetId)
log.Fatalf("Database Error:", err)
default:
fmt.Fprintf(w, "Widget Name: %s\n", widgetName)
}
}
package main
import (
"database/sql"
"log"
"net/http"
"net/http/httptest"
"testing"
_ "github.com/lib/pq"
)
func Test_FooHandler_200_OK(t *testing.T) {
db, err := sql.Open("postgres", pgSqlDsn)
if err != nil {
log.Fatalf("Error opening database handle: %s\n", err)
}
defer db.Close()
tx, _ := db.Begin()
defer tx.Rollback()
ts := httptest.NewServer(http.Handler(&FooHandler{tx: tx}))
defer ts.Close()
if _, err := tx.Exec("INSERT INTO widgets (id, name) VALUES (123, 'Test Widget')"); err != nil {
t.Fatalf("Failed to insert test widget: %s\n", err)
}
res, err := http.Get(ts.URL + "?id=123")
if err != nil {
log.Fatal(err)
}
if res.StatusCode != http.StatusOK {
t.Fatalf("Expected code %d, got %d\n", http.StatusOK, res.StatusCode)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment