From 7635d45c8adcf86aa1c269d76da607fddcb582a8 Mon Sep 17 00:00:00 2001 From: Ariel Mashraki <7413593+a8m@users.noreply.github.com> Date: Fri, 16 Oct 2020 14:04:52 +0300 Subject: [PATCH] entc/gen: reject codegen in case of duplicate edges (#858) See #856 --- entc/gen/graph.go | 4 ++++ entc/gen/graph_test.go | 19 +++++++++++++++++++ entc/gen/type.go | 6 +++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/entc/gen/graph.go b/entc/gen/graph.go index bc0e1f210..682a1befc 100644 --- a/entc/gen/graph.go +++ b/entc/gen/graph.go @@ -200,9 +200,13 @@ func (g *Graph) addIndexes(schema *load.Schema) { // addEdges adds the node edges to the graph. func (g *Graph) addEdges(schema *load.Schema) { t, _ := g.typ(schema.Name) + seen := make(map[string]struct{}, len(schema.Edges)) for _, e := range schema.Edges { typ, ok := g.typ(e.Type) expect(ok, "type %q does not exist for edge", e.Type) + _, ok = seen[e.Name] + expect(!ok, "%s schema contains multiple %q edges", schema.Name, e.Name) + seen[e.Name] = struct{}{} switch { // Assoc only. case !e.Inverse: diff --git a/entc/gen/graph_test.go b/entc/gen/graph_test.go index bfaff1b19..19f384844 100644 --- a/entc/gen/graph_test.go +++ b/entc/gen/graph_test.go @@ -178,6 +178,25 @@ func TestNewGraphBadInverse(t *testing.T) { require.Errorf(t, err, "mismatch type for back-reference") } +func TestNewGraphDuplicateEdges(t *testing.T) { + _, err := NewGraph(&Config{Package: "entc/gen", Storage: drivers[0]}, + &load.Schema{ + Name: "User", + Edges: []*load.Edge{ + {Name: "groups", Type: "Group"}, + {Name: "groups", Type: "Group", RefName: "owner", Inverse: true}, + }, + }, + &load.Schema{ + Name: "Group", + Edges: []*load.Edge{ + {Name: "users", Type: "User", RefName: "groups", Inverse: true}, + {Name: "owner", Type: "User", Unique: true}, + }, + }) + require.EqualError(t, err, `entc/gen: User schema contains multiple "groups" edges`) +} + func TestRelation(t *testing.T) { require := require.New(t) _, err := NewGraph(&Config{Package: "entc/gen", Storage: drivers[0]}, T1) diff --git a/entc/gen/type.go b/entc/gen/type.go index 2326ef87a..205934c3f 100644 --- a/entc/gen/type.go +++ b/entc/gen/type.go @@ -239,11 +239,11 @@ func (t Type) Receiver() string { return receiver(t.Name) } -// HasAssoc returns true if this type has an assoc edge with the given name. -// faster than map access for most cases. +// HasAssoc returns true if this type has an assoc-edge (non-inverse) +// with the given name. faster than map access for most cases. func (t Type) HasAssoc(name string) (*Edge, bool) { for _, e := range t.Edges { - if name == e.Name { + if name == e.Name && !e.IsInverse() { return e, true } }