Add namespacing for users

master
Bel LaPointe 2020-07-22 22:20:06 -06:00
parent 1a6973b02c
commit 660cd64262
5 changed files with 45 additions and 37 deletions

View File

@ -19,9 +19,9 @@ func NewGraph() Graph {
} }
} }
func (g Graph) List(ctx context.Context, from ...string) ([]entity.One, error) { func (g Graph) List(ctx context.Context, namespace string, from ...string) ([]entity.One, error) {
filter := operator.NewFilterIn("_id", from) filter := operator.NewFilterIn("_id", from)
ch, err := g.mongo.Find(ctx, filter) ch, err := g.mongo.Find(ctx, namespace, filter)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -36,14 +36,14 @@ func (g Graph) List(ctx context.Context, from ...string) ([]entity.One, error) {
return ones, nil return ones, nil
} }
func (g Graph) Insert(ctx context.Context, one entity.One) error { func (g Graph) Insert(ctx context.Context, namespace string, one entity.One) error {
return g.mongo.Insert(ctx, one) return g.mongo.Insert(ctx, namespace, one)
} }
func (g Graph) Update(ctx context.Context, one entity.One, modify interface{}) error { func (g Graph) Update(ctx context.Context, namespace string, one entity.One, modify interface{}) error {
return g.mongo.Update(ctx, one, modify) return g.mongo.Update(ctx, namespace, one, modify)
} }
func (g Graph) Delete(ctx context.Context, filter interface{}) error { func (g Graph) Delete(ctx context.Context, namespace string, filter interface{}) error {
return g.mongo.Delete(ctx, filter) return g.mongo.Delete(ctx, namespace, filter)
} }

View File

@ -21,11 +21,10 @@ func TestIntegration(t *testing.T) {
os.Args = os.Args[:1] os.Args = os.Args[:1]
graph := NewGraph() graph := NewGraph()
graph.mongo.db = "test-db" graph.mongo.db = "test-db"
graph.mongo.col = "test-col"
ctx, can := context.WithCancel(context.TODO()) ctx, can := context.WithCancel(context.TODO())
defer can() defer can()
clean := func() { clean := func() {
graph.mongo.client.Database(graph.mongo.db).Collection(graph.mongo.col).DeleteMany(ctx, map[string]interface{}{}) graph.mongo.client.Database(graph.mongo.db).Collection("col").DeleteMany(ctx, map[string]interface{}{})
} }
clean() clean()
defer clean() defer clean()
@ -39,7 +38,7 @@ func TestIntegration(t *testing.T) {
t.Run("graph.Insert(...)", func(t *testing.T) { t.Run("graph.Insert(...)", func(t *testing.T) {
for _, one := range ones { for _, one := range ones {
err := graph.Insert(ctx, one) err := graph.Insert(ctx, "col", one)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -47,7 +46,7 @@ func TestIntegration(t *testing.T) {
}) })
t.Run("graph.List", func(t *testing.T) { t.Run("graph.List", func(t *testing.T) {
all, err := graph.List(ctx) all, err := graph.List(ctx, "col")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -58,7 +57,7 @@ func TestIntegration(t *testing.T) {
}) })
t.Run("graph.List(foo => *)", func(t *testing.T) { t.Run("graph.List(foo => *)", func(t *testing.T) {
some, err := graph.List(ctx, ones[0].Peers()...) some, err := graph.List(ctx, "col", ones[0].Peers()...)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -69,12 +68,12 @@ func TestIntegration(t *testing.T) {
}) })
t.Run("graph.Update(foo, --bar)", func(t *testing.T) { t.Run("graph.Update(foo, --bar)", func(t *testing.T) {
err := graph.Update(ctx, ones[0].Query(), operator.Set{entity.Connections, map[string]interface{}{}}) err := graph.Update(ctx, "col", ones[0].Query(), operator.Set{entity.Connections, map[string]interface{}{}})
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
some, err := graph.List(ctx, ones[0].Name) some, err := graph.List(ctx, "col", ones[0].Name)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -92,7 +91,7 @@ func TestIntegration(t *testing.T) {
}) })
t.Run("graph.Update(foo, +=2); graph.Update(foo, -=1)", func(t *testing.T) { t.Run("graph.Update(foo, +=2); graph.Update(foo, -=1)", func(t *testing.T) {
err := graph.Update(ctx, ones[0].Query(), operator.Set{entity.Connections, map[string]entity.One{ err := graph.Update(ctx, "col", ones[0].Query(), operator.Set{entity.Connections, map[string]entity.One{
"hello": entity.One{Name: "hello", Relationship: ":("}, "hello": entity.One{Name: "hello", Relationship: ":("},
"world": entity.One{Name: "world", Relationship: ":("}, "world": entity.One{Name: "world", Relationship: ":("},
}}) }})
@ -100,7 +99,7 @@ func TestIntegration(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
some1, err := graph.List(ctx, ones[0].Name) some1, err := graph.List(ctx, "col", ones[0].Name)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -112,11 +111,11 @@ func TestIntegration(t *testing.T) {
t.Fatal(some1[0].Peers()) t.Fatal(some1[0].Peers())
} }
err = graph.Update(ctx, ones[0].Query(), operator.Unset(fmt.Sprintf("%s.world", entity.Connections))) err = graph.Update(ctx, "col", ones[0].Query(), operator.Unset(fmt.Sprintf("%s.world", entity.Connections)))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
some2, err := graph.List(ctx, ones[0].Name) some2, err := graph.List(ctx, "col", ones[0].Name)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -15,7 +15,6 @@ import (
type Mongo struct { type Mongo struct {
client *mongo.Client client *mongo.Client
db string db string
col string
} }
func NewMongo() Mongo { func NewMongo() Mongo {
@ -35,12 +34,11 @@ func NewMongo() Mongo {
return Mongo{ return Mongo{
client: c, client: c,
db: config.New().Database, db: config.New().Database,
col: "col",
} }
} }
func (m Mongo) Find(ctx context.Context, filter interface{}) (chan bson.Raw, error) { func (m Mongo) Find(ctx context.Context, namespace string, filter interface{}) (chan bson.Raw, error) {
c := m.client.Database(m.db).Collection(m.col) c := m.client.Database(m.db).Collection(namespace)
cursor, err := c.Find(ctx, filter) cursor, err := c.Find(ctx, filter)
if err != nil { if err != nil {
return nil, err return nil, err
@ -60,13 +58,13 @@ func (m Mongo) page(ctx context.Context, cursor *mongo.Cursor) chan bson.Raw {
return ch return ch
} }
func (m Mongo) Update(ctx context.Context, filter, apply interface{}) error { func (m Mongo) Update(ctx context.Context, namespace string, filter, apply interface{}) error {
c := m.client.Database(m.db).Collection(m.col) c := m.client.Database(m.db).Collection(namespace)
_, err := c.UpdateOne(ctx, filter, apply) _, err := c.UpdateOne(ctx, filter, apply)
return err return err
} }
func (m Mongo) Insert(ctx context.Context, apply interface{}) error { func (m Mongo) Insert(ctx context.Context, namespace string, apply interface{}) error {
b, err := bson.Marshal(apply) b, err := bson.Marshal(apply)
if err != nil { if err != nil {
return err return err
@ -80,13 +78,13 @@ func (m Mongo) Insert(ctx context.Context, apply interface{}) error {
} else if _, ok := mapp["_id"].(string); !ok { } else if _, ok := mapp["_id"].(string); !ok {
return errors.New("non-string _id in new object") return errors.New("non-string _id in new object")
} }
c := m.client.Database(m.db).Collection(m.col) c := m.client.Database(m.db).Collection(namespace)
_, err = c.InsertOne(ctx, apply) _, err = c.InsertOne(ctx, apply)
return err return err
} }
func (m Mongo) Delete(ctx context.Context, filter interface{}) error { func (m Mongo) Delete(ctx context.Context, namespace string, filter interface{}) error {
c := m.client.Database(m.db).Collection(m.col) c := m.client.Database(m.db).Collection(namespace)
_, err := c.DeleteOne(ctx, filter) _, err := c.DeleteOne(ctx, filter)
return err return err
} }

View File

@ -8,6 +8,8 @@ import (
"local/dndex/storage/entity" "local/dndex/storage/entity"
"log" "log"
"net/http" "net/http"
"path"
"strings"
) )
func Html(g storage.Graph) error { func Html(g storage.Graph) error {
@ -20,8 +22,8 @@ func Html(g storage.Graph) error {
func foo(g storage.Graph) http.Handler { func foo(g storage.Graph) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var err error var err error
switch r.URL.Path { switch path.Base(r.URL.Path) {
case "/who": case "who":
err = who(g, w, r) err = who(g, w, r)
default: default:
http.NotFound(w, r) http.NotFound(w, r)
@ -34,12 +36,18 @@ func foo(g storage.Graph) http.Handler {
} }
func who(g storage.Graph, w http.ResponseWriter, r *http.Request) error { func who(g storage.Graph, w http.ResponseWriter, r *http.Request) error {
namespace := path.Dir(r.URL.Path)
if len(namespace) < 2 {
http.NotFound(w, r)
return nil
}
namespace = strings.Replace(namespace[1:], "/", ".", -1)
ids := r.URL.Query()["id"] ids := r.URL.Query()["id"]
_, verbose := r.URL.Query()["v"] _, verbose := r.URL.Query()["v"]
results := make(map[string]entity.One) results := make(map[string]entity.One)
for i := 0; i < len(ids); i++ { for i := 0; i < len(ids); i++ {
id := ids[i] id := ids[i]
ones, err := g.List(r.Context(), id) ones, err := g.List(r.Context(), namespace, id)
if err != nil { if err != nil {
return err return err
} }
@ -48,7 +56,7 @@ func who(g storage.Graph, w http.ResponseWriter, r *http.Request) error {
} }
one := ones[0] one := ones[0]
if verbose { if verbose {
ones, err := g.List(r.Context(), one.Peers()...) ones, err := g.List(r.Context(), namespace, one.Peers()...)
if err != nil { if err != nil {
return err return err
} }

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"local/dndex/config" "local/dndex/config"
"local/dndex/storage" "local/dndex/storage"
"local/dndex/storage/entity" "local/dndex/storage/entity"
@ -33,14 +34,16 @@ func TestHtml(t *testing.T) {
} }
}() }()
time.Sleep(time.Millisecond * 250) time.Sleep(time.Millisecond * 250)
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/who?id=%s&v", config.New().Port, want.Name)) resp, err := http.Get(fmt.Sprintf("http://localhost:%d/col/who?id=%s&v", config.New().Port, want.Name))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer resp.Body.Close() defer resp.Body.Close()
var v interface{} var v interface{}
if err := json.NewDecoder(resp.Body).Decode(&v); err != nil { if b, err := ioutil.ReadAll(resp.Body); err != nil {
t.Fatal(err) t.Fatal(err)
} else if err := json.Unmarshal(b, &v); err != nil {
t.Fatalf("err unmarshalling response: %v: %s", err, b)
} }
b, err := json.MarshalIndent(v, "", " ") b, err := json.MarshalIndent(v, "", " ")
if err != nil { if err != nil {
@ -101,10 +104,10 @@ func fillDB(t *testing.T, g storage.Graph) []entity.One {
} }
} }
for i := range ones { for i := range ones {
if err := g.Insert(context.TODO(), ones[i]); err != nil { if err := g.Insert(context.TODO(), "col", ones[i]); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if results, err := g.List(context.TODO(), ones[i].Name); err != nil { if results, err := g.List(context.TODO(), "col", ones[i].Name); err != nil {
t.Fatal(err) t.Fatal(err)
} else if len(results) != 1 { } else if len(results) != 1 {
t.Fatal(len(results)) t.Fatal(len(results))