69 lines
1.3 KiB
Go
69 lines
1.3 KiB
Go
// Package store implements a synchronous in-memory K/V store
|
|
// fronted by an HTTP server.
|
|
package store
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
)
|
|
|
|
type Map struct {
|
|
m sync.Map
|
|
}
|
|
|
|
func New(from map[string]string) *Map {
|
|
var m Map
|
|
for k, v := range from {
|
|
m.Set(k, v)
|
|
}
|
|
return &m
|
|
}
|
|
|
|
func (m *Map) Get(k string) (string, bool) {
|
|
r, ok := m.m.Load(k)
|
|
return r.(string), ok
|
|
}
|
|
|
|
func (m *Map) Set(k, v string) {
|
|
m.m.Store(k, v)
|
|
}
|
|
|
|
func (m *Map) Delete(k string) {
|
|
m.m.Delete(k)
|
|
}
|
|
|
|
func (m *Map) Router() http.Handler {
|
|
r := http.NewServeMux()
|
|
r.HandleFunc("GET /{key}", m.get)
|
|
r.HandleFunc("PUT /{key}", m.set)
|
|
r.HandleFunc("POST /{key}", m.set)
|
|
r.HandleFunc("DELETE /{key}", m.delete)
|
|
return r
|
|
}
|
|
|
|
func (m *Map) get(w http.ResponseWriter, r *http.Request) {
|
|
k := r.PathValue("key")
|
|
v, ok := m.Get(k)
|
|
if !ok {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
}
|
|
io.WriteString(w, v)
|
|
}
|
|
|
|
func (m *Map) set(w http.ResponseWriter, r *http.Request) {
|
|
k := r.PathValue("key")
|
|
b, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
}
|
|
m.Set(k, string(b))
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
func (m *Map) delete(w http.ResponseWriter, r *http.Request) {
|
|
k := r.PathValue("key")
|
|
m.Delete(k)
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|