Permalink
Browse files

add code that uses another dep : github.com/boltdb/bolt

  • Loading branch information...
freeformz committed Feb 4, 2017
1 parent 259b580 commit fa297a98fa5256b63404671494ecfca557a60d1b
Showing with 188 additions and 0 deletions.
  1. +12 −0 main.go
  2. +84 −0 math/handler.go
  3. +92 −0 math/math.go
View
12 main.go
@@ -3,12 +3,24 @@ package main
import (
"net/http"
"os"
+ "time"
+ "github.com/boltdb/bolt"
+ "github.com/freeformz/depExample/maths"
"github.com/gorilla/mux"
)
func main() {
+ db, err := bolt.Open("maths.db", 0600, &bolt.Options{Timeout: 1 * time.Second})
+ if err != nil {
+ panic(err)
+ }
+ c := maths.Calc{DB: db}
+ h := maths.Handler{Calculator: &c}
+
r := mux.NewRouter()
r.Handle("/", http.FileServer(http.Dir(".")))
+ r.Handle("/maths/{op}/{key}", &h)
+ r.Handle("/maths/{op}/{key}/{value}", &h)
http.ListenAndServe(":"+os.Getenv("PORT"), r)
}
View
@@ -0,0 +1,84 @@
+package math
+
+import (
+ "io"
+ "net/http"
+ "strconv"
+
+ "fmt"
+
+ "github.com/gorilla/mux"
+)
+
+const (
+ errorHeader = "Error"
+)
+
+// Handler for http requests
+type Handler struct {
+ Calculator *Calc
+}
+
+func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ header := w.Header()
+
+ if r.Method != "POST" {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+
+ o, ok := vars["op"]
+ if !ok {
+ header.Add(errorHeader, "op missing")
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ op := operation(o)
+
+ key, ok := vars["key"]
+ if !ok {
+ header.Add(errorHeader, "key missing")
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ var val, sum int
+ var err error
+ switch op {
+ case add, subtract:
+ vs, ok := vars["value"]
+ if !ok {
+ header.Add(errorHeader, "value missing")
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ val, err = strconv.Atoi(vs)
+ if err != nil {
+ header.Add(errorHeader, "error converting value: "+err.Error())
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ switch op {
+ case add:
+ sum, err = h.Calculator.Add(val, key)
+ case subtract:
+ sum, err = h.Calculator.Subtract(val, key)
+ }
+ case value:
+ sum, err = h.Calculator.Value(key)
+ default:
+ header.Add(errorHeader, "unknown op: "+string(op))
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ if err != nil {
+ header.Add(errorHeader, "processing error: "+err.Error())
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+
+ io.WriteString(w, fmt.Sprintf("%s %s %d %d", op, key, val, sum))
+}
View
@@ -0,0 +1,92 @@
+package math
+
+import (
+ "fmt"
+ "strconv"
+
+ "github.com/boltdb/bolt"
+)
+
+type operation string
+
+const (
+ add operation = "add"
+ subtract operation = "subtract"
+ value operation = "value"
+)
+
+// Calc / store the named variables
+type Calc struct {
+ DB *bolt.DB
+}
+
+var (
+ valueKey = []byte("value")
+)
+
+// Add i to the key
+func (c *Calc) Add(i int, key string) (v int, err error) {
+ err = c.DB.Update(func(tx *bolt.Tx) error {
+ v, err = transactionOp(tx, i, key, add)
+ return err
+ })
+ return
+}
+
+// Subtract i from the key
+func (c *Calc) Subtract(i int, key string) (v int, err error) {
+ err = c.DB.Update(func(tx *bolt.Tx) error {
+ v, err = transactionOp(tx, i, key, subtract)
+ return err
+ })
+ return
+}
+
+// Value of the key
+func (c *Calc) Value(key string) (v int, err error) {
+ err = c.DB.View(func(tx *bolt.Tx) error {
+ v, err = transactionOp(tx, 0, key, value)
+ return err
+ })
+ return
+}
+
+func transactionOp(tx *bolt.Tx, i int, key string, op operation) (int, error) {
+ k := []byte(key)
+ var b *bolt.Bucket
+ var err error
+ switch op {
+ case value:
+ b = tx.Bucket(k)
+ default:
+ b, err = tx.CreateBucketIfNotExists(k)
+ }
+ if err != nil {
+ return 0, err
+ }
+ var rv []byte
+ if b != nil {
+ rv = b.Get(valueKey)
+ }
+ var v int
+ switch len(rv) {
+ case 0: // zero value
+ default:
+ v, err = strconv.Atoi(string(rv))
+ }
+ if err != nil {
+ return 0, err
+ }
+ switch op {
+ case add:
+ v += i
+ return v, b.Put(valueKey, []byte(strconv.Itoa(v)))
+ case subtract:
+ v -= i
+ return v, b.Put(valueKey, []byte(strconv.Itoa(v)))
+ case value:
+ return v, nil
+ default:
+ return v, fmt.Errorf("unknown operation: %s", op)
+ }
+}

0 comments on commit fa297a9

Please sign in to comment.