query remote relation model

This commit is contained in:
xing 2023-05-27 14:42:14 +08:00
parent 95e3298b7e
commit 1c33665e34
3 changed files with 45 additions and 27 deletions

View File

@ -41,6 +41,7 @@ type post struct {
Ships *[]TermRelationships Ships *[]TermRelationships
PostMeta *[]models.PostMeta PostMeta *[]models.PostMeta
TermTaxonomy *[]TermTaxonomy TermTaxonomy *[]TermTaxonomy
Terms *[]models.Terms
} }
type TermRelationships struct { type TermRelationships struct {

View File

@ -45,6 +45,7 @@ func parseBeforeJoin(qq *QueryCondition, ship Relationship) {
if ship.Middle != nil { if ship.Middle != nil {
parseBeforeJoin(qq, *ship.Middle) parseBeforeJoin(qq, *ship.Middle)
local = ship.Local local = ship.Local
fromTable = ship.Middle.Table
} else { } else {
fromTable = qq.From fromTable = qq.From
} }
@ -64,37 +65,34 @@ func parseBeforeJoin(qq *QueryCondition, ship Relationship) {
} }
func parseAfterJoin(ids [][]any, qq *QueryCondition, ship Relationship) bool { func parseAfterJoin(fromTable string, ids [][]any, qq *QueryCondition, ship Relationship) bool {
tables := strings.Split(ship.Middle.Table, " ") tables := strings.Split(ship.Middle.Table, " ")
from := strings.Split(qq.From, " ") from := strings.Split(fromTable, " ")
on := "" on := ""
if ship.On != "" { if ship.On != "" {
on = fmt.Sprintf("and %s", on) on = fmt.Sprintf("and %s", on)
} }
foreignKey := ship.ForeignKey foreignKey := ship.ForeignKey
local := ship.Local local := ship.Local
if ship.RelationType == HasMany {
foreignKey = ship.Local
local = ship.ForeignKey
}
qq.Join = append(qq.Join, []string{ qq.Join = append(qq.Join, []string{
"left join", ship.Middle.Table, "left join", ship.Middle.Table,
fmt.Sprintf("%s.%s=%s.%s %s", fmt.Sprintf("%s.%s=%s.%s %s",
tables[len(tables)-1], foreignKey, from[len(from)-1], local, on, tables[len(tables)-1], foreignKey, from[len(from)-1], local, on,
), ),
}) })
if ship.Middle.Middle != nil { if ship.Middle != nil && ship.Middle.Middle != nil {
return parseAfterJoin(ids, qq, *ship.Middle.Middle) return parseAfterJoin(tables[len(tables)-1], ids, qq, *ship.Middle)
} else { } else {
from := strings.Split(qq.From, " ")
ww, ok := qq.Where.(SqlBuilder) ww, ok := qq.Where.(SqlBuilder)
if ok { if ok {
ww = append(ww, []string{fmt.Sprintf("%s.%s", ww = append(ww, []string{fmt.Sprintf("%s.%s",
tables[len(tables)-1], ship.Middle.Local), "in", ""}, tables[len(tables)-1], ship.Middle.ForeignKey), "in", ""},
) )
qq.Where = ww qq.Where = ww
} }
if qq.Fields == "" || qq.Fields == "*" { if qq.Fields == "" || qq.Fields == "*" {
qq.Fields = str.Join(from[len(from)-1], ".", "*") qq.Fields = str.Join(from[len(from)-1], ".", "*", ",", tables[len(tables)-1], ".", ship.Middle.ForeignKey)
} }
qq.In = ids qq.In = ids
return ship.Middle.RelationType == HasMany return ship.Middle.RelationType == HasMany
@ -139,7 +137,7 @@ func Relation(isPlural bool, db dbQuery, ctx context.Context, r any, q *QueryCon
in := [][]any{ids} in := [][]any{ids}
if ok { if ok {
if ship.Middle != nil { if ship.Middle != nil {
isPlural = parseAfterJoin(in, qq, ship) isPlural = parseAfterJoin(qq.From, in, qq, ship)
} else { } else {
ww = append(ww, SqlBuilder{{ ww = append(ww, SqlBuilder{{
ship.ForeignKey, "in", "", ship.ForeignKey, "in", "",

View File

@ -2,6 +2,7 @@ package model
import ( import (
"github.com/fthvgb1/wp-go/app/pkg/models" "github.com/fthvgb1/wp-go/app/pkg/models"
"github.com/fthvgb1/wp-go/helper/slice"
"testing" "testing"
) )
@ -117,13 +118,30 @@ func PostMetas() (func(any) []any, func(any, any), any, any, Relationship) {
} }
} }
var term = RelationHasMany(func(m *post) uint64 { var postHaveManyTerms = RelationHasMany(func(m *post) uint64 {
return m.Id return m.Id
}, func(p *TermTaxonomy) uint64 { }, func(p *struct {
return p.TermTaxonomyId ObjectId uint64 `db:"object_id"`
}, func(m *post, i *[]TermTaxonomy) { models.Terms
m.TermTaxonomy = i }) uint64 {
return p.ObjectId
}, func(m *post, i *[]struct {
ObjectId uint64 `db:"object_id"`
models.Terms
}) {
v := slice.Map(*i, func(t struct {
ObjectId uint64 `db:"object_id"`
models.Terms
}) models.Terms {
return t.Terms
})
m.Terms = &v
}, Relationship{ }, Relationship{
RelationType: HasOne,
Table: "wp_terms",
ForeignKey: "term_id",
Local: "term_id",
Middle: &Relationship{
RelationType: HasOne, RelationType: HasOne,
Table: "wp_term_taxonomy taxonomy", Table: "wp_term_taxonomy taxonomy",
ForeignKey: "term_taxonomy_id", ForeignKey: "term_taxonomy_id",
@ -131,8 +149,9 @@ var term = RelationHasMany(func(m *post) uint64 {
Middle: &Relationship{ Middle: &Relationship{
RelationType: HasMany, RelationType: HasMany,
Table: "wp_term_relationships", Table: "wp_term_relationships",
ForeignKey: "ID", ForeignKey: "object_id",
Local: "object_id", Local: "ID",
},
}, },
}) })
@ -175,7 +194,7 @@ func TestGets2(t *testing.T) {
WithFn(true, false, nil, termMyHasOneTerm), WithFn(true, false, nil, termMyHasOneTerm),
), shipHasManyTermMy), ), shipHasManyTermMy),
), postHasManyShip), ), postHasManyShip),
//WithFn(true, false, nil, term), WithFn(true, false, nil, postHaveManyTerms),
) )
got, err := Gets[post](ctx, q) got, err := Gets[post](ctx, q)
_ = got _ = got
@ -196,12 +215,12 @@ func TestGets2(t *testing.T) {
Fields("posts.*"), Fields("posts.*"),
From("wp_posts posts"), From("wp_posts posts"),
WithFn(true, false, nil, Meta2()), WithFn(true, false, nil, Meta2()),
WithFn(true, false, Conditions( /*WithFn(true, false, Conditions(
WithFn(true, false, Conditions( WithFn(true, false, Conditions(
WithFn(true, false, nil, termMyHasOneTerm), WithFn(true, false, nil, termMyHasOneTerm),
), shipHasManyTermMy), ), shipHasManyTermMy),
), postHasManyShip), ), postHasManyShip),*/
//WithFn(true, false, nil, term), WithFn(true, false, nil, postHaveManyTerms),
) )
got, err := Finds[post](ctx, q) got, err := Finds[post](ctx, q)
_ = got _ = got