Support SubQuery for Generics
This commit is contained in:
parent
3de6d0b2f9
commit
797a557cc8
@ -127,6 +127,11 @@ type chainG[T any] struct {
|
|||||||
execG[T]
|
execG[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c chainG[T]) getInstance() *DB {
|
||||||
|
var r T
|
||||||
|
return c.g.apply(context.Background()).Model(r).getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
func (c chainG[T]) with(op op) chainG[T] {
|
func (c chainG[T]) with(op op) chainG[T] {
|
||||||
return chainG[T]{
|
return chainG[T]{
|
||||||
execG: execG[T]{g: &g[T]{
|
execG: execG[T]{g: &g[T]{
|
||||||
|
11
statement.go
11
statement.go
@ -205,19 +205,20 @@ func (stmt *Statement) AddVar(writer clause.Writer, vars ...interface{}) {
|
|||||||
} else {
|
} else {
|
||||||
writer.WriteString("(NULL)")
|
writer.WriteString("(NULL)")
|
||||||
}
|
}
|
||||||
case *DB:
|
case interface{ getInstance() *DB }:
|
||||||
subdb := v.Session(&Session{Logger: logger.Discard, DryRun: true}).getInstance()
|
cv := v.getInstance()
|
||||||
if v.Statement.SQL.Len() > 0 {
|
subdb := cv.Session(&Session{Logger: logger.Discard, DryRun: true}).getInstance()
|
||||||
|
if cv.Statement.SQL.Len() > 0 {
|
||||||
var (
|
var (
|
||||||
vars = subdb.Statement.Vars
|
vars = subdb.Statement.Vars
|
||||||
sql = v.Statement.SQL.String()
|
sql = cv.Statement.SQL.String()
|
||||||
)
|
)
|
||||||
|
|
||||||
subdb.Statement.Vars = make([]interface{}, 0, len(vars))
|
subdb.Statement.Vars = make([]interface{}, 0, len(vars))
|
||||||
for _, vv := range vars {
|
for _, vv := range vars {
|
||||||
subdb.Statement.Vars = append(subdb.Statement.Vars, vv)
|
subdb.Statement.Vars = append(subdb.Statement.Vars, vv)
|
||||||
bindvar := strings.Builder{}
|
bindvar := strings.Builder{}
|
||||||
v.Dialector.BindVarTo(&bindvar, subdb.Statement, vv)
|
cv.Dialector.BindVarTo(&bindvar, subdb.Statement, vv)
|
||||||
sql = strings.Replace(sql, bindvar.String(), "?", 1)
|
sql = strings.Replace(sql, bindvar.String(), "?", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,3 +366,35 @@ func TestGenericsGroupHaving(t *testing.T) {
|
|||||||
t.Errorf("expected group name 'GenericsGroupHavingMulti', got '%s'", grouped[0].Name)
|
t.Errorf("expected group name 'GenericsGroupHavingMulti', got '%s'", grouped[0].Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenericsSubQuery(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
users := []User{
|
||||||
|
{Name: "GenericsSubquery_1", Age: 10},
|
||||||
|
{Name: "GenericsSubquery_2", Age: 20},
|
||||||
|
{Name: "GenericsSubquery_3", Age: 30},
|
||||||
|
{Name: "GenericsSubquery_4", Age: 40},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gorm.G[User](DB).CreateInBatches(ctx, &users, len(users)); err != nil {
|
||||||
|
t.Fatalf("CreateInBatches failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := gorm.G[User](DB).Where("name IN (?)", gorm.G[User](DB).Select("name").Where("name LIKE ?", "GenericsSubquery%")).Find(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) != 4 {
|
||||||
|
t.Errorf("Four users should be found, instead found %d", len(results))
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err = gorm.G[User](DB).Where("name IN (?)", gorm.G[User](DB).Select("name").Where("name IN ?", []string{"GenericsSubquery_1", "GenericsSubquery_2"}).Or("name = ?", "GenericsSubquery_3")).Find(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("got error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) != 3 {
|
||||||
|
t.Errorf("Three users should be found, instead found %d", len(results))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
module gorm.io/gorm/tests
|
module gorm.io/gorm/tests
|
||||||
|
|
||||||
go 1.18.0
|
go 1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user