diff --git a/storage/graph.go b/storage/graph.go index 915c942..0f5fd5b 100644 --- a/storage/graph.go +++ b/storage/graph.go @@ -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) - ch, err := g.mongo.Find(ctx, filter) + ch, err := g.mongo.Find(ctx, namespace, filter) if err != nil { return nil, err } @@ -36,14 +36,14 @@ func (g Graph) List(ctx context.Context, from ...string) ([]entity.One, error) { return ones, nil } -func (g Graph) Insert(ctx context.Context, one entity.One) error { - return g.mongo.Insert(ctx, one) +func (g Graph) Insert(ctx context.Context, namespace string, one entity.One) error { + return g.mongo.Insert(ctx, namespace, one) } -func (g Graph) Update(ctx context.Context, one entity.One, modify interface{}) error { - return g.mongo.Update(ctx, one, modify) +func (g Graph) Update(ctx context.Context, namespace string, one entity.One, modify interface{}) error { + return g.mongo.Update(ctx, namespace, one, modify) } -func (g Graph) Delete(ctx context.Context, filter interface{}) error { - return g.mongo.Delete(ctx, filter) +func (g Graph) Delete(ctx context.Context, namespace string, filter interface{}) error { + return g.mongo.Delete(ctx, namespace, filter) } diff --git a/storage/graph_test.go b/storage/graph_test.go index 95fed95..107e36d 100644 --- a/storage/graph_test.go +++ b/storage/graph_test.go @@ -21,11 +21,10 @@ func TestIntegration(t *testing.T) { os.Args = os.Args[:1] graph := NewGraph() graph.mongo.db = "test-db" - graph.mongo.col = "test-col" ctx, can := context.WithCancel(context.TODO()) defer can() 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() defer clean() @@ -39,7 +38,7 @@ func TestIntegration(t *testing.T) { t.Run("graph.Insert(...)", func(t *testing.T) { for _, one := range ones { - err := graph.Insert(ctx, one) + err := graph.Insert(ctx, "col", one) if err != nil { t.Fatal(err) } @@ -47,7 +46,7 @@ func TestIntegration(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 { t.Fatal(err) } @@ -58,7 +57,7 @@ func TestIntegration(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 { t.Fatal(err) } @@ -69,12 +68,12 @@ func TestIntegration(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 { t.Fatal(err) } - some, err := graph.List(ctx, ones[0].Name) + some, err := graph.List(ctx, "col", ones[0].Name) if err != nil { 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) { - 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: ":("}, "world": entity.One{Name: "world", Relationship: ":("}, }}) @@ -100,7 +99,7 @@ func TestIntegration(t *testing.T) { t.Fatal(err) } - some1, err := graph.List(ctx, ones[0].Name) + some1, err := graph.List(ctx, "col", ones[0].Name) if err != nil { t.Fatal(err) } @@ -112,11 +111,11 @@ func TestIntegration(t *testing.T) { 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 { t.Fatal(err) } - some2, err := graph.List(ctx, ones[0].Name) + some2, err := graph.List(ctx, "col", ones[0].Name) if err != nil { t.Fatal(err) } diff --git a/storage/mon.go b/storage/mon.go index 1b08c8a..e93e437 100644 --- a/storage/mon.go +++ b/storage/mon.go @@ -15,7 +15,6 @@ import ( type Mongo struct { client *mongo.Client db string - col string } func NewMongo() Mongo { @@ -35,12 +34,11 @@ func NewMongo() Mongo { return Mongo{ client: c, db: config.New().Database, - col: "col", } } -func (m Mongo) Find(ctx context.Context, filter interface{}) (chan bson.Raw, error) { - c := m.client.Database(m.db).Collection(m.col) +func (m Mongo) Find(ctx context.Context, namespace string, filter interface{}) (chan bson.Raw, error) { + c := m.client.Database(m.db).Collection(namespace) cursor, err := c.Find(ctx, filter) if err != nil { return nil, err @@ -60,13 +58,13 @@ func (m Mongo) page(ctx context.Context, cursor *mongo.Cursor) chan bson.Raw { return ch } -func (m Mongo) Update(ctx context.Context, filter, apply interface{}) error { - c := m.client.Database(m.db).Collection(m.col) +func (m Mongo) Update(ctx context.Context, namespace string, filter, apply interface{}) error { + c := m.client.Database(m.db).Collection(namespace) _, err := c.UpdateOne(ctx, filter, apply) 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) if err != nil { return err @@ -80,13 +78,13 @@ func (m Mongo) Insert(ctx context.Context, apply interface{}) error { } else if _, ok := mapp["_id"].(string); !ok { 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) return err } -func (m Mongo) Delete(ctx context.Context, filter interface{}) error { - c := m.client.Database(m.db).Collection(m.col) +func (m Mongo) Delete(ctx context.Context, namespace string, filter interface{}) error { + c := m.client.Database(m.db).Collection(namespace) _, err := c.DeleteOne(ctx, filter) return err } diff --git a/view/html.go b/view/html.go index 25e26f0..6b38797 100644 --- a/view/html.go +++ b/view/html.go @@ -8,6 +8,8 @@ import ( "local/dndex/storage/entity" "log" "net/http" + "path" + "strings" ) func Html(g storage.Graph) error { @@ -20,8 +22,8 @@ func Html(g storage.Graph) error { func foo(g storage.Graph) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var err error - switch r.URL.Path { - case "/who": + switch path.Base(r.URL.Path) { + case "who": err = who(g, w, r) default: 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 { + 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"] _, verbose := r.URL.Query()["v"] results := make(map[string]entity.One) for i := 0; i < len(ids); i++ { id := ids[i] - ones, err := g.List(r.Context(), id) + ones, err := g.List(r.Context(), namespace, id) if err != nil { return err } @@ -48,7 +56,7 @@ func who(g storage.Graph, w http.ResponseWriter, r *http.Request) error { } one := ones[0] if verbose { - ones, err := g.List(r.Context(), one.Peers()...) + ones, err := g.List(r.Context(), namespace, one.Peers()...) if err != nil { return err } diff --git a/view/html_test.go b/view/html_test.go index e53e76a..77a4228 100644 --- a/view/html_test.go +++ b/view/html_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "io/ioutil" "local/dndex/config" "local/dndex/storage" "local/dndex/storage/entity" @@ -33,14 +34,16 @@ func TestHtml(t *testing.T) { } }() 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 { t.Fatal(err) } defer resp.Body.Close() 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) + } else if err := json.Unmarshal(b, &v); err != nil { + t.Fatalf("err unmarshalling response: %v: %s", err, b) } b, err := json.MarshalIndent(v, "", " ") if err != nil { @@ -101,10 +104,10 @@ func fillDB(t *testing.T, g storage.Graph) []entity.One { } } 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) } - 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) } else if len(results) != 1 { t.Fatal(len(results))