Compare commits

...

2 Commits

Author SHA1 Message Date
e7ea2bf334 fix bug 2023-03-19 20:53:27 +08:00
d48a156983 fix bug 及优化 2023-03-19 20:40:08 +08:00
10 changed files with 115 additions and 93 deletions

View File

@ -192,3 +192,20 @@ func RenderedHtml(t *template.Template, data map[string]any) (r string, err erro
r = buf.String() r = buf.String()
return return
} }
func BuildOptions[T any, K comparable](a []T, selected K, fn func(T) (K, any), attr ...string) string {
s := strings2.NewBuilder()
att := ""
if len(attr) > 0 {
att = strings.Join(attr, " ")
}
for _, t := range a {
k, v := fn(t)
ss := ""
if k == selected {
ss = "selected"
}
s.Sprintf(`<option %s %s value="%v">%v</option>`, ss, att, v, k)
}
return s.String()
}

View File

@ -91,3 +91,13 @@ func Divide[T constraints.Integer | constraints.Float](i, j T) T {
func CalTotalPage[T constraints.Integer](totalRows, size T) T { func CalTotalPage[T constraints.Integer](totalRows, size T) T {
return T(math.Ceil(float64(totalRows) / float64(size))) return T(math.Ceil(float64(totalRows) / float64(size)))
} }
type Counter[T constraints.Integer] func() T
func Counters[T constraints.Integer]() func() T {
var count T
return func() T {
count++
return count
}
}

View File

@ -2,6 +2,7 @@ package number
import ( import (
"fmt" "fmt"
"github.com/fthvgb1/wp-go/taskPools"
"golang.org/x/exp/constraints" "golang.org/x/exp/constraints"
"reflect" "reflect"
"testing" "testing"
@ -250,3 +251,40 @@ func TestCalTotalPage(t *testing.T) {
}) })
} }
} }
func TestCounters(t *testing.T) {
type testCase[T constraints.Integer] struct {
name string
want func() T
}
var c = 0
tests := []testCase[int]{
{
name: "t1",
want: func() int {
c++
return c
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Counters[int]()
if !reflect.DeepEqual(got(), tt.want()) {
t.Errorf("Counters() = %v, want %v", got(), tt.want())
}
got()
got()
got()
p := taskPools.NewPools(6)
for i := 0; i < 50; i++ {
p.Execute(func() {
got()
})
}
p.Wait()
fmt.Println("got ", got())
})
}
}

View File

