wp-go/model/sqxquery.go

157 lines
3.4 KiB
Go
Raw Permalink Normal View History

2023-02-06 09:58:24 +00:00
package model
import (
"context"
"fmt"
2023-03-19 14:48:23 +00:00
"github.com/fthvgb1/wp-go/helper"
"github.com/fthvgb1/wp-go/helper/slice"
2023-02-24 16:56:52 +00:00
str "github.com/fthvgb1/wp-go/helper/strings"
2023-04-05 12:54:38 +00:00
"github.com/fthvgb1/wp-go/safety"
2023-02-06 09:58:24 +00:00
"github.com/jmoiron/sqlx"
"strconv"
"strings"
)
type SqlxQuery struct {
2023-04-05 12:54:38 +00:00
sqlx *safety.Var[*sqlx.DB]
UniversalDb
2023-02-06 09:58:24 +00:00
}
2023-04-05 12:54:38 +00:00
func NewSqlxQuery(sqlx *safety.Var[*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 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
2023-02-06 09:58:24 +00:00
}
func (r *SqlxQuery) Selects(ctx context.Context, dest any, sql string, params ...any) error {
2023-03-20 05:02:40 +00:00
v := helper.GetContextVal(ctx, "handle=>", "")
2023-04-05 12:54:38 +00:00
db := r.sqlx.Load()
2023-03-19 14:48:23 +00:00
if v != "" {
switch v {
case "string":
2023-04-05 12:54:38 +00:00
return ToMapSlice(db, dest.(*[]map[string]string), sql, params...)
2023-03-19 14:48:23 +00:00
case "scanner":
fn := ctx.Value("fn")
2023-04-05 12:54:38 +00:00
return Scanner[any](db, dest, sql, params...)(fn.(func(any)))
}
2023-02-06 09:58:24 +00:00
}
2023-03-19 14:48:23 +00:00
2023-04-05 12:54:38 +00:00
return db.Select(dest, sql, params...)
2023-02-06 09:58:24 +00:00
}
func (r *SqlxQuery) Gets(ctx context.Context, dest any, sql string, params ...any) error {
2023-04-05 12:54:38 +00:00
db := r.sqlx.Load()
2023-03-20 05:02:40 +00:00
v := helper.GetContextVal(ctx, "handle=>", "")
2023-03-19 14:48:23 +00:00
if v != "" {
switch v {
case "string":
2023-04-05 12:54:38 +00:00
return GetToMap(db, dest.(*map[string]string), sql, params...)
}
2023-02-06 09:58:24 +00:00
}
2023-04-05 12:54:38 +00:00
return db.Get(dest, sql, params...)
2023-02-06 09:58:24 +00:00
}
2023-02-21 11:49:13 +00:00
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...)
2023-08-02 15:19:03 +00:00
if err != nil {
return err
}
columns, err := rows.Columns()
if err != nil {
return err
}
defer rows.Close()
columnLen := len(columns)
c := make([]*V, columnLen)
2023-04-05 12:54:38 +00:00
for i := range c {
var a V
c[i] = &a
}
2023-02-21 11:49:13 +00:00
args := slice.ToAnySlice(c)
var m []map[string]V
for rows.Next() {
2023-02-21 11:49:13 +00:00
err = rows.Scan(args...)
if err != nil {
return
}
v := make(map[string]V)
for i, data := range c {
v[columns[i]] = *data
}
m = append(m, v)
}
*dest = m
return
}
func GetToMap[V any](db *sqlx.DB, dest *map[string]V, sql string, params ...any) (err error) {
rows := db.QueryRowx(sql, params...)
columns, err := rows.Columns()
if err != nil {
return err
}
columnLen := len(columns)
c := make([]*V, columnLen)
2023-04-05 12:54:38 +00:00
for i := range c {
var a V
c[i] = &a
}
err = rows.Scan(slice.ToAnySlice(c)...)
if err != nil {
return
}
v := make(map[string]V)
for i, data := range c {
v[columns[i]] = *data
}
*dest = v
return
}
2023-02-10 13:23:30 +00:00
func FormatSql(sql string, params ...any) string {
2023-02-06 09:58:24 +00:00
for _, param := range params {
switch param.(type) {
case string:
sql = strings.Replace(sql, "?", fmt.Sprintf("'%s'", param.(string)), 1)
case int64:
sql = strings.Replace(sql, "?", strconv.FormatInt(param.(int64), 10), 1)
case int:
sql = strings.Replace(sql, "?", strconv.Itoa(param.(int)), 1)
case uint64:
sql = strings.Replace(sql, "?", strconv.FormatUint(param.(uint64), 10), 1)
case float64:
sql = strings.Replace(sql, "?", fmt.Sprintf("%f", param.(float64)), 1)
}
}
2023-02-24 16:56:52 +00:00
return str.CutSpecialDuplicate(sql, " ")
2023-02-06 09:58:24 +00:00
}