func vkvKeysHandler(db *vkv.DB) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": q := r.URL.Query() end := q.Get("end") if end == "" { end = "\xff" } limit := 0 if q.Get("limit") != "" { ilimit, err := strconv.Atoi(q.Get("limit")) if err != nil { http.Error(w, "bad limit", 500) } limit = ilimit } res, err := db.Keys(q.Get("start"), end, limit) if err != nil { panic(err) } httputil.WriteJSON(w, map[string]interface{}{"keys": res}) return default: w.WriteHeader(http.StatusMethodNotAllowed) } } }
func vkvVersionsHandler(db *vkv.DB) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": // TODO handle start/end/limit vars := mux.Vars(r) res, err := db.Versions(vars["key"], 0, int(time.Now().UTC().UnixNano()), 0) if err != nil { panic(err) } httputil.WriteJSON(w, res) return default: w.WriteHeader(http.StatusMethodNotAllowed) } } }
func vkvHandler(wg sync.WaitGroup, db *vkv.DB, kvUpdate chan *vkv.KeyValue, blobrouter *router.Router) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) switch r.Method { case "GET": iversion := -1 version := r.URL.Query().Get("version") if version != "" { iver, err := strconv.Atoi(version) if err != nil { panic(err) } iversion = iver } res, err := db.Get(vars["key"], iversion) if err != nil { if err == vkv.ErrNotFound { http.Error(w, http.StatusText(404), 404) return } panic(err) } httputil.WriteJSON(w, res) case "HEAD": exists, err := db.Check(vars["key"]) if err != nil { panic(err) } if exists { return } http.Error(w, http.StatusText(404), 404) return case "DELETE": k := vars["key"] sversion := r.URL.Query().Get("version") if sversion == "" { http.Error(w, "version missing", 500) return } version, err := strconv.Atoi(sversion) if err != nil { http.Error(w, "bad version", 500) return } hash, err := db.MetaBlob(k, version) if err != nil { panic(err) } if err := db.DeleteVersion(k, version); err != nil { panic(err) } req := &router.Request{ Type: router.Read, MetaBlob: true, } if err := blobrouter.Route(req).Delete(hash); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } case "PUT": wg.Add(1) defer wg.Done() k := vars["key"] hah, err := ioutil.ReadAll(r.Body) values, err := url.ParseQuery(string(hah)) if err != nil { panic(err) } v := values.Get("value") sversion := values.Get("version") version := -1 if sversion != "" { iversion, err := strconv.Atoi(sversion) if err != nil { http.Error(w, "bad version", 500) return } version = iversion } res, err := db.Put(k, v, version) // FIXME(tsileo): handle namespace in embeded client too res.SetNamespace(values.Get("ns")) if err != nil { panic(err) } kvUpdate <- res httputil.WriteJSON(w, res) default: w.WriteHeader(http.StatusMethodNotAllowed) } } }