diff --git a/app/pkg/dao/comments.go b/app/pkg/dao/comments.go index 1948443..504e0c5 100644 --- a/app/pkg/dao/comments.go +++ b/app/pkg/dao/comments.go @@ -34,7 +34,7 @@ func PostComments(args ...any) ([]uint64, error) { r, err := model.Finds[models.Comments](ctx, model.Conditions( model.Where(model.SqlBuilder{ {"comment_approved", "1"}, - {"comment_post_ID", "=", number.ToString(postId), "int"}, + {"comment_post_ID", "=", number.IntToString(postId), "int"}, }), model.Fields("comment_ID"), model.Order(model.SqlBuilder{ diff --git a/app/theme/wp/calclass.go b/app/theme/wp/calclass.go index fb7fd17..cd8e970 100644 --- a/app/theme/wp/calclass.go +++ b/app/theme/wp/calclass.go @@ -50,20 +50,20 @@ func (h *Handle) BodyClass() string { if cate.Slug[0] != '%' { class = append(class, str.Join("category-", cate.Slug)) } - class = append(class, str.Join("category-", number.ToString(cate.Terms.TermId))) + class = append(class, str.Join("category-", number.IntToString(cate.Terms.TermId))) case constraints.Author: class = append(class, "archive", "author") author := h.Index.Param.Author user, _ := cache.GetUserByName(h.C, author) - class = append(class, str.Join("author-", number.ToString(user.Id))) + class = append(class, str.Join("author-", number.IntToString(user.Id))) if user.UserLogin[0] != '%' { class = append(class, str.Join("author-", user.UserLogin)) } case constraints.Detail: class = append(class, "post-template-default", "single", "single-post") - class = append(class, str.Join("postid-", number.ToString(h.Detail.Post.Id))) + class = append(class, str.Join("postid-", number.IntToString(h.Detail.Post.Id))) if len(h.themeMods.ThemeSupport.PostFormats) > 0 { class = append(class, "single-format-standard") } diff --git a/model/query.go b/model/query.go index 6689bc0..fb1cd66 100644 --- a/model/query.go +++ b/model/query.go @@ -48,7 +48,7 @@ func pagination[T Model](db dbQuery, ctx context.Context, q *QueryCondition, pag err = er return } - qx.From = str.Join("( ", sq, " ) ", "table", number.ToString(rand.Int())) + qx.From = str.Join("( ", sq, " ) ", "table", number.IntToString(rand.Int())) qx = QueryCondition{ From: qx.From, In: qx.In, diff --git a/model/querycondition.go b/model/querycondition.go index 1a9118e..d7daae8 100644 --- a/model/querycondition.go +++ b/model/querycondition.go @@ -36,7 +36,7 @@ func finds[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []T, err = db.Select(ctx, &r, sq, args...) return } - err = parseRelation(true, db, ctx, &r, q) + err = ParseRelation(true, db, ctx, &r, q) return } @@ -317,14 +317,14 @@ func gets[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r T, err err = db.Get(ctx, &r, s, args...) return } - err = parseRelation(false, db, ctx, &r, q) + err = ParseRelation(false, db, ctx, &r, q) return } -func parseRelation(isMultiple bool, db dbQuery, ctx context.Context, r any, q *QueryCondition) (err error) { - fn, fns := Relation(isMultiple, db, ctx, r, q) - for _, f := range fn { - f() +func ParseRelation(isMultiple bool, db dbQuery, ctx context.Context, r any, q *QueryCondition) (err error) { + before, after := Relation(isMultiple, db, ctx, r, q) + for _, fn := range before { + fn() } s, args, err := BuildQuerySql(q) if err != nil { @@ -339,8 +339,8 @@ func parseRelation(isMultiple bool, db dbQuery, ctx context.Context, r any, q *Q if err != nil { return } - for _, f := range fns { - err = f() + for _, fn := range after { + err = fn() if err != nil { return } diff --git a/model/relation.go b/model/relation.go index dec55ff..6bdb6dd 100644 --- a/model/relation.go +++ b/model/relation.go @@ -25,13 +25,13 @@ type Relationship struct { } func Relation(isMultiple bool, db dbQuery, ctx context.Context, r any, q *QueryCondition) ([]func(), []func() error) { - var fn []func() - var fns []func() error + var beforeFn []func() + var afterFn []func() error for _, f := range q.RelationFn { - getVal, isJoin, qq, ff := f() - idFn, assignment, rr, rrs, ship := ff() + getVal, isJoin, qq, relationship := f() + idFn, assignmentFn, rr, rrs, ship := relationship() if isJoin { - fn = append(fn, func() { + beforeFn = append(beforeFn, func() { tables := strings.Split(ship.Table, " ") from := strings.Split(q.From, " ") on := "" @@ -46,44 +46,45 @@ func Relation(isMultiple bool, db dbQuery, ctx context.Context, r any, q *QueryC if !getVal { continue } - fns = append(fns, func() error { + afterFn = append(afterFn, func() error { ids := idFn(r) if len(ids) < 1 { return nil } var err error - { - if qq == nil { - qq = &QueryCondition{ - Fields: "*", - } - } - var w any = qq.Where - if w == nil { - w = SqlBuilder{} - } - ww, ok := w.(SqlBuilder) - if ok { - ww = append(ww, SqlBuilder{{ - ship.ForeignKey, "in", "", - }}...) - qq.In = [][]any{ids} - qq.Where = ww - } - if qq.From == "" { - qq.From = ship.Table + if qq == nil { + qq = &QueryCondition{ + Fields: "*", } } - err = parseRelation(isMultiple || ship.RelationType == "hasMany", db, ctx, helper.Or(isMultiple, rrs, rr), qq) - if err != nil && err != sql.ErrNoRows { - return err + var w any = qq.Where + if w == nil { + w = SqlBuilder{} } - assignment(r, helper.Or(isMultiple, rrs, rr)) - + ww, ok := w.(SqlBuilder) + if ok { + ww = append(ww, SqlBuilder{{ + ship.ForeignKey, "in", "", + }}...) + qq.In = [][]any{ids} + qq.Where = ww + } + if qq.From == "" { + qq.From = ship.Table + } + err = ParseRelation(isMultiple || ship.RelationType == "hasMany", db, ctx, helper.Or(isMultiple, rrs, rr), qq) + if err != nil { + if err == sql.ErrNoRows { + err = nil + } else { + return err + } + } + assignmentFn(r, helper.Or(isMultiple, rrs, rr)) return err }) } - return fn, fns + return beforeFn, afterFn } func GetWithID[T, V any](fn func(*T) V) func(any) []any { @@ -98,47 +99,52 @@ func GetWithID[T, V any](fn func(*T) V) func(any) []any { } } -func SetHasOne[T, V any, K comparable](fn func(*T, *V), idFn func(*T) K, iddFn func(*V) K) func(any, any) { - return func(m, v any) { +// SetHasOne mIdFn is main , pIdFn is part +// +// eg: post has a user. mIdFn is post's userId, iddFn is user's id +func SetHasOne[T, V any, K comparable](assignmentFn func(*T, *V), mIdFn func(*T) K, pIdFn func(*V) K) func(any, any) { + return func(m, p any) { one, ok := m.(*T) if ok { - fn(one, v.(*V)) + assignmentFn(one, p.(*V)) return } - r := m.(*[]T) - vv := v.(*[]V) - mm := slice.SimpleToMap(*vv, func(v V) K { - return iddFn(&v) + mSlice := m.(*[]T) + pSLice := p.(*[]V) + mm := slice.SimpleToMap(*pSLice, func(v V) K { + return pIdFn(&v) }) - for i := 0; i < len(*r); i++ { - val := &(*r)[i] - id := idFn(val) - v, ok := mm[id] + for i := 0; i < len(*mSlice); i++ { + m := &(*mSlice)[i] + id := mIdFn(m) + p, ok := mm[id] if ok { - fn(val, &v) + assignmentFn(m, &p) } } } } -func SetHasMany[T, V any, K comparable](fn func(*T, *[]V), idFn func(*T) K, iddFn func(*V) K) func(any, any) { - return func(m, v any) { +// SetHasMany +// eg: post has many comments,pIdFn is comment's postId, mIdFn is post's id +func SetHasMany[T, V any, K comparable](assignmentFn func(*T, *[]V), pIdFn func(*T) K, mIdFn func(*V) K) func(any, any) { + return func(m, p any) { one, ok := m.(*T) if ok { - fn(one, v.(*[]V)) + assignmentFn(one, p.(*[]V)) return } r := m.(*[]T) - vv := v.(*[]V) + vv := p.(*[]V) mm := slice.GroupBy(*vv, func(t V) (K, V) { - return iddFn(&t), t + return mIdFn(&t), t }) for i := 0; i < len(*r); i++ { - val := &(*r)[i] - id := idFn(val) - v, ok := mm[id] + m := &(*r)[i] + id := pIdFn(m) + p, ok := mm[id] if ok { - fn(val, &v) + assignmentFn(m, &p) } } }