@ -3,11 +3,9 @@ package cache
import ( import (
"context" "context"
"github.com/fthvgb1/wp-go/cache" "github.com/fthvgb1/wp-go/cache"
"github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
"github.com/fthvgb1/wp-go/internal/cmd/cachemanager" "github.com/fthvgb1/wp-go/internal/cmd/cachemanager"
"github.com/fthvgb1/wp-go/internal/pkg/config" "github.com/fthvgb1/wp-go/internal/pkg/config"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/dao" "github.com/fthvgb1/wp-go/internal/pkg/dao"
"github.com/fthvgb1/wp-go/internal/pkg/logs" "github.com/fthvgb1/wp-go/internal/pkg/logs"
"github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/pkg/models"
@ -17,7 +15,7 @@ import (
var postContextCache *cache.MapCache[uint64, dao.PostContext] var postContextCache *cache.MapCache[uint64, dao.PostContext]
var archivesCaches *Arch var archivesCaches *Arch
var categoryAndTagsCaches *cache.VarCache[[]models.TermsMy] var categoryAndTagsCaches *cache.MapCache[int, []models.TermsMy]
var recentPostsCaches *cache.VarCache[[]models.Posts] var recentPostsCaches *cache.VarCache[[]models.Posts]
var recentCommentsCaches *cache.VarCache[[]models.Comments] var recentCommentsCaches *cache.VarCache[[]models.Comments]
var postCommentCaches *cache.MapCache[uint64, []uint64] var postCommentCaches *cache.MapCache[uint64, []uint64]
@ -65,7 +63,7 @@ func InitActionsCommonCache() {
postMetaCache = cachemanager.MapBatchCacheBy(dao.GetPostMetaByPostIds, c.CacheTime.PostDataCacheTime) postMetaCache = cachemanager.MapBatchCacheBy(dao.GetPostMetaByPostIds, c.CacheTime.PostDataCacheTime)
categoryAndTagsCaches = cache.NewVarCache(dao.CategoriesAndTags, c.CacheTime.CategoryCacheTime) categoryAndTagsCaches = cachemanager.MapCacheBy[int](dao.CategoriesAndTags, c.CacheTime.CategoryCacheTime)
recentPostsCaches = cache.NewVarCache(dao.RecentPosts, c.CacheTime.RecentPostCacheTime) recentPostsCaches = cache.NewVarCache(dao.RecentPosts, c.CacheTime.RecentPostCacheTime)
@ -128,22 +126,22 @@ func (a *Arch) getArchiveCache(ctx context.Context) []models.PostArchive {
// //
// t is constraints.Tag or constraints.Category // t is constraints.Tag or constraints.Category
func CategoriesTags(ctx context.Context, t ...int) []models.TermsMy { func CategoriesTags(ctx context.Context, t ...int) []models.TermsMy {
r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx) tt := 0
logs.ErrPrintln(err, "get category err")
if len(t) > 0 { if len(t) > 0 {
return slice.Filter(r, func(my models.TermsMy, i int) bool { tt = t[0]
return helper.Or(t[0] == constraints.Tag, "post_tag", "category") == my.Taxonomy
})
} }
r, err := categoryAndTagsCaches.GetCache(ctx, tt, time.Second, ctx, tt)
logs.ErrPrintln(err, "get category err")
return r return r
} }
func AllCategoryTagsNames(ctx context.Context, c int) map[string]struct{} { func AllCategoryTagsNames(ctx context.Context, t ...int) map[string]struct{} {
r, err := categoryAndTagsCaches.GetCache(ctx, time.Second, ctx) tt := 0
logs.ErrPrintln(err, "get category err") if len(t) > 0 {
return slice.FilterAndToMap(r, func(t models.TermsMy) (string, struct{}, bool) { tt = t[0]
if helper.Or(c == constraints.Tag, "post_tag", "category") == t.Taxonomy {
return t.Name, struct{}{}, true
} }
return "", struct{}{}, false r, err := categoryAndTagsCaches.GetCache(ctx, tt, time.Second, ctx, tt)
}) logs.ErrPrintln(err, "get category err")
return slice.ToMap(r, func(t models.TermsMy) (string, struct{}) {
return t.Name, struct{}{}
}, true)
} }

View File

@ -2,6 +2,7 @@ package dao
import ( import (
"context" "context"
"github.com/fthvgb1/wp-go/internal/pkg/constraints"
"github.com/fthvgb1/wp-go/internal/pkg/models" "github.com/fthvgb1/wp-go/internal/pkg/models"
"github.com/fthvgb1/wp-go/internal/wpconfig" "github.com/fthvgb1/wp-go/internal/wpconfig"
"github.com/fthvgb1/wp-go/model" "github.com/fthvgb1/wp-go/model"
@ -21,7 +22,16 @@ type PostContext struct {
func CategoriesAndTags(a ...any) (terms []models.TermsMy, err error) { func CategoriesAndTags(a ...any) (terms []models.TermsMy, err error) {
ctx := a[0].(context.Context) ctx := a[0].(context.Context)
t, ok := a[1].(int)
var in = []any{"category", "post_tag"} var in = []any{"category", "post_tag"}
if ok {
switch t {
case constraints.Category:
in = []any{"category"}
case constraints.Tag:
in = []any{"post_tag"}
}
}
terms, err = model.Finds[models.TermsMy](ctx, model.Conditions( terms, err = model.Finds[models.TermsMy](ctx, model.Conditions(
model.Where(model.SqlBuilder{ model.Where(model.SqlBuilder{
{"tt.count", ">", "0", "int"}, {"tt.count", ">", "0", "int"},

View File

@ -177,10 +177,15 @@ func MonthPost(args ...any) (r []uint64, err error) {
{"year(post_date)", year}, {"year(post_date)", year},
{"month(post_date)", month}, {"month(post_date)", month},
} }
return model.Column[models.Posts, uint64](ctx, func(v models.Posts) (uint64, bool) { r, err = model.Column[models.Posts, uint64](ctx, func(v models.Posts) (uint64, bool) {
return v.Id, true return v.Id, true
}, model.Conditions( }, model.Conditions(
model.Fields("ID"), model.Fields("ID"),
model.Where(where), model.Where(where),
)) ))
l := int64(len(r))
if l > atomic.LoadInt64(&TotalRaw) {
atomic.StoreInt64(&TotalRaw, l)
}
return
} }

View File

@ -1,71 +0,0 @@
package components
import (
"github.com/dlclark/regexp2"
)
type Block struct {
Closer string
NameSpace string
Name string
Attrs string
Void string
Len int
StartOffset int
}
var block = regexp2.MustCompile(`<!--\s+(?<closer>/)?wp:(?<namespace>[a-z][a-z0-9_-]*\/)?(?<name>[a-z][a-z0-9_-]*)\s+(?<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*)?}\s+)?(?<void>\/)?-->`, regexp2.IgnoreCase|regexp2.Singleline)
func ParseBlock(s string) []Block {
m, err := block.FindStringMatch(s)
if err != nil {
panic(err)
}
var blocks []Block
for m != nil {
if m.GroupCount() < 1 {
continue
}
b, _ := token(m.Groups())
b.StartOffset = m.Group.Index
b.Len = m.Length
blocks = append(blocks, b)
m, _ = block.FindNextMatch(m)
}
return blocks
}
func token(g []regexp2.Group) (Block, string) {
if len(g) < 1 {
return Block{}, "no-more-tokens"
}
b := Block{NameSpace: "core/"}
for i, group := range g {
v := group.String()
if v == "" {
continue
}
switch i {
case 1:
b.Closer = v
case 2:
b.NameSpace = v
case 3:
b.Name = v
case 4:
b.Attrs = v
case 5:
b.Void = v
default:
continue
}
}
if b.Void != "" {
return b, ""
}
if b.Closer != "" {
return b, "block-closer"
}
return b, "block-opener"
}

View File

@ -144,15 +144,17 @@ func categoryLi(root *tree.Node[models.TermsMy, uint64], cate, roots *tree.Node[
} }
s.Sprintf(` <li class="cat-item cat-item-%d %s"> s.Sprintf(` <li class="cat-item cat-item-%d %s">
<a %s href="/p/category/%s">%s %s</a> <a %s href="/p/category/%s">%s %s</a>
</li>
`, category.Terms.TermId, strings.Join(class, " "), aria, category.Name, category.Name, count) `, category.Terms.TermId, strings.Join(class, " "), aria, category.Name, category.Name, count)
if len(*child.Children) > 0 { if len(*child.Children) > 0 {
s.WriteString(`<ul class="children"> s.WriteString(` <ul class="children">
`) `)
categoryLi(&child, cate, roots, isCount, s) categoryLi(&child, cate, roots, isCount, s)
s.WriteString(`</ul>`) s.WriteString(`</ul>
`)
} }
s.Sprintf(`</li>`)
} }
} }

View File

@ -14,7 +14,7 @@ import (
) )
var widgetFn = map[string]wp.Components[string]{ var widgetFn = map[string]wp.Components[string]{
"search": {Fn: widget.Search, CacheKey: "widgetSearch"}, "search": {Fn: widget.Search},
"recent-posts": {Fn: widget.RecentPosts}, "recent-posts": {Fn: widget.RecentPosts},
"recent-comments": {Fn: widget.RecentComments}, "recent-comments": {Fn: widget.RecentComments},
"archives": {Fn: widget.Archive}, "archives": {Fn: widget.Archive},

13
safety/number.go Normal file
View File

@ -0,0 +1,13 @@
package safety
import (
"golang.org/x/exp/constraints"
"sync/atomic"
)
func Counter[T constraints.Integer]() func() T {
var counter int64
return func() T {
return T(atomic.AddInt64(&counter, 1))
}
}