1 Star 0 Fork 0

Erdian718/sqlx

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
sqlx.go 2.62 KB
一键复制 编辑 原始数据 按行查看 历史
Erdian718 提交于 2025-05-27 16:09 +08:00 . Optimize error messages
// Package sqlx provides extra features for go's standard database/sql library.
package sqlx
import (
"database/sql"
"fmt"
"reflect"
"regexp"
"strings"
"sync"
"gitee.com/erdian718/linq"
)
// A Result summarizes an executed SQL command.
type Result = sql.Result
// IsolationLevel is the transaction isolation level.
type IsolationLevel = sql.IsolationLevel
// Isolation levels.
const (
LevelDefault = sql.LevelDefault
LevelReadUncommitted = sql.LevelReadUncommitted
LevelReadCommitted = sql.LevelReadCommitted
LevelWriteCommitted = sql.LevelWriteCommitted
LevelRepeatableRead = sql.LevelRepeatableRead
LevelSnapshot = sql.LevelSnapshot
LevelSerializable = sql.LevelSerializable
LevelLinearizable = sql.LevelLinearizable
)
var (
structIndexesMutex sync.RWMutex
structIndexes = make(map[reflect.Type]map[string]int)
regexpParam = regexp.MustCompile(`[:@$]\w+`)
)
// Query executes a query.
func Query[T any](stmt *Stmt, args ...any) linq.Seq[T] {
return linq.Map(stmt.Query(args...), func(row Row) (T, error) {
p := new(T) // Ensure addressable.
v := reflect.ValueOf(p).Elem()
t := v.Type()
if t.Kind() == reflect.Pointer {
t = t.Elem()
v.Set(reflect.New(t))
v = v.Elem()
}
return *p, row.scan(t, v)
})
}
func getFieldValue(t reflect.Type, v reflect.Value, name string, create bool) (reflect.Value, error) {
indexes := getStructIndexes(t)
i := strings.IndexByte(name, '_')
key := name
if i >= 0 {
key = name[:i]
}
index, ok := indexes[key]
if !ok {
return reflect.Value{}, fmt.Errorf("sqlx: field [%s.%s] is not found", t, name)
}
fv := v.FieldByIndex([]int{index})
if i < 0 {
return fv, nil
}
ft := fv.Type()
if ft.Kind() == reflect.Pointer {
ft = ft.Elem()
if fv.IsNil() {
if !create {
return reflect.Value{}, fmt.Errorf("sqlx: field [%s.%s] is nil", t, key)
}
fv.Set(reflect.New(ft))
}
fv = fv.Elem()
}
if ft.Kind() != reflect.Struct {
return reflect.Value{}, fmt.Errorf("sqlx: unsupported type [%s] for [%s]", ft, name)
}
return getFieldValue(ft, fv, name[i+1:], create)
}
func getStructIndexes(t reflect.Type) map[string]int {
structIndexesMutex.RLock()
indexes, ok := structIndexes[t]
structIndexesMutex.RUnlock()
if ok {
return indexes
}
structIndexesMutex.Lock()
defer structIndexesMutex.Unlock()
if indexes, ok = structIndexes[t]; ok {
return indexes
}
n := t.NumField()
indexes = make(map[string]int, n)
structIndexes[t] = indexes
for i := 0; i < n; i++ {
f := t.Field(i)
if f.IsExported() {
key := f.Name
if tag, ok := f.Tag.Lookup("db"); ok {
key = tag
}
indexes[key] = i
}
}
return indexes
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/erdian718/sqlx.git
git@gitee.com:erdian718/sqlx.git
erdian718
sqlx
sqlx
main

搜索帮助