Compare commits

..

2 Commits

4 changed files with 102 additions and 11 deletions

View File

@ -19,13 +19,13 @@ func InitOptions() error {
} }
ops, err := model.FindToStringMap[models.Options](ctx, model.Conditions( ops, err := model.FindToStringMap[models.Options](ctx, model.Conditions(
model.Where(model.SqlBuilder{{"autoload", "yes"}}), model.Where(model.SqlBuilder{{"autoload", "yes"}}),
model.Fields("option_name, option_value"), model.Fields("option_name k, option_value v"),
)) ))
if err != nil { if err != nil {
return err return err
} }
for _, option := range ops { for _, option := range ops {
options.Store(option["option_name"], option["option_value"]) options.Store(option["k"], option["v"])
} }
return nil return nil
} }

View File

@ -26,7 +26,7 @@ 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) { func finds[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []T, err error) {
sq, args, err := FindRawSql[T](q) sq, args, err := BuildQuerySql[T](q)
if err != nil { if err != nil {
return return
} }
@ -179,11 +179,11 @@ func GetFieldFromDB[T Model](db dbQuery, ctx context.Context, field string, q *Q
} }
func getToStringMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r map[string]string, err error) { func getToStringMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r map[string]string, err error) {
rawSql, in, err := FindRawSql[T](q) rawSql, in, err := BuildQuerySql[T](q)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctx = context.WithValue(ctx, "toMap", "string") ctx = context.WithValue(ctx, "handle=>", "string")
err = db.Get(ctx, &r, rawSql, in...) err = db.Get(ctx, &r, rawSql, in...)
return return
} }
@ -193,11 +193,11 @@ func GetToStringMap[T Model](ctx context.Context, q *QueryCondition) (r map[stri
} }
func findToStringMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []map[string]string, err error) { func findToStringMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition) (r []map[string]string, err error) {
rawSql, in, err := FindRawSql[T](q) rawSql, in, err := BuildQuerySql[T](q)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ctx = context.WithValue(ctx, "toMap", "string") ctx = context.WithValue(ctx, "handle=>", "string")
err = db.Select(ctx, &r, rawSql, in...) err = db.Select(ctx, &r, rawSql, in...)
return return
} }
@ -217,7 +217,7 @@ func GetToStringMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCond
return return
} }
func FindRawSql[T Model](q *QueryCondition) (r string, args []any, err error) { func BuildQuerySql[T Model](q *QueryCondition) (r string, args []any, err error) {
var rr T var rr T
w := "" w := ""
if q.where != nil { if q.where != nil {
@ -257,3 +257,17 @@ func FindRawSql[T Model](q *QueryCondition) (r string, args []any, err error) {
r = fmt.Sprintf(tp, q.fields, rr.Table(), j, w, groupBy, h, q.order.parseOrderBy(), l) r = fmt.Sprintf(tp, q.fields, rr.Table(), j, w, groupBy, h, q.order.parseOrderBy(), l)
return return
} }
func findScanner[T Model](db dbQuery, ctx context.Context, fn func(T), q *QueryCondition) (err error) {
s, args, err := BuildQuerySql[T](q)
if err != nil {
return
}
ctx = context.WithValue(ctx, "handle=>", "scanner")
var v T
ctx = context.WithValue(ctx, "fn", func(v any) {
fn(*(v.(*T)))
})
err = db.Select(ctx, &v, s, args...)
return
}

View File

@ -3,6 +3,7 @@ package model
import ( import (
"context" "context"
"database/sql" "database/sql"
"fmt"
"github.com/fthvgb1/wp-go/helper/number" "github.com/fthvgb1/wp-go/helper/number"
"github.com/fthvgb1/wp-go/helper/slice" "github.com/fthvgb1/wp-go/helper/slice"
"reflect" "reflect"
@ -475,3 +476,58 @@ func Test_findToStringMap(t *testing.T) {
}) })
} }
} }
func Test_findScanner(t *testing.T) {
type args[T Model] struct {
db dbQuery
ctx context.Context
fn func(T)
q *QueryCondition
}
type testCase[T Model] struct {
name string
args args[T]
wantErr bool
}
tests := []testCase[options]{
{
name: "t1",
args: args[options]{glob, ctx, func(t options) {
fmt.Println(t)
}, Conditions(Where(SqlBuilder{{"option_id", "<", "10", "int"}}))},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := findScanner[options](tt.args.db, tt.args.ctx, tt.args.fn, tt.args.q); (err != nil) != tt.wantErr {
t.Errorf("findScanner() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func BenchmarkScannerXX(b *testing.B) {
for i := 0; i < b.N; i++ {
err := findScanner[options](glob, ctx, func(t options) {
_ = t
//fmt.Println(t)
}, Conditions(Where(SqlBuilder{{"option_id", "<", "100", "int"}})))
if err != nil {
panic(err)
}
}
}
func BenchmarkFindsXX(b *testing.B) {
for i := 0; i < b.N; i++ {
r, err := finds[options](glob, ctx, Conditions(Where(SqlBuilder{{"option_id", "<", "100", "int"}})))
if err != nil {
panic(err)
}
for _, o := range r {
_ = o
//fmt.Println(o)
}
}
}

View File

@ -34,13 +34,16 @@ func SetGet(db *SqlxQuery, fn func(context.Context, any, string, ...any) error)
} }
func (r *SqlxQuery) Selects(ctx context.Context, dest any, sql string, params ...any) error { func (r *SqlxQuery) Selects(ctx context.Context, dest any, sql string, params ...any) error {
v := ctx.Value("toMap") v := ctx.Value("handle=>")
if v != nil { if v != nil {
vv, ok := v.(string) vv, ok := v.(string)
if ok && vv != "" { if ok && vv != "" {
switch vv { switch vv {
case "string": case "string":
return ToMapSlice(r.sqlx, dest.(*[]map[string]string), sql, params...) return ToMapSlice(r.sqlx, dest.(*[]map[string]string), sql, params...)
case "scanner":
fn := ctx.Value("fn")
return Scanner[any](r.sqlx, dest, sql, params...)(fn.(func(any)))
} }
} }
} }
@ -48,7 +51,7 @@ func (r *SqlxQuery) Selects(ctx context.Context, dest any, sql string, params ..
} }
func (r *SqlxQuery) Gets(ctx context.Context, dest any, sql string, params ...any) error { func (r *SqlxQuery) Gets(ctx context.Context, dest any, sql string, params ...any) error {
v := ctx.Value("toMap") v := ctx.Value("handle=>")
if v != nil { if v != nil {
vv, ok := v.(string) vv, ok := v.(string)
if ok && vv != "" { if ok && vv != "" {
@ -61,6 +64,23 @@ func (r *SqlxQuery) Gets(ctx context.Context, dest any, sql string, params ...an
return r.sqlx.Get(dest, sql, params...) return r.sqlx.Get(dest, sql, params...)
} }
func Scanner[T any](db *sqlx.DB, v T, s string, params ...any) func(func(T)) error {
return func(fn func(T)) error {
rows, err := db.Queryx(s, params...)
if err != nil {
return err
}
for rows.Next() {
err = rows.StructScan(v)
if err != nil {
return err
}
fn(v)
}
return nil
}
}
func ToMapSlice[V any](db *sqlx.DB, dest *[]map[string]V, sql string, params ...any) (err error) { func ToMapSlice[V any](db *sqlx.DB, dest *[]map[string]V, sql string, params ...any) (err error) {
rows, err := db.Query(sql, params...) rows, err := db.Query(sql, params...)
columns, err := rows.Columns() columns, err := rows.Columns()
@ -74,9 +94,10 @@ func ToMapSlice[V any](db *sqlx.DB, dest *[]map[string]V, sql string, params ...
var a V var a V
c[i] = &a c[i] = &a
} }
args := slice.ToAnySlice(c)
var m []map[string]V var m []map[string]V
for rows.Next() { for rows.Next() {
err = rows.Scan(slice.ToAnySlice(c)...) err = rows.Scan(args...)
if err != nil { if err != nil {
return return
} }