Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions generator/templates/client.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,17 @@ type PredicateData struct {
Children []PredicateData
}

type ChildPredicate struct {
Column string
Value any
}

type PredicateOf[M any] interface {
ToPredicateData() PredicateData
Validate() error
Column() string
Value() any
Children() []ChildPredicate
phantom(M)
}

Expand All @@ -355,6 +361,17 @@ func (p Predicate[M]) Value() any {
return p.Data.Value
}

func (p Predicate[M]) Children() []ChildPredicate {
if !p.Data.IsLogical || len(p.Data.Children) == 0 {
return nil
}
res := make([]ChildPredicate, len(p.Data.Children))
for i, c := range p.Data.Children {
res[i] = ChildPredicate{Column: c.Column, Value: c.Value}
}
return res
}

func (p Predicate[M]) phantom(M) {}

type UniquePredicate[M any] struct {
Expand All @@ -380,6 +397,17 @@ func (p UniquePredicate[M]) Value() any {
return p.Data.Value
}

func (p UniquePredicate[M]) Children() []ChildPredicate {
if !p.Data.IsLogical || len(p.Data.Children) == 0 {
return nil
}
res := make([]ChildPredicate, len(p.Data.Children))
for i, c := range p.Data.Children {
res[i] = ChildPredicate{Column: c.Column, Value: c.Value}
}
return res
}

func (p UniquePredicate[M]) phantom(M) {}

func validateValue(col string, val any) error {
Expand Down
41 changes: 41 additions & 0 deletions integration/composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,47 @@ func TestCompositeKeys(t *testing.T) {
}
})

t.Run("hook_inspects_composite_Children", func(t *testing.T) {
db, cleanup := setupTestDB(t)
defer cleanup()

var children []phi.ChildPredicate

db.User.Use(user.Extension{
FindUnique: func(ctx context.Context, args *user.FindUniqueArgs, next user.FindUniqueQuery) (*phi.User, error) {
if len(args.Where) > 0 {
children = args.Where[0].Children()
}
return next(ctx, args)
},
})

_, err := db.User.Create().
SetEmail("hook-children@example.com").
SetPhoneNum("composite-005b").
Exec(ctx)
if err != nil {
t.Fatalf("create failed: %v", err)
}

_, err = db.User.FindUnique(
user.EmailPhone.EQ("hook-children@example.com", "composite-005b"),
).Exec(ctx)
if err != nil {
t.Fatalf("find unique failed: %v", err)
}

if len(children) != 2 {
t.Fatalf("expected 2 children, got %d", len(children))
}
if children[0].Column != "email" || children[0].Value != "hook-children@example.com" {
t.Errorf("unexpected child 0: %+v", children[0])
}
if children[1].Column != "phoneNum" || children[1].Value != "composite-005b" {
t.Errorf("unexpected child 1: %+v", children[1])
}
})

t.Run("hook_replaces_composite_predicate", func(t *testing.T) {
db, cleanup := setupTestDB(t)
defer cleanup()
Expand Down
17 changes: 16 additions & 1 deletion integration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ func main() {
// runExtensionExamples(db, ctx)
// runCTP(db, ctx)
//

usr, err := db.User.Create().SetEmail("xx@yy.com").SetPhoneNum("11").Exec(ctx)
if err != nil {
panic(err)
Expand All @@ -84,6 +83,22 @@ func main() {
panic(err)
}
printJSON(posts)

db.User.Use(user.Extension{
FindUnique: func(ctx context.Context, args *phi.UserFindUniqueArgs, next phi.UserFindUniqueQuery) (*phi.User, error) {
for _, w := range args.Where {
switch w.Column() {
case user.Email.Column:
// Scalar unique predicate
case user.EmailPhone.Column:
for _, child := range w.Children() {
fmt.Printf("Composite field: %s = %v\n", child.Column, child.Value)
}
}
}
return next(ctx, args)
},
})
}

// =============================================================================
Expand Down
28 changes: 28 additions & 0 deletions integration/phi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1293,11 +1293,17 @@ type PredicateData struct {
Children []PredicateData
}

type ChildPredicate struct {
Column string
Value any
}

type PredicateOf[M any] interface {
ToPredicateData() PredicateData
Validate() error
Column() string
Value() any
Children() []ChildPredicate
phantom(M)
}

Expand All @@ -1321,6 +1327,17 @@ func (p Predicate[M]) Value() any {
return p.Data.Value
}

func (p Predicate[M]) Children() []ChildPredicate {
if !p.Data.IsLogical || len(p.Data.Children) == 0 {
return nil
}
res := make([]ChildPredicate, len(p.Data.Children))
for i, c := range p.Data.Children {
res[i] = ChildPredicate{Column: c.Column, Value: c.Value}
}
return res
}

func (p Predicate[M]) phantom(M) {}

type UniquePredicate[M any] struct {
Expand All @@ -1346,6 +1363,17 @@ func (p UniquePredicate[M]) Value() any {
return p.Data.Value
}

func (p UniquePredicate[M]) Children() []ChildPredicate {
if !p.Data.IsLogical || len(p.Data.Children) == 0 {
return nil
}
res := make([]ChildPredicate, len(p.Data.Children))
for i, c := range p.Data.Children {
res[i] = ChildPredicate{Column: c.Column, Value: c.Value}
}
return res
}

func (p UniquePredicate[M]) phantom(M) {}

func validateValue(col string, val any) error {
Expand Down
Loading