代码拉取完成,页面将自动刷新
package sqlx
import (
"context"
"database/sql"
"reflect"
"gitee.com/erdian718/linq"
)
// Stmt is a prepared statement.
type Stmt struct {
err error
ctx context.Context
raw *sql.Stmt
nargs map[string]any
pargs []any
}
// Exec executes a query without returning any rows.
func (s *Stmt) Exec(args ...any) (Result, error) {
if s.err != nil {
return nil, s.err
}
return s.raw.ExecContext(s.ctx, s.buildArgs(args)...)
}
// Query executes a query that returns rows.
func (s *Stmt) Query(args ...any) linq.Seq[Row] {
if s.err != nil {
return linq.Error[Row](s.err)
}
return func(yield func(Row, error) bool) {
rows, err := s.raw.QueryContext(s.ctx, s.buildArgs(args)...)
if err != nil {
yield(Row{}, err)
return
}
defer rows.Close()
row := Row{rows: rows}
if row.columns, err = rows.Columns(); err != nil {
yield(row, err)
return
}
row.fields = make([]any, len(row.columns))
for rows.Next() {
if !yield(row, nil) {
return
}
}
if err := rows.Err(); err != nil {
yield(row, err)
}
}
}
func (s *Stmt) reset() {
if len(s.pargs) > 0 {
s.pargs = s.pargs[:0]
for param := range s.nargs {
s.nargs[param] = nil
}
}
}
func (s *Stmt) buildArgs(args []any) []any {
s.reset()
for _, arg := range args {
s.buildArg(arg)
}
for name, value := range s.nargs {
s.pargs = append(s.pargs, sql.Named(name, value))
}
return s.pargs
}
func (s *Stmt) buildArg(arg any) {
if namedArg, ok := arg.(sql.NamedArg); ok {
s.buildNamedArg(namedArg)
return
}
v := reflect.ValueOf(arg)
t := v.Type()
if t.Kind() == reflect.Struct {
s.buildStructArg(t, v)
return
}
if t.Kind() == reflect.Pointer {
if t := t.Elem(); t.Kind() == reflect.Struct {
s.buildStructArg(t, v.Elem())
return
}
}
s.pargs = append(s.pargs, arg)
}
func (s *Stmt) buildNamedArg(arg sql.NamedArg) {
if _, ok := s.nargs[arg.Name]; ok {
s.nargs[arg.Name] = arg.Value
}
}
func (s *Stmt) buildStructArg(t reflect.Type, v reflect.Value) {
for name := range s.nargs {
if fv, err := getFieldValue(t, v, name, false); err == nil {
s.nargs[name] = fv.Interface()
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。