优化 加个scanner

This commit is contained in:
xing 2023-02-21 19:49:13 +08:00
parent 73fb725960
commit 226c98cbd9
4 changed files with 77 additions and 11 deletions

View File

@ -19,13 +19,13 @@ func InitOptions() error {
}
ops, err := model.FindToStringMap[models.Options](ctx, model.Conditions(
model.Where(model.SqlBuilder{{"autoload", "yes"}}),
model.Fields("option_name, option_value"),
model.Fields("option_name k, option_value v"),
))
if err != nil {
return err
}
for _, option := range ops {
options.Store(option["option_name"], option["option_value"])
options.Store(option["k"], option["v"])
}
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) {
sq, args, err := FindRawSql[T](q)
sq, args, err := BuildQuerySql[T](q)
if err != nil {
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) {
rawSql, in, err := FindRawSql[T](q)
rawSql, in, err := BuildQuerySql[T](q)
if err != nil {
return nil, err
}
ctx = context.WithValue(ctx, "toMap", "string")
ctx = context.WithValue(ctx, "handle=>", "string")
err = db.Get(ctx, &r, rawSql, in...)
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) {
rawSql, in, err := FindRawSql[T](q)
rawSql, in, err := BuildQuerySql[T](q)
if err != nil {
return nil, err
}
ctx = context.WithValue(ctx, "toMap", "string")
ctx = context.WithValue(ctx, "handle=>", "string")
err = db.Select(ctx, &r, rawSql, in...)
return
}
@ -217,7 +217,7 @@ func GetToStringMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCond
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
w := ""
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)
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 (
"context"
"database/sql"
"fmt"
"github.com/fthvgb1/wp-go/helper/number"
"github.com/fthvgb1/wp-go/helper/slice"
"reflect"
@ -475,3 +476,33 @@ 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)
}
})
}
}

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 {
v := ctx.Value("toMap")
v := ctx.Value("handle=>")
if v != nil {
vv, ok := v.(string)
if ok && vv != "" {
switch vv {
case "string":
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 {
v := ctx.Value("toMap")
v := ctx.Value("handle=>")
if v != nil {
vv, ok := v.(string)
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...)
}
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) {
rows, err := db.Query(sql, params...)
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
c[i] = &a
}
args := slice.ToAnySlice(c)
var m []map[string]V
for rows.Next() {
err = rows.Scan(slice.ToAnySlice(c)...)
err = rows.Scan(args...)
if err != nil {
return
}