优化代码,添加getoption函数,添加db查询函数,可返回map[string]any,添加getthememods函数返回不太通用的值
This commit is contained in:
parent
cb3d043c90
commit
a319e7595f
@ -2,14 +2,14 @@ package maps
|
||||
|
||||
import "strings"
|
||||
|
||||
func GetStrMapAnyVal[T any](m map[string]any, key string) (r T, o bool) {
|
||||
func GetStrAnyVal[T any](m map[string]any, key string) (r T, o bool) {
|
||||
k := strings.Split(key, ".")
|
||||
if len(k) > 1 {
|
||||
val, ok := m[k[0]]
|
||||
if ok {
|
||||
vx, ok := val.(map[string]any)
|
||||
if ok {
|
||||
r, o = GetStrMapAnyVal[T](vx, strings.Join(k[1:], "."))
|
||||
r, o = GetStrAnyVal[T](vx, strings.Join(k[1:], "."))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -25,6 +25,17 @@ func GetStrMapAnyVal[T any](m map[string]any, key string) (r T, o bool) {
|
||||
return
|
||||
}
|
||||
|
||||
func GetStrAnyValWithDefaults[T any](m map[string]any, key string, defaults T) (r T) {
|
||||
r = defaults
|
||||
v, ok := GetStrAnyVal[T](m, key)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
r = v
|
||||
return
|
||||
}
|
||||
|
||||
// GetStrMapAnyValWithAny 使用"." 分隔层级
|
||||
func GetStrMapAnyValWithAny(key string, v map[string]any) (r any, o bool) {
|
||||
k := strings.Split(key, ".")
|
||||
if len(k) > 1 {
|
||||
|
@ -54,12 +54,12 @@ func TestGetStrMapAnyVal(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotR, gotO := GetStrMapAnyVal[int](tt.args.v, tt.args.key)
|
||||
gotR, gotO := GetStrAnyVal[int](tt.args.v, tt.args.key)
|
||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("GetStrMapAnyVal() gotR = %v, want %v", gotR, tt.wantR)
|
||||
t.Errorf("GetStrAnyVal() gotR = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
if gotO != tt.wantO {
|
||||
t.Errorf("GetStrMapAnyVal() gotO = %v, want %v", gotO, tt.wantO)
|
||||
t.Errorf("GetStrAnyVal() gotO = %v, want %v", gotO, tt.wantO)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ func PostComment(c *gin.Context) {
|
||||
}
|
||||
defer req.Body.Close()
|
||||
req.Header = c.Request.Header.Clone()
|
||||
home, err := url.Parse(wpconfig.Options.Value("siteurl"))
|
||||
home, err := url.Parse(wpconfig.GetOption("siteurl"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -102,7 +102,7 @@ func PostComment(c *gin.Context) {
|
||||
logs.ErrPrintln(err, "获取文档", id)
|
||||
return
|
||||
}
|
||||
su := fmt.Sprintf("%s: %s[%s]发表了评论对文档[%v]的评论", wpconfig.Options.Value("siteurl"), author, m, post.PostTitle)
|
||||
su := fmt.Sprintf("%s: %s[%s]发表了评论对文档[%v]的评论", wpconfig.GetOption("siteurl"), author, m, post.PostTitle)
|
||||
err = mail.SendMail([]string{conf.Mail.User}, su, comment)
|
||||
logs.ErrPrintln(err, "发送邮件", conf.Mail.User, su, comment)
|
||||
}()
|
||||
|
@ -33,7 +33,7 @@ func Login(c *gin.Context) {
|
||||
c.Error(err)
|
||||
return
|
||||
}
|
||||
cohash := fmt.Sprintf("wp-postpass_%s", str.Md5(wpconfig.Options.Value("siteurl")))
|
||||
cohash := fmt.Sprintf("wp-postpass_%s", str.Md5(wpconfig.GetOption("siteurl")))
|
||||
c.SetCookie(cohash, pass, 24*3600, "/", "", false, false)
|
||||
|
||||
c.Redirect(http.StatusFound, ref)
|
||||
|
@ -45,7 +45,7 @@ func RecoverAndSendMail(w io.Writer) func(ctx *gin.Context) {
|
||||
|
||||
er := mail.SendMail(
|
||||
[]string{config.GetConfig().Mail.User},
|
||||
fmt.Sprintf("%s%s %s 发生错误", fmt.Sprintf(wpconfig.Options.Value("siteurl")), c.FullPath(), time.Now().Format(time.RFC1123Z)), content)
|
||||
fmt.Sprintf("%s%s %s 发生错误", fmt.Sprintf(wpconfig.GetOption("siteurl")), c.FullPath(), time.Now().Format(time.RFC1123Z)), content)
|
||||
|
||||
if er != nil {
|
||||
logs.ErrPrintln(er, "recover send mail fail", fmt.Sprintf("%v", err))
|
||||
|
@ -5,7 +5,8 @@ import (
|
||||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
)
|
||||
|
||||
func UnPHPSerialize[T any](s string) (r T, err error) {
|
||||
// UnPHPSerializeToStruct 使用 json tag
|
||||
func UnPHPSerializeToStruct[T any](s string) (r T, err error) {
|
||||
var rr map[any]any
|
||||
err = phpserialize.Unmarshal([]byte(s), &rr)
|
||||
if err == nil {
|
||||
@ -14,3 +15,15 @@ func UnPHPSerialize[T any](s string) (r T, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func UnPHPSerializeToAnyMap(s string) (map[string]any, error) {
|
||||
m := map[string]any{}
|
||||
var r map[any]any
|
||||
err := phpserialize.Unmarshal([]byte(s), &r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m = maps.AnyAnyToStrAny(r)
|
||||
return m, err
|
||||
}
|
||||
|
18
internal/pkg/cache/feed.go
vendored
18
internal/pkg/cache/feed.go
vendored
@ -21,14 +21,14 @@ var templateRss rss2.Rss2
|
||||
|
||||
func InitFeed() {
|
||||
templateRss = rss2.Rss2{
|
||||
Title: wpconfig.Options.Value("blogname"),
|
||||
AtomLink: fmt.Sprintf("%s/feed", wpconfig.Options.Value("home")),
|
||||
Link: wpconfig.Options.Value("siteurl"),
|
||||
Description: wpconfig.Options.Value("blogdescription"),
|
||||
Title: wpconfig.GetOption("blogname"),
|
||||
AtomLink: fmt.Sprintf("%s/feed", wpconfig.GetOption("home")),
|
||||
Link: wpconfig.GetOption("siteurl"),
|
||||
Description: wpconfig.GetOption("blogdescription"),
|
||||
Language: wpconfig.GetLang(),
|
||||
UpdatePeriod: "hourly",
|
||||
UpdateFrequency: 1,
|
||||
Generator: wpconfig.Options.Value("home"),
|
||||
Generator: wpconfig.GetOption("home"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ func feed(arg ...any) (xml []string, err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
site := wpconfig.Options.Value("siteurl")
|
||||
site := wpconfig.GetOption("siteurl")
|
||||
rs := templateRss
|
||||
rs.LastBuildDate = time.Now().Format(timeFormat)
|
||||
rs.Items = slice.Map(posts, func(t models.Posts) rss2.Item {
|
||||
@ -109,7 +109,7 @@ func postFeed(arg ...any) (x string, err error) {
|
||||
return
|
||||
}
|
||||
rs := templateRss
|
||||
site := wpconfig.Options.Value("siteurl")
|
||||
site := wpconfig.GetOption("siteurl")
|
||||
|
||||
rs.Title = fmt.Sprintf("《%s》的评论", post.PostTitle)
|
||||
rs.AtomLink = fmt.Sprintf("%s/p/%d/feed", site, post.Id)
|
||||
@ -153,9 +153,9 @@ func commentsFeed(args ...any) (r []string, err error) {
|
||||
c := args[0].(*gin.Context)
|
||||
commens := RecentComments(c, 10)
|
||||
rs := templateRss
|
||||
rs.Title = fmt.Sprintf("\"%s\"的评论", wpconfig.Options.Value("blogname"))
|
||||
rs.Title = fmt.Sprintf("\"%s\"的评论", wpconfig.GetOption("blogname"))
|
||||
rs.LastBuildDate = time.Now().Format(timeFormat)
|
||||
site := wpconfig.Options.Value("siteurl")
|
||||
site := wpconfig.GetOption("siteurl")
|
||||
rs.AtomLink = fmt.Sprintf("%s/comments/feed", site)
|
||||
com, err := GetCommentByIds(c, slice.Map(commens, func(t models.Comments) uint64 {
|
||||
return t.CommentId
|
||||
|
27
internal/pkg/cache/headerImages.go
vendored
27
internal/pkg/cache/headerImages.go
vendored
@ -20,8 +20,20 @@ func getHeaderImages(a ...any) (r []models.PostThumbnail, err error) {
|
||||
ctx := a[0].(context.Context)
|
||||
theme := a[1].(string)
|
||||
meta, err := wpconfig.GetThemeMods(theme)
|
||||
if err == nil && meta.HeaderImage != "" {
|
||||
if "random-uploaded-image" == meta.HeaderImage {
|
||||
if err != nil || meta.HeaderImage == "" {
|
||||
return
|
||||
}
|
||||
if "random-uploaded-image" != meta.HeaderImage {
|
||||
m, er := GetPostById(ctx, uint64(meta.HeaderImagData.AttachmentId))
|
||||
if er != nil {
|
||||
err = er
|
||||
return
|
||||
}
|
||||
m.Thumbnail = thumb(m, theme)
|
||||
r = []models.PostThumbnail{m.Thumbnail}
|
||||
return
|
||||
}
|
||||
|
||||
headers, er := model.Finds[models.Posts](ctx, model.Conditions(
|
||||
model.Where(model.SqlBuilder{
|
||||
{"post_type", "attachment"},
|
||||
@ -53,16 +65,7 @@ func getHeaderImages(a ...any) (r []models.PostThumbnail, err error) {
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
m, er := GetPostById(ctx, uint64(meta.HeaderImagData.AttachmentId))
|
||||
if er != nil {
|
||||
err = er
|
||||
return
|
||||
}
|
||||
m.Thumbnail = thumb(m, theme)
|
||||
r = []models.PostThumbnail{m.Thumbnail}
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func thumb(m models.Posts, theme string) models.PostThumbnail {
|
||||
|
@ -28,7 +28,7 @@ func GetPostMetaByPostIds(args ...any) (r map[uint64]map[string]any, err error)
|
||||
}
|
||||
r[postmeta.PostId][postmeta.MetaKey] = postmeta.MetaValue
|
||||
if postmeta.MetaKey == "_wp_attachment_metadata" {
|
||||
metadata, err := phphelper.UnPHPSerialize[models.WpAttachmentMetadata](postmeta.MetaValue)
|
||||
metadata, err := phphelper.UnPHPSerializeToStruct[models.WpAttachmentMetadata](postmeta.MetaValue)
|
||||
if err != nil {
|
||||
logs.ErrPrintln(err, "解析postmeta失败", postmeta.MetaId, postmeta.MetaValue)
|
||||
continue
|
||||
|
@ -34,22 +34,22 @@ func InitDb() (*sqlx.DB, error) {
|
||||
return db, err
|
||||
}
|
||||
|
||||
func QueryDb(db *sqlx.DB) model.UniversalDb {
|
||||
query := model.NewUniversalDb(
|
||||
func QueryDb(db *sqlx.DB) *model.SqlxQuery {
|
||||
query := model.NewSqlxQuery(db, model.NewUniversalDb(
|
||||
nil,
|
||||
nil))
|
||||
|
||||
func(ctx context.Context, a any, s string, args ...any) error {
|
||||
model.SetSelect(query, func(ctx context.Context, a any, s string, args ...any) error {
|
||||
if config.GetConfig().ShowQuerySql {
|
||||
go log.Println(model.FormatSql(s, args...))
|
||||
}
|
||||
return db.Select(a, s, args...)
|
||||
},
|
||||
|
||||
func(ctx context.Context, a any, s string, args ...any) error {
|
||||
if config.GetConfig().ShowQuerySql {
|
||||
go log.Println(model.FormatSql(s, args...))
|
||||
}
|
||||
return db.Get(a, s, args...)
|
||||
return query.Selects(ctx, a, s, args...)
|
||||
})
|
||||
model.SetGet(query, func(ctx context.Context, a any, s string, args ...any) error {
|
||||
if config.GetConfig().ShowQuerySql {
|
||||
go log.Println(model.FormatSql(s, args...))
|
||||
}
|
||||
return query.Gets(ctx, a, s, args...)
|
||||
})
|
||||
|
||||
return query
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ func Gravatar(email string, isTls bool) (u string) {
|
||||
q := url.Values{}
|
||||
q.Add("s", "112")
|
||||
q.Add("d", "mm")
|
||||
q.Add("r", strings.ToLower(wpconfig.Options.Value("avatar_rating")))
|
||||
q.Add("r", strings.ToLower(wpconfig.GetOption("avatar_rating")))
|
||||
u = fmt.Sprintf("%s?%s", u, q.Encode())
|
||||
return
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
func (h *Handle) CalCustomLogo() (r string) {
|
||||
id := uint64(h.ThemeMods.CustomLogo)
|
||||
if id < 1 {
|
||||
id = str.ToInteger[uint64](wpconfig.Options.Value("site_logo"), 0)
|
||||
id = str.ToInteger[uint64](wpconfig.GetOption("site_logo"), 0)
|
||||
if id < 1 {
|
||||
return
|
||||
}
|
||||
@ -22,7 +22,7 @@ func (h *Handle) CalCustomLogo() (r string) {
|
||||
}
|
||||
siz := "full"
|
||||
meta, _ := cache.GetPostMetaByPostId(h.C, id)
|
||||
alt := maps.WithDefaultVal(meta, "_wp_attachment_image_alt", any(wpconfig.Options.Value("blogname")))
|
||||
alt := maps.WithDefaultVal(meta, "_wp_attachment_image_alt", any(wpconfig.GetOption("blogname")))
|
||||
desc := alt.(string)
|
||||
imgx := map[string]string{
|
||||
"class": "custom-logo",
|
||||
|
@ -24,7 +24,7 @@ func NewDetailHandle(handle *Handle) *DetailHandle {
|
||||
}
|
||||
|
||||
func (d *DetailHandle) BuildDetailData() (err error) {
|
||||
d.GinH["title"] = wpconfig.Options.Value("blogname")
|
||||
d.GinH["title"] = wpconfig.GetOption("blogname")
|
||||
err = d.CheckAndGetPost()
|
||||
if err != nil {
|
||||
return
|
||||
@ -51,7 +51,7 @@ func (d *DetailHandle) CheckAndGetPost() (err error) {
|
||||
d.GinH["post"] = post
|
||||
d.Post = post
|
||||
d.GinH["user"] = cache.GetUserById(d.C, post.PostAuthor)
|
||||
d.GinH["title"] = fmt.Sprintf("%s-%s", post.PostTitle, wpconfig.Options.Value("blogname"))
|
||||
d.GinH["title"] = fmt.Sprintf("%s-%s", post.PostTitle, wpconfig.GetOption("blogname"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ func (d *DetailHandle) RenderComment() {
|
||||
}
|
||||
d.GinH["showComment"] = ableComment
|
||||
if len(d.Comments) > 0 && ableComment {
|
||||
dep := str.ToInteger(wpconfig.Options.Value("thread_comments_depth"), 5)
|
||||
dep := str.ToInteger(wpconfig.GetOption("thread_comments_depth"), 5)
|
||||
d.GinH["comments"] = plugins.FormatComments(d.C, d.CommentRender, d.Comments, dep)
|
||||
}
|
||||
}
|
||||
|
@ -89,15 +89,15 @@ func (i *IndexParams) getSearchKey() string {
|
||||
}
|
||||
|
||||
func NewIndexParams(ctx *gin.Context) *IndexParams {
|
||||
blogName := wpconfig.Options.Value("blogname")
|
||||
size := str.ToInteger(wpconfig.Options.Value("posts_per_page"), 10)
|
||||
blogName := wpconfig.GetOption("blogname")
|
||||
size := str.ToInteger(wpconfig.GetOption("posts_per_page"), 10)
|
||||
i := &IndexParams{
|
||||
Ctx: ctx,
|
||||
Page: 1,
|
||||
PageSize: size,
|
||||
PaginationStep: number.Max(1, config.GetConfig().PaginationStep),
|
||||
TitleL: blogName,
|
||||
TitleR: wpconfig.Options.Value("blogdescription"),
|
||||
TitleR: wpconfig.GetOption("blogdescription"),
|
||||
Where: model.SqlBuilder{
|
||||
{"post_type", "in", ""},
|
||||
{"post_status", "in", ""},
|
||||
@ -106,7 +106,7 @@ func NewIndexParams(ctx *gin.Context) *IndexParams {
|
||||
Join: model.SqlBuilder{},
|
||||
PostType: []any{"post"},
|
||||
PostStatus: []any{"publish"},
|
||||
BlogName: wpconfig.Options.Value("blogname"),
|
||||
BlogName: wpconfig.GetOption("blogname"),
|
||||
}
|
||||
i.ParseSearch = i.parseSearch
|
||||
i.ParseArchive = i.parseArchive
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
var sizes = []string{"site_icon-270", "site_icon-32", "site_icon-192", "site_icon-180"}
|
||||
|
||||
func (h *Handle) CalSiteIcon() (r string) {
|
||||
id := str.ToInteger[uint64](wpconfig.Options.Value("site_icon"), 0)
|
||||
id := str.ToInteger[uint64](wpconfig.GetOption("site_icon"), 0)
|
||||
if id < 1 {
|
||||
return
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ var comFn = template.FuncMap{
|
||||
return t.Format("2006年 01月 02日")
|
||||
},
|
||||
"getOption": func(k string) string {
|
||||
return wpconfig.Options.Value(k)
|
||||
return wpconfig.GetOption(k)
|
||||
},
|
||||
"getLang": wpconfig.GetLang,
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ func InitTheme() {
|
||||
func GetTemplateName() string {
|
||||
tmlp := config.GetConfig().Theme
|
||||
if tmlp == "" {
|
||||
tmlp = wpconfig.Options.Value("template")
|
||||
tmlp = wpconfig.GetOption("template")
|
||||
}
|
||||
if !IsTemplateDirExists(tmlp) {
|
||||
tmlp = "twentyfifteen"
|
||||
|
@ -8,10 +8,15 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Options safety.Map[string, string]
|
||||
var options safety.Map[string, string]
|
||||
|
||||
var ctx context.Context
|
||||
|
||||
func InitOptions() error {
|
||||
ctx := context.Background()
|
||||
options.Flush()
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
ops, err := model.SimpleFind[models.Options](ctx, model.SqlBuilder{{"autoload", "yes"}}, "option_name, option_value")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -22,14 +27,27 @@ func InitOptions() error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, options := range ops {
|
||||
Options.Store(options.OptionName, options.OptionValue)
|
||||
for _, option := range ops {
|
||||
options.Store(option.OptionName, option.OptionValue)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetOption(k string) string {
|
||||
v, ok := options.Load(k)
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
vv, err := model.GetField[models.Options, string](ctx, "option_value", model.Conditions(model.Where(model.SqlBuilder{{"option_name", k}})))
|
||||
options.Store(k, vv)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return vv
|
||||
}
|
||||
|
||||
func GetLang() string {
|
||||
s, ok := Options.Load("WPLANG")
|
||||
s, ok := options.Load("WPLANG")
|
||||
if !ok {
|
||||
s = "zh-CN"
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
"github.com/fthvgb1/wp-go/internal/cmd/reload"
|
||||
"github.com/fthvgb1/wp-go/internal/phphelper"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/logs"
|
||||
"github.com/fthvgb1/wp-go/internal/pkg/models"
|
||||
"github.com/fthvgb1/wp-go/safety"
|
||||
"path/filepath"
|
||||
@ -19,6 +20,7 @@ func SetTemplateFs(fs embed.FS) {
|
||||
templateFs = fs
|
||||
}
|
||||
|
||||
// ThemeMods 只有部分公共的参数,其它的参数调用 GetThemeModsVal 函数获取
|
||||
type ThemeMods struct {
|
||||
CustomCssPostId int `json:"custom_css_post_id,omitempty"`
|
||||
NavMenuLocations map[string]int `json:"nav_menu_locations,omitempty"`
|
||||
@ -36,6 +38,8 @@ type ThemeMods struct {
|
||||
SidebarTextcolor string `json:"sidebar_textcolor,omitempty"`
|
||||
HeaderBackgroundColor string `json:"header_background_color,omitempty"`
|
||||
HeaderTextcolor string `json:"header_textcolor,omitempty"`
|
||||
HeaderVideo int `json:"header_video,omitempty"`
|
||||
ExternalHeaderVideo string `json:"external_header_video,omitempty"`
|
||||
HeaderImagData ImageData `json:"header_image_data,omitempty"`
|
||||
SidebarsWidgets Sidebars `json:"sidebars_widgets,omitempty"`
|
||||
ThemeSupport ThemeSupport
|
||||
@ -106,23 +110,47 @@ func Thumbnail(metadata models.WpAttachmentMetadata, Type, host string, except .
|
||||
|
||||
var themeModes = func() *safety.Map[string, ThemeMods] {
|
||||
m := safety.NewMap[string, ThemeMods]()
|
||||
themeModsRaw = safety.NewMap[string, map[string]any]()
|
||||
reload.Push(func() {
|
||||
m.Flush()
|
||||
themeModsRaw.Flush()
|
||||
})
|
||||
|
||||
return m
|
||||
}()
|
||||
|
||||
var themeModsRaw *safety.Map[string, map[string]any]
|
||||
|
||||
func GetThemeModsVal[T any](theme, k string, defaults T) (r T) {
|
||||
m, ok := themeModsRaw.Load(theme)
|
||||
if !ok {
|
||||
r = defaults
|
||||
return
|
||||
}
|
||||
r = maps.GetStrAnyValWithDefaults(m, k, defaults)
|
||||
return
|
||||
}
|
||||
|
||||
func GetThemeMods(theme string) (r ThemeMods, err error) {
|
||||
r, ok := themeModes.Load(theme)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
mods, ok := Options.Load(fmt.Sprintf("theme_mods_%s", theme))
|
||||
if !ok || mods == "" {
|
||||
mods := GetOption(fmt.Sprintf("theme_mods_%s", theme))
|
||||
if mods == "" {
|
||||
return
|
||||
}
|
||||
m, err := phphelper.UnPHPSerializeToAnyMap(mods)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
themeModsRaw.Store(theme, m)
|
||||
//这里在的err可以不用处理,因为php的默认值和有设置过的类型可能不一样,直接按有设置的类型处理就行
|
||||
r, err = phphelper.UnPHPSerialize[ThemeMods](mods)
|
||||
r, err = maps.StrAnyMapToStruct[ThemeMods](m)
|
||||
if err != nil {
|
||||
logs.ErrPrintln(err, "解析thememods错误")
|
||||
err = nil
|
||||
}
|
||||
r.setThemeSupport(theme)
|
||||
themeModes.Store(theme, r)
|
||||
return
|
||||
|
@ -105,7 +105,7 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
InitDB(NewSqlxQuery(db))
|
||||
InitDB(NewSqlxQuery(db, NewUniversalDb(nil, nil)))
|
||||
}
|
||||
func TestFind(t *testing.T) {
|
||||
type args struct {
|
||||
|
@ -3,7 +3,9 @@ package model
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/fthvgb1/wp-go/helper/maps"
|
||||
"github.com/fthvgb1/wp-go/helper/slice"
|
||||
"strings"
|
||||
)
|
||||
@ -25,43 +27,10 @@ func FindFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r
|
||||
}
|
||||
|
||||
func finds[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []T, err error) {
|
||||
var rr T
|
||||
w := ""
|
||||
var args []any
|
||||
if q.where != nil {
|
||||
w, args, err = q.where.ParseWhere(&q.in)
|
||||
sq, args, err := FindRawSql[T](q)
|
||||
if err != nil {
|
||||
return r, err
|
||||
return
|
||||
}
|
||||
}
|
||||
h := ""
|
||||
if q.having != nil {
|
||||
hh, arg, err := q.having.ParseWhere(&q.in)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
args = append(args, arg...)
|
||||
h = strings.Replace(hh, " where", " having", 1)
|
||||
}
|
||||
|
||||
j := q.join.parseJoin()
|
||||
groupBy := ""
|
||||
if q.group != "" {
|
||||
g := strings.Builder{}
|
||||
g.WriteString(" group by ")
|
||||
g.WriteString(q.group)
|
||||
groupBy = g.String()
|
||||
}
|
||||
tp := "select %s from %s %s %s %s %s %s %s"
|
||||
l := ""
|
||||
|
||||
if q.limit > 0 {
|
||||
l = fmt.Sprintf(" limit %d", q.limit)
|
||||
}
|
||||
if q.offset > 0 {
|
||||
l = fmt.Sprintf(" %s offset %d", l, q.offset)
|
||||
}
|
||||
sq := fmt.Sprintf(tp, q.fields, rr.Table(), j, w, groupBy, h, q.order.parseOrderBy(), l)
|
||||
err = db.Select(ctx, &r, sq, args...)
|
||||
return
|
||||
}
|
||||
@ -186,3 +155,92 @@ func column[V Model, T any](db dbQuery, ctx context.Context, fn func(V) (T, bool
|
||||
r = slice.FilterAndMap(res, fn)
|
||||
return
|
||||
}
|
||||
|
||||
func GetField[T Model, V any](ctx context.Context, field string, q *QueryCondition) (r V, err error) {
|
||||
r, err = getField[T, V](globalBb, ctx, field, q)
|
||||
return
|
||||
}
|
||||
func getField[T Model, V any](db dbQuery, ctx context.Context, field string, q *QueryCondition) (r V, err error) {
|
||||
res, err := getToAnyMap[T](globalBb, ctx, q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r, ok := maps.GetStrAnyVal[V](res, field)
|
||||
if !ok {
|
||||
err = errors.New("not exists")
|
||||
}
|
||||
return
|
||||
}
|
||||
func GetFieldFromDB[T Model, V any](db dbQuery, ctx context.Context, field string, q *QueryCondition) (r V, err error) {
|
||||
return getField[T, V](db, ctx, field, q)
|
||||
}
|
||||
|
||||
func findToAnyMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []map[string]any, err error) {
|
||||
rawSql, in, err := FindRawSql[T](q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx = context.WithValue(ctx, "toMap", true)
|
||||
err = db.Select(ctx, &r, rawSql, in...)
|
||||
return
|
||||
}
|
||||
|
||||
func FindToAnyMap[T Model](ctx context.Context, q *QueryCondition) (r []map[string]any, err error) {
|
||||
r, err = findToAnyMap[T](globalBb, ctx, q)
|
||||
return
|
||||
}
|
||||
|
||||
func FindToAnyMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []map[string]any, err error) {
|
||||
r, err = findToAnyMap[T](db, ctx, q)
|
||||
return
|
||||
}
|
||||
func getToAnyMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r map[string]any, err error) {
|
||||
rawSql, in, err := FindRawSql[T](q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx = context.WithValue(ctx, "toMap", true)
|
||||
err = db.Get(ctx, &r, rawSql, in...)
|
||||
return
|
||||
}
|
||||
|
||||
func FindRawSql[T Model](q *QueryCondition) (r string, args []any, err error) {
|
||||
var rr T
|
||||
w := ""
|
||||
if q.where != nil {
|
||||
w, args, err = q.where.ParseWhere(&q.in)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
h := ""
|
||||
if q.having != nil {
|
||||
hh, arg, er := q.having.ParseWhere(&q.in)
|
||||
if er != nil {
|
||||
err = er
|
||||
return
|
||||
}
|
||||
args = append(args, arg...)
|
||||
h = strings.Replace(hh, " where", " having", 1)
|
||||
}
|
||||
|
||||
j := q.join.parseJoin()
|
||||
groupBy := ""
|
||||
if q.group != "" {
|
||||
g := strings.Builder{}
|
||||
g.WriteString(" group by ")
|
||||
g.WriteString(q.group)
|
||||
groupBy = g.String()
|
||||
}
|
||||
tp := "select %s from %s %s %s %s %s %s %s"
|
||||
l := ""
|
||||
|
||||
if q.limit > 0 {
|
||||
l = fmt.Sprintf(" limit %d", q.limit)
|
||||
}
|
||||
if q.offset > 0 {
|
||||
l = fmt.Sprintf(" %s offset %d", l, q.offset)
|
||||
}
|
||||
r = fmt.Sprintf(tp, q.fields, rr.Table(), j, w, groupBy, h, q.order.parseOrderBy(), l)
|
||||
return
|
||||
}
|
||||
|
@ -273,3 +273,56 @@ func TestColumn(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetField(t *testing.T) {
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
field string
|
||||
q *QueryCondition
|
||||
}
|
||||
type testCase[V any] struct {
|
||||
name string
|
||||
args args
|
||||
wantR V
|
||||
wantErr bool
|
||||
}
|
||||
tests := []testCase[string]{
|
||||
{
|
||||
name: "t1",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
field: "option_value",
|
||||
q: Conditions(Where(SqlBuilder{{"option_name", "blogname"}})),
|
||||
},
|
||||
wantR: "记录并见证自己的成长",
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotR, err := GetField[options, string](tt.args.ctx, tt.args.field, tt.args.q)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetField() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotR, tt.wantR) {
|
||||
t.Errorf("GetField() gotR = %v, want %v", gotR, tt.wantR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type options struct {
|
||||
OptionId uint64 `gorm:"column:option_id" db:"option_id" json:"option_id" form:"option_id"`
|
||||
OptionName string `gorm:"column:option_name" db:"option_name" json:"option_name" form:"option_name"`
|
||||
OptionValue string `gorm:"column:option_value" db:"option_value" json:"option_value" form:"option_value"`
|
||||
Autoload string `gorm:"column:autoload" db:"autoload" json:"autoload" form:"autoload"`
|
||||
}
|
||||
|
||||
func (w options) PrimaryKey() string {
|
||||
return "option_id"
|
||||
}
|
||||
|
||||
func (w options) Table() string {
|
||||
return "wp_options"
|
||||
}
|
||||
|
@ -4,34 +4,129 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SqlxQuery struct {
|
||||
sqlx *sqlx.DB
|
||||
UniversalDb
|
||||
}
|
||||
|
||||
func NewSqlxQuery(sqlx *sqlx.DB) SqlxQuery {
|
||||
return SqlxQuery{sqlx: sqlx}
|
||||
func NewSqlxQuery(sqlx *sqlx.DB, u UniversalDb) *SqlxQuery {
|
||||
|
||||
s := &SqlxQuery{sqlx: sqlx, UniversalDb: u}
|
||||
if u.selects == nil {
|
||||
s.UniversalDb.selects = s.Selects
|
||||
}
|
||||
if u.gets == nil {
|
||||
s.UniversalDb.gets = s.Gets
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (r SqlxQuery) Select(ctx context.Context, dest any, sql string, params ...any) error {
|
||||
if os.Getenv("SHOW_SQL") == "true" {
|
||||
go log.Println(FormatSql(sql, params...))
|
||||
func SetSelect(db *SqlxQuery, fn func(context.Context, any, string, ...any) error) {
|
||||
db.selects = fn
|
||||
}
|
||||
func SetGet(db *SqlxQuery, fn func(context.Context, any, string, ...any) error) {
|
||||
db.gets = fn
|
||||
}
|
||||
|
||||
func (r *SqlxQuery) Selects(ctx context.Context, dest any, sql string, params ...any) error {
|
||||
v := ctx.Value("toMap")
|
||||
if v != nil {
|
||||
vv, ok := v.(bool)
|
||||
if ok && vv {
|
||||
d, ok := dest.(*[]map[string]any)
|
||||
if ok {
|
||||
return r.toMapSlice(d, sql, params...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return r.sqlx.Select(dest, sql, params...)
|
||||
}
|
||||
|
||||
func (r SqlxQuery) Get(ctx context.Context, dest any, sql string, params ...any) error {
|
||||
if os.Getenv("SHOW_SQL") == "true" {
|
||||
go log.Println(FormatSql(sql, params...))
|
||||
func (r *SqlxQuery) Gets(ctx context.Context, dest any, sql string, params ...any) error {
|
||||
v := ctx.Value("toMap")
|
||||
if v != nil {
|
||||
vv, ok := v.(bool)
|
||||
if ok && vv {
|
||||
d, ok := dest.(*map[string]any)
|
||||
if ok {
|
||||
return r.toMap(d, sql, params...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return r.sqlx.Get(dest, sql, params...)
|
||||
}
|
||||
|
||||
func (r *SqlxQuery) toMap(dest *map[string]any, sql string, params ...any) (err error) {
|
||||
rows := r.sqlx.QueryRowx(sql, params...)
|
||||
columns, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
columnLen := len(columns)
|
||||
c := make([]any, columnLen)
|
||||
for i, _ := range c {
|
||||
var a any
|
||||
c[i] = &a
|
||||
}
|
||||
err = rows.Scan(c...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
v := make(map[string]any)
|
||||
for i, data := range c {
|
||||
s, ok := data.(*any)
|
||||
if ok {
|
||||
ss, ok := (*s).([]uint8)
|
||||
if ok {
|
||||
data = string(ss)
|
||||
}
|
||||
}
|
||||
v[columns[i]] = data
|
||||
}
|
||||
*dest = v
|
||||
return
|
||||
}
|
||||
|
||||
func (r *SqlxQuery) toMapSlice(dest *[]map[string]any, sql string, params ...any) (err error) {
|
||||
rows, err := r.sqlx.Query(sql, params...)
|
||||
columns, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
columnLen := len(columns)
|
||||
c := make([]any, columnLen)
|
||||
for i, _ := range c {
|
||||
var a any
|
||||
c[i] = &a
|
||||
}
|
||||
var m []map[string]any
|
||||
for rows.Next() {
|
||||
err = rows.Scan(c...)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
v := make(map[string]any)
|
||||
for i, data := range c {
|
||||
s, ok := data.(*any)
|
||||
if ok {
|
||||
ss, ok := (*s).([]uint8)
|
||||
if ok {
|
||||
data = string(ss)
|
||||
}
|
||||
}
|
||||
v[columns[i]] = data
|
||||
}
|
||||
m = append(m, v)
|
||||
}
|
||||
*dest = m
|
||||
return
|
||||
}
|
||||
|
||||
func FormatSql(sql string, params ...any) string {
|
||||
for _, param := range params {
|
||||
switch param.(type) {
|
||||
|
Loading…
Reference in New Issue
Block a user